17 KiB
quotesdb Implementation Dispatch Plan
For Claude: REQUIRED SUB-SKILL: Use
superpowers:executing-plansto implement this plan task-by-task.
Goal: Commit all pending triage work, advance ec118c to in_progress, then dispatch parallel domain orchestrators to implement all 69 open implementation tickets.
Architecture: A sequential foundation agent resolves shared-file conflicts first (Cargo.toml touched by both API and UI setup tickets). Then 3 parallel domain orchestrators — API+QA, UI, Infra — each pick up tickets via nbd ready --json, create per-ticket git worktrees, dispatch domain-expert sub-agents, validate, merge, and loop.
Tech Stack: Rust/Axum/Tokio (API), Yew/Trunk/Wasm (UI), OpenTofu/Cloudflare (Infra), reqwest/tokio-test (QA), nbd (ticket tracking), git worktrees (agent isolation)
Critical files:
quotesdb/Cargo.toml— single crate, shared by API + UI; modified by foundation tickets onlyquotesdb/.nbd/tickets/— per-ticket markdown files; no cross-ticket conflictsquotesdb/docs/ARCHITECTURE.md— already updated with WASM dep versionsquotesdb/api/openapi.yaml— OpenAPI spec (source of truth, do not generate)
Task 1: Commit all pending changes
Run from: /run/media/pop/4e1ca4f1-37f1-4bd3-bad2-603166a773db/Projects/src/gitea.elijah.run/vibed/worktrees/quotesdb/ (the worktree git root, one level above quotesdb/)
What is in the working tree:
- 80 modified/untracked files: mostly nbd ticket updates (triage resolutions, new implementation tickets, XML tag additions from previous session)
quotesdb/CLAUDE.md— updatedquotesdb/docs/ARCHITECTURE.md— updated with WASM dependency version tableflake.lock— updated
Step 1: Stage all changes
git add quotesdb/.nbd/tickets/ \
quotesdb/CLAUDE.md \
quotesdb/docs/ARCHITECTURE.md \
flake.lock
Step 2: Verify staged files look right
git status
git diff --cached --stat
Step 3: Commit
git commit -m "$(cat <<'EOF'
chore(quotesdb): resolve all triage tickets and create implementation tickets
- All 21 TRIAGE decision tickets resolved with chosen approaches documented
- This session: e2bd9b (SPA routing → _redirects), 2ec8b1 (OpenAPI → build.rs),
0d84fa (HTTP client → reqwest), 0bc655 (auth code → session storage)
- New implementation tickets created: 9ef703, 8892d5, 5379eb
- Downstream tickets updated with resolved approaches and correct dependencies
- ARCHITECTURE.md updated with pinned WASM dependency versions (yew 0.22,
yew-router 0.19, wasm-bindgen 0.2)
- XML tags added to all tickets for improved LLM guidance
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
EOF
)"
Task 2: Update root ticket ec118c to in_progress
Run from: quotesdb/ directory
Phase 0 (design) and Phase 1 (planning / ticket creation) are both complete. All 21 triages are resolved. Moving to Phase 2 (implementation).
nbd update ec118c --status in_progress --json | jq '{id, status}'
Expected output:
{ "id": "ec118c", "status": "in_progress" }
Task 3: Foundation agent — shared Cargo.toml setup (sequential)
Why sequential: Tickets 1f5bb5, 93515e, and 8892d5 all write to Cargo.toml. Running them in parallel would cause merge conflicts. This one-shot foundation agent does them in order before parallel agents start.
Dispatch a single general-purpose agent with this prompt:
You are a senior Rust engineer setting up the foundation of the
quotesdbproject — a single Cargo crate withapianduibinaries.Working directory:
quotesdb/inside the worktree at/run/media/pop/4e1ca4f1-37f1-4bd3-bad2-603166a773db/Projects/src/gitea.elijah.run/vibed/worktrees/quotesdb/Task tracking: Always run
nbdfromquotesdb/. Usenbd update <id> --status in_progress --jsonbefore starting a ticket,nbd update <id> --status done --jsonwhen finished.Worktree convention (per ticket):
git worktree add .claude/worktrees/quotesdb-shared-<id> -b quotesdb/shared/<id> # do all work inside quotesdb/ root within the worktree cargo fmt && cargo check && cargo clippy && cargo test git checkout quotesdb git merge quotesdb/shared/<id> git worktree remove .claude/worktrees/quotesdb-shared-<id>Do these 4 tickets in order — do not start the next until the previous is merged:
7a0d9f— Implementgenerate_id()insrc/lib.rs(UUID v4, WASM-compatible). Read the ticket first:nbd read 7a0d9f --json. Validation:cargo check. Branch:quotesdb/shared/7a0d9f.
1f5bb5— Set upCargo.tomlwith all crate dependencies (axum, tokio, workers-rs, rusqlite, uuid, rand, serde, getrandom, plus[build-dependencies]serde_json + serde_yaml). Read:nbd read 1f5bb5 --json. Validation:cargo check. Branch:quotesdb/shared/1f5bb5.
93515e— Add Yew/Wasm UI dependencies toCargo.toml(yew 0.22, yew-router 0.19, wasm-bindgen, gloo, web-sys). Read:nbd read 93515e --json. Validation:cargo check. Branch:quotesdb/shared/93515e.
8892d5— Createbuild.rsthat convertsapi/openapi.yamlto JSON at compile time (writes to$OUT_DIR/openapi.json). Read:nbd read 8892d5 --json. Validation:cargo check(confirms build.rs runs). Branch:quotesdb/shared/8892d5.After all 4 are merged, run
cargo fmt && cargo check && cargo clippy && cargo testfromquotesdb/to confirm the foundation is clean.Return: which tickets were completed, the final
cargo checkoutput, and any issues encountered.
Proceed to Task 4 only after this agent returns successfully.
Task 4: Dispatch 3 parallel domain orchestrators
Invoke all 3 agents in a single message (parallel). Each orchestrator runs nbd ready --json, filters to its domain, picks the highest-priority unblocked ticket, works it in a worktree, merges, and loops until its domain's sub-project ticket can be closed.
Orchestrator A: API + QA
Domain: src/bin/api/, src/lib.rs (non-Cargo parts), tests/
Sub-project ticket: f3dc74 (quotesdb/api), ce1e4f (quotesdb/qa)
Worktree prefix: quotesdb/api/<id> and quotesdb/qa/<id>
Ready tickets to start with (priority order):
00aff0— QuoteRepository trait + cfg-split D1/rusqlite implementations5f5ba0— Add integration test dev-dependencies (reqwest, tokio, tempfile, serde_json)a5049d— DB connection module + SQLx migrations (after00aff0)9c9546—.env.exampledocumentingDATABASE_URLaf56a7—docs/LOCAL_DEV.mdquickstart guide6e829e— API servermain.rs(router setup, Axum app)28e7d9— GET /api/ handler (serves compiled openapi.json)a6bce1— GET /api/quotes (list, pagination, filters)1a274d— GET /api/quotes/randomb20b5a— GET /api/quotes/:id05f8ae— PUT /api/quotes (create)2c5a57— Auth middleware (X-Auth-Code header validation)5f1112— POST /api/quotes/:id (update)5cdbd9— DELETE /api/quotes/:id- Then QA tickets:
9b581f,789d0f,aa0eab,93f1b6,f9f448,4a4c26,fae330,8c87db,893eba,e8f5cf
Agent prompt:
You are a senior Rust backend engineer implementing the
quotesdbAPI (Axum + Tokio) and its integration test suite.Working directory: Always work from
quotesdb/at/run/media/pop/4e1ca4f1-37f1-4bd3-bad2-603166a773db/Projects/src/gitea.elijah.run/vibed/worktrees/quotesdb/quotesdb/Your domains:
src/bin/api/,src/lib.rs(non-Cargo parts),tests/Ticket tracking:
nbdcommands always fromquotesdb/. Markin_progressbefore starting,doneafter merging.Worktree loop (repeat until
f3dc74andce1e4fcan close):
nbd ready --json | jq '[.[] | select(.title | test("api|lib|test|DB|QuoteRepo|router|handler|migration|local|env|auth|GET|PUT|POST|DELETE|random|list|quotes|Test suite|integration"; "i"))]'- Pick highest priority unblocked ticket. Read it:
nbd read <id> --json- Create worktree:
git worktree add .claude/worktrees/quotesdb-api-<id> -b quotesdb/api/<id>- Dispatch a Bash sub-agent to implement the ticket inside
quotesdb/within the worktree- Validate:
cargo fmt && cargo check && cargo clippy && cargo test- Merge:
git checkout quotesdb && git merge quotesdb/api/<id>- Remove:
git worktree remove .claude/worktrees/quotesdb-api-<id>- Mark ticket done:
nbd update <id> --status done --json- Loop
Key architectural facts:
- API target is Cloudflare Workers (
wasm32) in prod; native Axum/Tokio for local dev and tests- DB layer uses
QuoteRepositorytrait with two impls:D1Repository(wasm32) andRusqliteRepository(native)- Auth:
X-Auth-Codeheader, stored plaintext inquotes.auth_code, 403 on mismatch- IDs: UUID v4 via
generate_id()insrc/lib.rs(done in foundation phase)- Auth codes: 4-word passphrase, generated via
rand 0.10withOsRng- Router order:
GET /api/quotes/randomMUST be registered beforeGET /api/quotes/:id- OpenAPI spec: served via
include_str!(concat!(env!("OUT_DIR"), "/openapi.json"))(done in foundation)Validation before closing any ticket:
cargo fmt && cargo check && cargo clippy && cargo testClose
f3dc74when all API tickets are done. Closece1e4fwhen all QA tickets are done.Return a summary: tickets completed, any blockers encountered, final test run output.
Orchestrator B: UI
Domain: src/bin/ui/, index.html, Trunk.toml, _redirects
Sub-project ticket: c3503b (quotesdb/ui)
Worktree prefix: quotesdb/ui/<id>
Ready tickets to start with (priority order):
9ef703— Create_redirectsfile + add Trunk copy-file directive toindex.html00d6d7— Add Trunk proxy[[proxy]]block for/api/*→localhost:30005379eb— Auth code session storage utility (src/bin/ui/storage.rs) + AuthModal pre-filldc3d2b—Trunk.toml+index.htmlfinal setup (depends on9ef703)04f865— Yew app shell, BrowserRouter, route definitions for 5 pages0fbdd5—src/bin/ui/style.cssfull stylesheet (BEM naming)bb1514— CSS content implementation- Page components: HomPage, BrowsePage, QuotePage, AuthorPage, SubmitPage
f850c6— AuthModal componentfc2f51— Error display component00d6d7— Pagination component- CI/CD:
5137d7(deploy-ui workflow) - Docs:
372790
Agent prompt:
You are a senior Rust frontend engineer implementing the
quotesdbUI (Yew + Wasm compiled by Trunk, hosted on Cloudflare Pages).Working directory: Always work from
quotesdb/at/run/media/pop/4e1ca4f1-37f1-4bd3-bad2-603166a773db/Projects/src/gitea.elijah.run/vibed/worktrees/quotesdb/quotesdb/Your domains:
src/bin/ui/,index.html,Trunk.toml,_redirects,src/bin/ui/style.cssTicket tracking:
nbdfromquotesdb/. Markin_progressbefore starting,doneafter merging.Worktree loop (repeat until
c3503bcan close):
nbd ready --json | jq '[.[] | select(.title | test("ui|Trunk|Yew|CSS|style|page|component|modal|redirect|auth|BrowserRouter|browse|submit|author|home|wasm|SPA"; "i"))]'- Pick highest priority. Read:
nbd read <id> --json- Create worktree:
git worktree add .claude/worktrees/quotesdb-ui-<id> -b quotesdb/ui/<id>- Implement inside
quotesdb/within the worktree- Validate:
trunk build(fromquotesdb/root)- Merge + mark done, loop
Key architectural facts:
- Compile target:
wasm32-unknown-unknown. Nostd::thread,std::fs, or threading primitives.- Yew 0.22 + yew-router 0.19 (only correct compatible versions).
- API calls via
gloo::net::http::Request(not reqwest — incompatible with wasm32).- Auth code storage:
sessionStorageviaweb_sys::window().session_storage()(NOT localStorage). Key pattern:auth_code_{quote_id}._redirectsfile content:/* /index.html 200— must be at project root, copied to dist/ by Trunk.- CSS: plain CSS, BEM naming (
quote-card,quote-card__text,page-browse). No Tailwind.- Trunk proxy:
[[proxy]] rewrite = "/api" backend = "http://localhost:3000"— local dev only.- In production, Cloudflare routes
/api/*to the Worker before Pages sees the request.Frontend routes (5 pages):
/→ Home (random quote + Browse link)/browse→ Paginated list + author/tag filters/quotes/:id→ View/edit/delete single quote/author/:name→ All quotes by author/submit→ New quote formValidation before closing any ticket:
trunk buildClose
c3503bwhen all UI tickets are done.Return a summary: tickets completed, any blockers, final
trunk buildoutput.
Orchestrator C: Infra
Domain: infra/, .gitea/workflows/
Sub-project ticket: 25c413 (quotesdb/infra)
Worktree prefix: quotesdb/infra/<id>
Ready tickets to start with (priority order):
2d1371— Bootstrap OpenTofu project (providers.tf,terraform.tf,infra/.gitignore)- Then: D1 database resource, Cloudflare Worker resource, Pages project, domain/routes, variables
- CI/CD:
57fe5e(deploy-api workflow),3781c9(deploy-ui workflow listed under infra) - Docs:
d5839a(infra README)
Agent prompt:
You are a DevOps/infrastructure engineer provisioning the
quotesdbCloudflare infrastructure with OpenTofu.Working directory:
infra/at/run/media/pop/4e1ca4f1-37f1-4bd3-bad2-603166a773db/Projects/src/gitea.elijah.run/vibed/worktrees/quotesdb/quotesdb/infra/Your domains:
infra/(all.tffiles),.gitea/workflows/(CI/CD YAML files)Ticket tracking:
nbdfromquotesdb/. Markin_progressbefore starting,doneafter merging.Worktree loop (repeat until
25c413can close):
nbd ready --json | jq '[.[] | select(.title | test("infra|OpenTofu|tofu|Cloudflare|Worker|D1|Pages|provider|deploy|workflow|gitea|action|migration|wrangler|domain"; "i"))]'- Pick highest priority. Read:
nbd read <id> --json- Create worktree:
git worktree add .claude/worktrees/quotesdb-infra-<id> -b quotesdb/infra/<id>- Implement. Validate from
infra/:tofu validate && tofu plan- Merge + mark done, loop
Key architectural facts:
- OpenTofu state backend: local file (
terraform.tfstate), gitignored.- Resource for the Worker:
cloudflare_workers_script(check resolved triageefee79for the exact resource name in the current provider version).- D1 binding: chicken-and-egg resolved in triage
07cafb— create D1 first (tofu apply -target), then bind its ID to the Worker.- Pages project: direct upload (no git source block). Deploy via
wrangler pages deploy dist/.- D1 migrations: separate
wrangler d1 executestep, not in OpenTofu (resolved in triage5c0c64).- Every
resourceanddatablock must have a comment explaining its purpose.- Do NOT commit
.terraform/,*.tfstate,*.tfstate.backup, or.terraform.lock.hcl.Validation before closing any ticket (from
infra/):tofu validate tofu planClose
25c413when all infra tickets are done.Return a summary: tickets completed,
tofu planoutput summary, any blockers.
Execution Notes
Ordering
Task 1 (commit) → Task 2 (ec118c update) → Task 3 (foundation agent)
↓
Task 4: 3 parallel orchestrators
(single message, 3 Task tool calls)
Coordination between orchestrators
| Concern | Resolution |
|---|---|
Cargo.toml conflicts |
Foundation agent handles all Cargo.toml tickets first |
.nbd/tickets/ conflicts |
Each ticket is a separate file — no cross-agent conflicts |
src/lib.rs |
Foundation agent owns this; orchestrators only add to src/bin/ |
| UI calling API | UI uses API endpoint paths (not shared code) — no conflict |
| QA calling API | QA tests against a running API server in tests — no shared files |
When orchestrators finish
After all 3 return:
- Run full validation from
quotesdb/:cargo fmt && cargo check && cargo clippy && cargo test - Run
trunk buildto verify UI - Run
nbd list --json | jq '[.[] | select(.status != "done")]'— should be empty or near-empty - Close sub-project tickets:
f3dc74,c3503b,25c413,ce1e4f - Close root ticket:
nbd update ec118c --status done --json - Use
superpowers:finishing-a-development-branchto mergequotesdbbranch intomain
Ticket filtering tips for orchestrators
# Find the next unblocked ticket in your domain
nbd ready --json | jq 'sort_by(-.priority) | .[0] | {id, priority, title}'
# Check if a sub-project ticket can now close (all deps done)
nbd read f3dc74 --json | jq '.dependencies'
# Then for each dep: nbd read <id> --json | jq .status