Otaku Solutions · Build System

The Automated Project Workflow
PRD → Beads → GitHub → Build

How an idea becomes a tracked, buildable project on this machine — vault planning compiles into a dependency-aware issue graph, scaffolds its own repo, and is drained by an autonomous beads subagent. One command per stage; the contract between stages is deterministic.

Captured: 2026-06-08  ·  Worked example: myrp-build-web (28 issues seeded)  ·  Stack: braynee · beads (Dolt) · gh · Vercel

The pipeline at a glance

Five stages. Each has one entry command and emits a typed artifact the next stage consumes. Nothing is hand-carried between stages — the vault PRD compiles into beads issues the same way every time.

STAGE 1
PRD
Author the spec in the vault against a fixed schema. The MVP-Definition gate forces real decisions.
braynee:prd
STAGE 2
Seed
Parse Acceptance Criteria into beads issues — priorities, milestones, dependencies, DoD gate.
prd-seed.mjs
STAGE 3
Repo + Deploy
Scaffold the app, give it its own standalone repo, create+push GitHub, then wire it to Vercel and push env to all 3 scopes.
create-next-app · gh · vercel
STAGE 4
Track
Beads is the source of truth, mirrored three ways so agent, UI, and vault all agree.
bd · TodoWrite · mtn
STAGE 5
Build
An autonomous subagent drains the ready queue: claim → execute → close → repeat.
braynee:autopilot
★ The design goal — created once, reachable everywhere

The whole point of this flow: from the moment a project is created, everything about it lives somewhere you can reach from any machine — local laptop or a cloud box. Three things must travel, not just the code:

  Code → GitHub  ·  Deploy → Vercel (linked, env in all scopes)  ·  Tasks → beads (in git + a cloud Dolt remote)

Clone the repo on any machine and you get the app, the deploy wiring, and the full issue backlog — no "but the tasks were on my other laptop." That requirement is exactly why Stage 3 includes Vercel + env, and why beads must reach a remote (below).

1 PRD — plan in the vault

The PRD is the contract between thinking (vault) and execution (code). It lives at 2. Areas/Product Manager/PRDs/<Name>.md and follows a schema strict enough that a script can read it.

Three commands

  • prd-new.mjs — scaffold the canonical schema
  • prd-audit.mjs — re-runnable schema check, reports gaps
  • prd-seed.mjs — compile Acceptance Criteria → beads

The folder: join key

Frontmatter folder: names the repo directory — it's how the PRD binds to its code. folder: myrp-build-web~/code/myrp-build-web. This is the thread that ties spec to build.

The MVP-Definition gate

A PRD without this section is not seedable. It forces three decisions before any issue exists — so scope is locked, not discovered mid-build:

Worked example — myrp-build-web

Auth = none (stateless marketing site) · Freemium = display-only (purchase lives in the app) · 5 core features (landing, pricing, download, docs, audience capture). The whole site is "built from source" — content derived from the real myrp-build app, the same way braynee-web derives from hooks.json.

2 Seed — compile the PRD into beads

This is the magic step. prd-seed.mjs reads the Acceptance Criteria section and turns each line into a beads issue, deterministically. The format is the API.

# The seed contract — one line → one `bd create`
### Milestone: MVP
- [ ] **[P0] Pricing page** — tiers from data/plans.ts; CTA = Download. No Stripe.
       └─────┘ └──────────┘   └──────────────────────────────────────────┘
       priority   bd title                    bd description

Parse rules

In the PRDBecomes
[P0]…[P3]priority (critical→low)
title before bd title
body after bd description
### Milestone: Xlabel milestone:X
other linesignored

Priorities seen this run

P0 critical   P1 high

P2 medium   P3 low

The seeder also auto-adds a milestone gate: it wires dependencies so the Quality & Deploy issues block on the feature work.

What the seeder injects for free

Beyond your hand-written criteria, the seeder appends a Definition-of-Done molecule (the ship-pipeline gate, see §6) and adds dependency edges so the graph reflects real build order:

node prd-seed.mjs "myRP-build-Website" --dry-run   # always preview first

Done. 28/28 issues would be created, 8 dep edge(s) would be added.
Result this session

23 hand-written criteria + 5 auto-injected DoD issues = 28 beads issues, 8 dependency edges, across milestones MVP · v1.1 · v2 · Quality&Deploy. The PRD frontmatter flipped to seeded: true, seeded_count: 28 — so it can never be silently double-seeded.

