This page is the full contributor guide. CONTRIBUTING.md at the repository root is the short version GitHub surfaces on pull requests — when one changes, change the other.

Setup

Anonymous watch works with zero environment variables, by design. See Quickstart for the full variable table.

Before you push

CI runs the identical two gates in .github/workflows/checks.yml.

House rules

Short prose sentences — what changed and why. No feat:/fix: prefixes. Match git log --oneline -20.
State constraints code can’t show — why a storage key can’t be renamed, why an effect reads a ref. Don’t add comments that just restate the next line.
Most modules are TDD’d. A behavior change updates the test that encoded the old behavior, with a comment saying who decided (see Watch.test.tsx).
Non-negotiable. Every feature renders without any env keys. Clerk hooks only behind useClerkReady().
Amber = now, crimson = LIVE, no third accent, no purple, no glassmorphism, real flag images never emoji, honor blocklist.json before any stream plays, drop closed channels only, NSFW stays behind its off-by-default toggle.
Keep the atlas. prefix forever — renaming discards user data (src/state/storage.ts).

Where things live

Secrets

gitleaks git . runs clean against full history (config in .gitleaks.toml). Keep it that way — secrets live in .env*.local (gitignored), GitHub secrets, or wrangler secret put. Never in code, fixtures, or workflow files.
The one existing allowlist entry in .gitleaks.toml covers upstream IPTV catalog fixtures whose auth_key URL parameters and playback JWTs look like secrets but are public tokens served to every viewer, not credentials.

Previewing this documentation