deckhearth/.convoys
Randall Stillwell 1667b87ee3 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>
2026-05-23 02:58:16 -05:00
..
bump-next-js convoy(bump-next-js): plan + brief 1 (Decisions A-D) 2026-05-23 02:31:26 -05:00
fix-auth-bypass convoy(fix-auth-bypass): architect plan + 5 briefs (Wave A/B/C dispatch) 2026-05-23 02:58:16 -05:00
bump-next-js.md convoy(bump-next-js): plan + brief 1 (Decisions A-D) 2026-05-23 02:31:26 -05:00
fix-auth-bypass.md convoy(fix-auth-bypass): architect plan + 5 briefs (Wave A/B/C dispatch) 2026-05-23 02:58:16 -05:00
README.md bootstrap: agent pipeline v0.5.0 + ship-readiness review 2026-05-23 02:31:26 -05:00
ship-readiness.md fix(bootstrap): make L3 CI green + record two new ship-blockers 2026-05-23 02:31:26 -05:00

Convoys

A convoy is a multi-PR work-stream coordinated by an agent pipeline. One convoy = one feature, bug fix, or epic. Each convoy is a Markdown file in this directory plus an optional sub-directory of implementer briefs.

File layout

.convoys/
├── README.md                              (this file)
├── <slug>.md                              (the convoy file — written by role-conductor)
└── <slug>/
    ├── brief-1-<kebab-title>.md           (written by role-architect)
    ├── brief-2-<kebab-title>.md
    └── ...

Convoy file format

Frontmatter (set by role-conductor, then appended-to by other roles):

---
name: <kebab-slug>
classification: feature | hotfix | docs-only | infra-only | server-only | config-only
success_metric: <one sentence>
skip:
  - <flag1>
status: open | in-progress | merged | shipped | abandoned
created: <YYYY-MM-DD>
---

Body sections (added in order by the pipeline roles):

  1. ## Why (Conductor)
  2. ## Scope (Conductor)
  3. ## Roles invoked (Conductor)
  4. ## Todos (Conductor → refined by Architect)
  5. ## IA (IA Architect)
  6. ## UX (UX Reviewer)
  7. ## Architecture (Architect)

After Architect, briefs live in .convoys/<slug>/brief-N-*.md. Implementers read only their brief, not the whole convoy.

Skip flags

The Conductor sets skip: based on classification. These flags map to pipeline stages that no-op when set:

Flag Skips
ia IA Architect
ux UX Reviewer
arch Architect
test Component tests
review Reviewer
visual Visual diff
a11y A11y auditor
design Design-system auditor
smoke Staging smoke
qa Manual QA
docs Doc Writer
flag Flag rollout

Never skipped (mandatory human gates): plan-approval, pr-merge, prod-promote.

Status lifecycle

  • open — Conductor created the convoy; no work started.
  • in-progress — At least one brief has an open or merged PR.
  • merged — All briefs merged to umbrella; release PR to develop pending.
  • shipped — Release to main complete; flag rollout (if any) underway.
  • abandoned — Convoy closed without shipping; reason in convoy body.

Update status by editing the convoy frontmatter as you progress.

Adding a new convoy

  1. Open Cursor in this repo.
  2. Prompt: "Start a new convoy: . Success = ."
  3. The role-conductor subagent writes .convoys/<slug>.md.
  4. Run subsequent roles in order per the convoy's Roles invoked list.

See .cursor/agents/role-conductor.md for the Conductor's full spec.

Multitask + worktrees (Cursor 3.2+)

Cursor 3.2 (Apr 24, 2026) added /multitask async subagents and native worktree management in the Agents Window. The pipeline uses both:

Audit fan-out — after an implementer ships a PR draft:

/multitask role-reviewer + role-design-system-auditor + role-a11y-auditor

All three read the same diff and emit independent comments. Use group id audit-<convoy>-<pr> so analytics can compute wall-clock savings.

Implementer fleet — after architect's plan is approved (gate 1), if slice_dependencies: declares parallel-safe briefs (depends_on: [], disjoint files:):

/multitask role-implementer briefs 1, 2, 3

Use Cursor's Agents Window to create a worktree per brief — one click each. The legacy scripts/wt.sh is now a deprecation stub.

See the multitask playbook for the full guardrail set.

Self-analytics

Each L2 role appends one event to .convoys/.metrics.jsonl via scripts/log-convoy-event.sh. The file is gitignored by default — events stay local. To opt-in to commit team-shared metrics, remove .convoys/.metrics.jsonl from .gitignore.

Aggregate across repos and render a dashboard with the agent-pipeline analytics scripts:

cd ~/code/agent-pipeline/analytics
npx tsx analyze-convoys.ts <repo-path> [<repo-path>...]
npx tsx render-dashboard.ts
open ~/agent-pipeline-data/dashboard.html

Schema: analytics/schemas/convoy-event.json.