3 Repo + Deploy — standalone GitHub, wired to Vercel

Order matters: scaffold → bd init → seed → wire to Vercel. Each project is its own repo — never a monorepo, never nested in a parent — and creating the repo is not finished until it's connected to Vercel with env vars set across every scope.

# 1 · scaffold the app (Next.js App Router + TS + Tailwind)
npx create-next-app@latest myrp-build-web --typescript --tailwind --app …

# 2 · own git repo for THIS project (not the parent folder)
git init -b main

# 3 · beads, pointed at the shared Dolt server
bd init --shared-server --external --prefix myrp-web --role maintainer

# 4 · seed (stage 2)
node prd-seed.mjs "myRP-build-Website"

# 5 · create + push the standalone GitHub repo
gh repo create hamchowderr/myrp-build-web --private --source=. --remote=origin --push

3b · Wire to Vercel + set env everywhere

Repo creation isn't done at gh repo create. The repo must be connected to Vercel (so every push deploys) and have its environment variables set across all three scopesproduction, preview, development — with values injected from Infisical or Agent Vault, never typed or committed.

# 6 · link the project + connect the GitHub repo (push → auto-deploy)
vercel link
vercel git connect          # branch push → preview · main → production

# 7 · set each var across ALL THREE scopes — value injected, never printed.
#     Infisical injects → piped straight into vercel env add (encrypted, not logged)
infisical run --recursive --silent -- bash -c '\
  printf "%s" "$NEWSLETTER_API_KEY" | vercel env add NEWSLETTER_API_KEY production preview development'

# …repeat per secret. Agent Vault path: wrap the CLI via the VPS broker (HTTPS_PROXY recipe)
# for VPS-brokered creds. Either way the value never lands in the transcript or a file.

# 8 · pull a local .env.local for dev (placeholders only ship in .env.example)
vercel env pull .env.local

The three scopes — set them all

ScopeUsed by
productionthe live main deploy
previewevery feature-branch preview URL
developmentvercel dev / local pull

A var missing from preview is the classic "works on prod, broken on the PR preview" bug.

Two secret sources

  • Infisical — folder-organized project secrets; infisical run --recursive --silent injects at runtime.
  • Agent Vault — the Hostinger-VPS credential broker; wrap the CLI via its HTTPS_PROXY recipe for VPS-brokered creds.

Rule: confirm a secret by mask (type/length), never by value. Never infisical secrets/get/export — those print.

Why this lives in "Repo," not a later step

A repo with no Vercel link and no env is a half-created project — the first preview deploy will fail on a missing key. Treating link + env-everywhere as part of repo creation means the very first push already produces a working preview. (In the DoD gate, §6, these are phases 4–5.)

Hard-won guardrail — one project, one repo

This session hit a stray empty git repo at ~/code itself. Because the projects-root was accidentally a repo, create-next-app saw "already in git" and skipped making one for the project — so setup commits landed in the wrong place. Fix: move the stray .git aside (preserved, never deleted), then git init the project on its own. Always verify git rev-parse --show-toplevel points at the project, not a parent.

4 Source of truth — the three-way mirror

Beads is the single source of truth for tasks. It mirrors two more ways so the agent's list, the live UI, and the vault never drift apart.

● TRUTH
beads (bd)
Dolt-backed issue graph: status, priority, dependencies, notes. Survives compaction & restarts. The canonical state.
◐ LIVE UI
TodoWrite
The in-session checklist you see while the agent works. A beads-todo hook fires on every bd state change to keep it in sync.
❄ VAULT
TaskNotes (mtn)
File-based tasks inside Obsidian, auto-synced by braynee — so the vault reflects the same work, searchable later.

Why three? Each serves a different reader: the agent queries beads, the human in the terminal watches TodoWrite, and the vault / future sessions read TaskNotes. Writing once to beads fans out to all three — this session, the seed reported TaskNotes: 28 new mirrored automatically.

5 The beads subagent — autonomous drain

braynee:autopilot is the engine that turns a seeded backlog into shipped work without hand-holding. It runs a tight loop and is CLI-only (no MCP) for reliability.

