2 briefs, single PR. ~12 files net (down from the 18 in the original scope —
10 of the 17 Layout-importing pages already pass user explicitly).
Brief 1: components/Layout.js default user=null + Sign-in CTA branch in
UserProfileDropdown when logged out. Adds first jsdom test in the repo
at test/components/Layout.test.js (Decision D2) with 5 regression-lock
assertions. devDeps: jsdom@^29, @testing-library/react@^16.
Brief 2: page audit sweep — 7 pages need code changes:
- Pass user={user} to Layout: scanner.js, deck-builder.js (×4),
deck/[id].js (×3), decks.js (×3)
- Replace page-level useState({email: 'me@...'}) → useState(null) +
null-guards: profile.js, settings.js
- Replace hardcoded const user = {email: 'me@...'} with useAuth():
card/[id].js
Discovered second anti-pattern: profile.js, settings.js, card/[id].js
seed page-level state with the maintainer email. Folded into Brief 2 since
success metric "no real email address remains in any component default-prop"
reads naturally to include page-level seed values.
Decisions:
A1 — Sign-in CTA replaces avatar+email+dropdown when user===null;
hides auth-only dropdown (Profile/Settings/Logout/Admin);
keeps public + community nav visible
B — Per-page bucket assignment (10 already correct, 7 need fix);
full per-page table with justification in convoy file
C2 — Two briefs in one PR (Brief 1 = Layout + test; Brief 2 = page
sweep depends on Brief 1). C1 buries the conceptual change under
mechanical edits; C3 is over-orchestrated for this scope
D2 — vitest lock-in; first jsdom test in repo; same negative-regression
style as test/lib/permission-middleware.test.js (synthetic-admin
shape). devDeps jsdom + @testing-library/react
Risks tracked R1-R8. Biggest: R2 (useState(null) null-deref in 3 leaky
pages — mitigated by audit-pass mandate + manual smoke).
MobileNavigation deliberately NOT folded in: its user prop is dead code
(never reads user.*); different bug class; cleanup queued separately to
avoid scope expansion.
Flagged-but-deferred:
- 4 pages still import useAuth from lib/auth-context.js
→ single-auth-provider (queued P1 #9)
- Layout headers still render "Deck Hearth" / "DH" branding
→ pick-a-name (queued P1 #12)
- MobileNavigation dead user prop → cleanup-mobile-nav-dead-props
or fold into god-component-split
addresses: P0 #7 from .convoys/ship-readiness.md (last P0 ship-blocker)
parent: ship-readiness
Co-authored-by: Cursor <cursoragent@cursor.com>
|
||
|---|---|---|
| .. | ||
| bump-next-js | ||
| drop-public-setup | ||
| fix-auth-bypass | ||
| fix-layout-default-user | ||
| bump-next-js.md | ||
| drop-public-setup.md | ||
| fix-auth-bypass.md | ||
| fix-layout-default-user.md | ||
| README.md | ||
| ship-readiness.md | ||
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):
## Why(Conductor)## Scope(Conductor)## Roles invoked(Conductor)## Todos(Conductor → refined by Architect)## IA(IA Architect)## UX(UX Reviewer)## 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
- Open Cursor in this repo.
- Prompt: "Start a new convoy: . Success = ."
- The
role-conductorsubagent writes.convoys/<slug>.md. - Run subsequent roles in order per the convoy's
Roles invokedlist.
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.