How this gets made

Build Engine

Kadova is delivered by a fleet of autonomous Claude agents working in parallel against a hand-authored backlog, gated by automated reviews and merged by a bot. This page documents where the inputs come from, how the pipeline runs, and what's still manual. No marketing. Click any file path to open it on GitHub.

InputsSources of truth

Everything the agents produce is anchored on these files. They're hand-authored — not LLM-generated — so the system has a stable spec to converge on.

The task list. ~172 entries with id, title, what, where, acceptance, tier (auto / ai_review / human_signoff), effort (S / M / L), and depends_on. Single source of truth for what's been merged vs pending.
Prose decomposition of phases into tasks. The "why" behind each backlog entry. Agents read this during their work.
Project north-star: what Kadova is, who Iron Health is, how E123 fits in, the modular structure. Required reading for every agent.
ADR-style record of key architectural choices (Supabase + Clerk JWT, RLS-everywhere, mock-fallback pattern, etc.).
Known risks across security, compliance, vendor concentration, and migration. Updated when new ones surface.
Project-level operating rules: use bun not npm, import type for type-only imports, .limit(1) not .single(), sky-blue palette only, no emojis, Heroicons, mock fallback, no edits to Phase 2 frozen files. Every agent reads this before touching code.
The exact prompt template fed to each spawned agent. {{TASK_ID}}, {{WHAT}}, {{WHERE}}, {{ACCEPTANCE}}, etc. substituted from backlog.json before dispatch.
CodeRabbit review configuration. "chill" profile, auto-review every PR, project-specific path instructions for migrations / RLS / commissions.

ProcessThe pipeline

An overnight build is one tour through this loop, repeated until the picker runs out of conflict-free work or a usage cap fires.

1

Picker selects the next batch

scripts/pick-next-task.sh scans backlog.json for tasks whose depends_on are all merged, sorts by effort (S < M < L) then module, and filters out anything that would collide with an in-flight task on a "hot file" (Settings.tsx, App.tsx, commission-engine.ts, etc.).
2

Wave dispatched

Up to 8 tasks claimed atomically in backlog.json (status → in_progress). One agent spawned per task in an isolated git worktree. The wave gets a label like wave:wave-20260513-evening and a Teams "start" card showing all task titles.
3

Agents work in parallel

Each agent reads CLAUDE.md + the dossier + its task spec, implements the feature, writes tests (≥80% coverage), runs tsc -b + vitest run in its worktree, commits, pushes a branch, and opens a PR with the wave label. Then stops.
4

Gates run cloud-side

GitHub Actions CI (tsc + vitest + lint), Playwright smoke against the Vercel preview deploy, and CodeRabbit review all fire automatically. The merge bot waits for all three to be green before doing anything.
5

Merge bot lands the PR

.github/scripts/agent-merge-bot.sh squash-merges the PR when its tier passes gates: auto tasks need CI green; ai_review tasks also need CodeRabbit ok; human_signoff tasks are labeled needs-zac and never auto-merged.
6

Backlog + project board sync

backlog-merge-sync fires on every merge, flips the task's status to merged in backlog.json, then calls sync-project-status.sh to flip the GitHub Project board's Status column (Todo → Done).
7

Orchestrator polls + dispatches the next wave

Every 2 minutes the orchestrator (a Claude session) re-runs the picker, accepts any merges, spawns a conflict-resolver agent for stuck PRs, and dispatches the next wave. Continues until 0 conflict-free picks remain or the user calls it.

WorkersThe agents

Implementation agents general-purpose

One per backlog task. Spawned with isolation: "worktree" so each gets a clean checkout. Reads CLAUDE.md + the dossier, implements the feature, writes tests, opens a PR, stops. Tonight: ran 8-at-a-time in parallel.

Conflict-resolver agents on demand

Spawned when a PR has merge conflicts that the healer cron can't auto-fix. Brief: rebase against main, semantically merge hot files (append-and-keep-both for tab arrays / route lists), run tests, force-push with --force-with-lease. Proven across 4 stuck PRs tonight.

Finalizer (inline) orchestrator

When an agent's session is interrupted before commit (worktree-cwd bug, model timeout), the orchestrator finalizes work in place: runs tsc/tests, adds the smoke spec, commits, opens the PR. Used ~5 times tonight.

Healer cron every 30 min

fleet-healer.yml rebases DIRTY PRs, retriggers stuck CI runs, resets stale agent claims (>4h old) back to pending. Cloud-side, no human needed.

SafetyGuardrails

Nothing merges to main without passing all of these. Manual merges go through safe-merge.sh which enforces the same gates.

tsc -b

Strict TypeScript type-check. No any allowed. Fails the PR build if even one type error.

vitest run

Full test suite. 4,400+ tests currently. ≥80% coverage required on new code.

Playwright smoke

Hits the Vercel preview deploy on every PR. Each task adds a tests/smoke/T-XXX.spec.ts that verifies the feature renders without 5xx or page errors.

CodeRabbit review

Pro Plus, "chill" profile. Auto-reviews every PR against project-specific path instructions (RLS, migrations, commissions, AI features).

Vercel preview build

tsc -b && vite build against the PR branch. Catches drift between branches and main.

safe-merge.sh

Wraps gh pr merge. Refuses to merge if any gate above is pending or failing. Used by the orchestrator's manual sweeps so we never bypass CodeRabbit by accident.

VisibilityFeedback loops

Teams · wave cards

One "start" card when a wave dispatches (task list), one "summary" card when all PRs in the wave settle. No per-PR spam. No failure noise — channel is progress-only.

Teams · morning report

Daily 7am MDT card with PM-friendly LLM-generated prose summary (Claude Haiku), velocity stats, security wins, action items, and what's next. Auto-fires via morning-report.yml.

Public roadmap

/roadmap.html auto-refreshes every 60s from /api/backlog (live) or /backlog.json (static fallback). Shows phase progress, AI-time remaining, recent merges.

GitHub Project board

HealthDMS Backlog Status column auto-synced (Todo / In Progress / Done) via sync-project-status.sh on every merge.

Reality checkWhat's still manual

The pipeline above describes the ideal. Here's what currently still needs a human or has known rough edges:

●
Orchestrator is interactive. Until claude -p auth on the Mac is fixed (likely fresh claude auth login), the launchd cron that would run dispatches unattended doesn't work. So today the orchestrator = a Claude session that the user kicks off with "@claude start overnight build."
●
Worktree-cwd bug. Agent Edit/Write tool calls with absolute paths sometimes resolve to the main repo checkout instead of the agent's worktree. Mitigation: agents have been instructed to use relative paths from pwd; the finalizer recovers when it slips. Real fix lives in the Claude Code tool layer.
●
Dep-chain locking at the tail. The picker is dependency-aware but can hit a state where every remaining task is blocked behind a single un-picked root task. Resolution: pick those roots manually by name when they surface.
●
Some integrations are stubbed. SFTP transport (T-169) ships with a stub edge function — production SFTP client is a follow-up. openrouter-proxy edge function not yet deployed (gates all AI features). DocuSign / Sterling / NIPR adapters have base classes but full E2E flows are still WIP.
●
Usage cap is the throttle. Claude Code Max has a rolling 5-hour usage window. A burst of 8 parallel agents at peak exhausts one window in ~5-6h. The current approach is "burst then sleep"; the long-term plan is scripts/burst-window.sh + launchd cron to run 3 bursts per night.