loop:
  bd ready          → pick the next unblocked issue (deps satisfied)
  bd update --status in_progress   → claim it (also mirrors to TodoWrite)
  …execute the work…   → write code, run tests, commit on a feature branch
  bd close --reason "…"            → done; unblocks dependents
  repeat
# stops on: empty queue · failed claim · 3 consecutive failures
Invoke it

"autopilot", "drain the queue", "work the backlog" → spawns the subagent. For myrp-build-web, the first ready P0s are Source-derived content data layer, Marketing landing, Pricing, Download.

6 Definition of Done — the ship gate

Every project under ~/code inherits one DoD, auto-seeded as that Quality&Deploy molecule. DONE = CI green + a live preview deploy. Production promotion is always a separate, human-gated step — an agent never pushes to prod.

#PhaseWhat
1Local buildscaffold per defaults; biome check clean; it builds
2Test gate (pre-commit)Tier 1: Vitest + Supertest, fully mocked, AIMock at the LLM boundary
3Repogh repo create --private; work a feature/* branch — never commit to main
4–5Link + envvercel link; vercel env add across prod/preview/dev — secrets via Infisical, never pasted
6CI gateGitHub Actions runs full tiers (Vitest + Supertest + Playwright) with AIMock; green on the PR
7Previewpush branch → Vercel preview deploy; capture the URL
8DNS (if custom domain)Cloudflare scoped token + API; else use the *.vercel.app URL

Testing tiers (mocked first, live gated)

  • Vitest — units, the dev loop
  • Supertest — HTTP/API boundary
  • Playwright — browser E2E
  • AIMock — deterministic mock LLM server

Real API keys are the last tier, never the first.

Per-project overrides

The gate narrows itself: no custom domain → skip phase 8; no LLM in the loop → AIMock not required. State any deviation in the PRD.

⚠ For a static marketing site like myrp-build-web, the AIMock/Supertest parts of the auto-seeded gate don't apply — trim those issues to fit (lint + Playwright + preview).

What's underneath — how beads travels everywhere

"Tasks reachable from anywhere" is a real requirement with a real mechanism. Beads rides on Dolt — a MySQL-compatible database with git-style version control (history, diffs, branches, push/pull to a remote). That last property is what lets the issue graph leave this laptop.

① IN-GIT SNAPSHOT
.beads/issues.jsonl
bd auto-exports the whole issue graph to .beads/issues.jsonl, committed with the repo. Clone anywhere → the backlog comes with it (bd auto-imports on first use). This is wired today.
② LOCAL ENGINE
Shared Dolt server
All projects share one server at ~/.beads/shared-server/ (this run: port 3308); each gets its own DB (myrp_web). bd init --shared-server --external joins it — fewer orphan processes, one local home for live queries.
③ CLOUD REMOTE
DoltHub sync
Push the live database (not just the jsonl) to a Dolt remote under the personal chowderr namespace so it pulls across machines. The repo is auto-created via the DoltHub REST API (token in Infisical prod), then bd dolt remote add + bd dolt push. This completes "anywhere."
Status for myrp-build-web — all three tiers LIVE ✅

① 28 issues committed as issues.jsonl in the GitHub repo · ② live in the local shared Dolt server (db myrp_build_web) · ③ pushed to chowderr/myrp_build_web on DoltHub (public, 28 issues verified via the SQL API). The DoltHub repo was auto-created programmatically: POST /api/v1alpha1/database with the DOLTHUB_API_TOKEN (Infisical prod) → bd dolt remote add origin chowderr/myrp_build_webbd dolt push. Note: there is no otaku-solutions org on DoltHub — DBs live under the personal chowderr namespace.

★ Important — tier ③ is OPTIONAL, never a requirement for collaborators

The DoltHub remote (otaku-solutions org) is owner-specific cloud infrastructure — Chowderr's account, Chowderr's convenience for working across machines. When this project (or this whole workflow) is shared with anyone else, the DoltHub sync must not be a dependency. A collaborator clones the GitHub repo and is fully operational on tiers ① + ②: the issues.jsonl in git gives them the backlog, and a local bd init gives them their own engine. No DoltHub account, no otaku-solutions access, no paid tier required. This mirrors the standing rule that the tooling ships zero user-specific paid-tool dependencies — bake the cloud remote in for yourself, but the shared workflow degrades cleanly without it.

Guardrails baked into the flow