convoy(fix-auth-bypass): architect plan + 5 briefs (Wave A/B/C dispatch)
Architect pass for P0 security-critical convoy (closes ship-blockers
#1, #2, #4, #5, #6 partial). Produces 5 briefs with explicit
slice_dependencies for /multitask fan-out.
Decomposition:
- Brief 1: Central JWT secret helper + 24h token TTL (8 files, ~120 LOC)
- Brief 2: Remove the synthetic-admin bypass (2 files, ~25 LOC net negative)
- Brief 3: Delete 4 dev-only endpoints + CI guard (6 files, ~30 LOC)
- Brief 4: Tighten auth surface — CORS + rate limit (5 files, ~150 LOC)
- Brief 5: Install vitest + auth tests + re-enable CI test job (8 files, ~280 LOC)
Total estimate: ~600 LOC across 5 PRs. All under 400-LOC budget.
Wave A (parallel from t=0): Briefs 1 + 3 (disjoint files)
Wave B (parallel after Brief 1): Briefs 2 + 4 (disjoint subsets of Brief 1's exports)
Wave C (after Briefs 2 + 4): Brief 5 alone (lockfile sequencing + functional dep on Brief 2's null contract)
Architect's calls (3 decisions documented in convoy file Decisions log):
- Token TTL = 24h (matches current login.js UX; security-conservative)
- Rate-limit = @upstash/ratelimit@^2.0.8 + @upstash/redis@^1.38.0
(DIY-Postgres needs schema change OOS; DIY-memory broken on Vercel
cold starts; next-rate-limit is stale)
- Vitest in this convoy (not split to adopt-vitest); pinned to ^3.2.4
to dodge vitest@4's non-optional vite peer dep
Boot-the-brief findings (9 verifications, 0 revisions):
- 24/24 getUserFromRequest callers already handle null correctly —
Brief 2 is safer than the convoy file predicted
- 7 JWT_SECRET literal sites match AGENTS.md gotcha #3 exactly
- Dev endpoints have zero runtime references (only doc references) —
safe to delete
- Cross-brief commitments declared in both directions for every
Brief-1 -> {2,4,5} pair
Risk list: 12 risks documented (R1-R12). Headlines:
- R1: JWT_SECRET fail-loud throws may break unexpected import chains
- R3: existing tokens stop verifying once literal fallback removed
(one-time "log back in" pre-launch is acceptable)
- R5-R6: rate-limit IP extraction + Upstash quota; fail-open mitigation
- R10: JWT_SECRET rotation now requires a deploy (no silent fallback)
Pre-merge env-var checklist (user action required before Brief 4 ships):
- UPSTASH_REDIS_REST_URL (new — Vercel project settings)
- UPSTASH_REDIS_REST_TOKEN (new — Vercel project settings)
- JWT_SECRET (verify already set — no fallback any more)
Awaiting human gate 1 (plan approval) before implementers run.
Co-authored-by: Cursor <cursoragent@cursor.com>