| name | consort |
| description | Consort, a spec-first, test-driven agent framework for building transactional applications on Lakebase-paired projects: a deterministic orchestrator drives role agents through a spec-first design lane (Spec Driven Development) and a Test Driven Development build lane (RED-GREEN-REFACTOR) that runs against a live copy-on-write branch of a real, governed Lakebase database (Databricks' serverless Postgres/OLTP database, not the Delta Lakehouse), composed with paired-branch primitives (cheap experiments, parent-aware schema diff, real per-branch databases). The controls are code the agent cannot edit: gates fail closed, tests are immutable within a unit of work, and a green result is a real test run against real data. Spec-first means the spec is drafted, reviewed, and frozen at gates before any build cycle runs; the spec, the architecture, and the database all evolve increment over increment. Use when planning a new feature, running design-spec gates, running TDD cycles, comparing parallel experiments, or detecting build bad smells. Imports software-design-principles canon. Builds on lakebase-scm-workflows. |
| user-invocable | true |
Consort – agent contract
Agent-facing contract: hard rules, phase flow, agent prompt index, and concrete code patterns for the kit's orchestration primitives.
For the human-facing overview (lexicon, roles narrative, how-to-use prompts, project entry points) see README.md.
Hard rules
The contract every agent (Navigator, Driver, Orchestrator) and every human collaborator must honor.
- Tests are immutable until the test list itself is renegotiated through the PO. Never delete or weaken a test to make it pass.
- "Minimal code" means minimal honest code that satisfies the current test list, not just the current test. Use the test list as your horizon.
- After every GREEN, ask: "would a fresh reader infer the right concept from this API now?" If no, request REFACTOR before the next test.
- Test at the outermost public boundary that maps to the AC. Inner-loop unit tests are reserved for pure logic that can't be exercised through the outer boundary.
- A correct refactor should not change the outer-boundary tests. A refactor that requires editing tests is suspect.
- Never make a private method public to test it.
- Test count is a lagging indicator. The leading indicator is "how cheap is the next test?" Rising cost = design problem.
- Spike code is throwaway. Promote nothing from a spike branch into a TDD branch except notes.
- Experiments are scoped to a story (the branch forks from feature HEAD). N=1 is one experiment per story (iterative refinement, no promote/synthesize ceremony); N>=2 races competing strategies for that story. The PO accepts a story's experiment by merge (git-merge + run its migrations against the feature branch DB), or discards/revises it.
See agents/navigator.md and agents/driver.md for per-role specializations.
Phases and gates
Consort is spec-first and test-driven: it composes two disciplines back to back. The design lane is spec-driven – spec drafting, architectural review, test-list construction, all driven by /design – and the build lane is test-driven – the RED → GREEN → REVIEW → REFACTOR cycles driven by /build. Spec-first means the design lane freezes the spec at the spec + test_list gates; the build lane only starts once they are approved, so the build always runs against a reviewed spec.
Iterative and evolutionary. The freeze is per increment, not forever. Across increments, all three dimensions evolve and are never treated as static: the spec and features are living , each sprint the PO re-plans, folding in what the last working software revealed; the architecture evolves under fitness functions (@architectural-design-principles/evolutionary-architecture.md); and the database evolves by migration on the paired branch, diffed against its parent (@architectural-design-principles/evolutionary-database-design.md). The rule is: spec-first within an increment, evolutionary across increments.
Gates are keyed (not numbered): spec / plan / test_list / promote / deploy. The SDD lane runs PER STORY (it streams), and experiments + plans are per-story.
| Step (per story unless noted) | Output | HITL gate |
|---|
| Spec drafting | feature-spec.{md,json} (feature) + per-story story.{md,json} + acs/<AC>.{md,json} | spec gate |
| Architectural review | layer + architectural_notes on each AC; architecture.{md,json} (holds the NFRs) | folds into the spec gate |
| Test-list construction | per-story test-list-per-story.json (scoped from the feature test-list.{md,json}) | test_list gate |
| Build (per AC) | cut a per-story experiment; RED -> GREEN -> REVIEW -> REFACTOR cycles producing tests + code | Continuous: smells; per story: accept (merge) / discard / revise |
| Deploy | working software on the experiment branch (reachable + verify) | deploy gate |
Sprint planning has its own plan gate. For N>=2 experiments within a story, the menu-pick promote/synthesize decision is recorded under synthesis/<F>/. Refuse to transition if prior-step artifacts are missing or invalid.
Enhancement review (placeholder, TODO)
Enhancements are decided iteratively. After a feature ships, new work is proposed and prioritized with the Product Owner during sprint planning (/plan) - the same gate that commits any sprint - so the loop keeps returning to the PO for the next increment.
TODO (not yet implemented): add a review role that inspects the running, deployed software (post-deploy) and recommends concrete enhancements back to the PO as candidate features for the next /plan. This mirrors the existing review lens (the Architect Reviewer / Navigator review the spec and code) but aimed at observed runtime behavior rather than source. To flesh out: the trigger point (post-deploy), the inputs (the reachable endpoint + feature-status), the output (enhancement candidates feeding planning/feature-proposals.md), and the PO hand-off. Until this lands, enhancements are surfaced manually at sprint planning.
The phases + gates above are the PER-FEATURE pipeline that /design (phases 0 to 2 + gates 1 to 4) and /build (phase 4) run. They sit inside a larger orchestrated loop:
Orchestrated commands (the dev loop)
Every command is a thin invocation of the deterministic orchestrator driver (consort-drive), scoped to a phase range. The driver sequences the work and spawns each role as a subagent (claude -p --agent <role>); routing is code, not an LLM. Gates always pause for a human decision: --gates interactive (the default for the live slash commands) stops at each gate so the human answers; --gates proxy (headless / CI) has the Human Proxy answer.
Tier 1: /sprint = plan ─> [PLAN GATE] ─> per feature: /design ─> /build ─> /deploy
▲ │
└──────────────────── working software feeds back ─────────────────┘
Tier 2: /plan /design /build /deploy (run ONE phase, then stop + suggest next)
/spike (throwaway exploration, outside the loop)
/sprint [name] (Tier 1, the top-level orchestrator): runs the whole sprint as one continuous flow, plan to the plan gate, then claim + drive each backlog feature design -> build -> deploy. Re-invoked per cycle; resumable (halts at the next HITL gate for the human, continues on re-run). consort-drive --sprint <name>.
/plan [name] (Tier 2, sprint planning, ABOVE the per-feature loop): the Spec Author proposes the candidate breakdown (.consort/planning/feature-proposals.md); the Architect t-shirt-sizes the candidates (.consort/planning/estimates.json, XS/S/M/L/XL); the Product Owner commits the backlog by authoring a feature-request.md per feature that fits sprint capacity; the deterministic sync-backlog step projects .consort/sprints/<name>/backlog.json (committed ids + sizes); the sprint plan gate is the HITL checkpoint. Stops there (does not flow into design). Requires project intake (product-overview.md + nfrs.md, +design-brief.md for UI) as a precondition. --sprint <name> --plan-only.
/design <feature-id>: the SDD (Spec Driven Development) lane. Claims the paired branch (Step 0), enforces the feature's feature-request.md + project intake (Step 0.5, a precondition, NOT a gate), then drives the per-story design lane (Spec Author -> Architect Reviewer -> DBA -> Test Strategist) to the spec + test_list gates, producing the executable spec. The DBA turns the architect's logical persistence contract into a physical schema (db-design.json). --only design.
/build <feature-id>: the TDD (Test Driven Development) lane. RED -> GREEN -> REVIEW -> REFACTOR cycles + per-story acceptance against the frozen spec, to ready-for-review (requires the SDD lane done). --only build.
/deploy <feature-id> [--target local] [--story <s>]: deploys the merged feature (or one story's branch) + verifies reachable + feature-verify; the deploy gate is the working-software review the PO signs off (the local target is the only one implemented; remote release is the scaffolded merge.yml). --only deploy. For a hands-on review the human can run ./scripts/run-dev.sh to serve the app locally (migrates + hot-reload) and open it in a browser.
/spike <slug> [--for <feature>]: throwaway exploration on its own paired branch, OUTSIDE the workflow (no gates). Notes carry forward into a feature's design-spec gate; code is never promoted. consort-spike.
The same orchestrated path runs for real and headless; headless, the Human Proxy stands in for the human at every supply + gate (below).
Headless / Human Proxy mode
By default every gate is HITL (the workflow halts for the Product Owner). When LAKEBASE_CONSORT_HUMAN_PROXY=1 (set by CI and the smoke), the approver role is performed by the human-proxy identity, a diligent stand-in, not a rubber stamp. For the artifact gates (spec/plan/test_list/promote), it approves a gates.json gate and emits gate.approved only when both hold (the deploy gate is certified differently, see the /deploy bullet below):
- Given the artifacts: the gate's expected artifacts EXIST (a missing one is refused).
- Format-conformant: each validates against its declared format (JSON against its schema; narrative MD against its required sections, see
references/spec-format.md + consort-gate-conformance). A malformed artifact, or one missing a required section, is refused.
So the producing role's job here is to HAND the approver complete, conformant artifacts, recording its recommended resolutions (decisions, NFR acceptances, orderings) INSIDE them rather than leaving open questions for a human reply. A gate advances because real well-formed work was verified, never because it was skipped; a missing/malformed artifact hard-blocks in CI exactly as for a human.
Beyond the gates, the Human Proxy stands in wherever the path needs human input (consort-human-proxy has two subcommands, supply and approve; both validate-then-place, neither fabricates or skips):
- Project intake (precondition of
/plan + /design): supplys product-overview.md / nfrs.md / design-brief.md from $LAKEBASE_CONSORT_RECORDED_INTAKE_DIR; consort-intake then passes because they're present + conformant.
/plan backlog: the Architect sizes the candidates live; the Proxy supplys the recorded feature-request.md files (the PO's groomed sprint). sync-backlog projects backlog.json (committed ids + sizes).
/deploy gate: confirms the app came up reachable AND the verify passed, then records gate.approved; never approves a non-reachable or failed-verify deploy.
Check the mode with [ "$LAKEBASE_CONSORT_HUMAN_PROXY" = "1" ]. Absent/unset = normal HITL.
Configuration (one source of truth per setting)
Every knob has exactly ONE home; see CONFIG.md for the full table + writers. In brief:
- Project settings (what the project IS:
uiTrack, gates, deployTarget, the per-role model matrix, build cadence) live only in .lakebase/consort-config.json, resolved file -> code default by resolveConsortSettings. There is no env or flag override at read time. The writers are create-project (create-time, e.g. --ui-track) and the drive's write-through flags (--gates / --deploy-target / --no-sizing), which persist INTO the file before it is read.
uiTrack is the single door for the UX lane. It drives BOTH the UX Designer (design-guide / ia.md / adherence gate) AND the e2e harness (create-project derives e2e from it, and refuses a UI project without it). A UI project can never run with the UX lane off.
- Run-mode knobs (record/replay, headless, debug, e.g.
LAKEBASE_CONSORT_AUTO_CONTINUE, _TRACE, _RECORD_DIR) are per-invocation LAKEBASE_CONSORT_* env vars, read via consortEnv (canonical prefix; the legacy LAKEBASE_CONSORT_* / LAKEBASE_CONSORT_* prefixes are still honored). They are NOT project settings and never belong in consort-config.json. (LAKEBASE_CONSORT_HUMAN_PROXY, the headless-approver switch, is a raw-shell-checked var the command templates read directly, not a consortEnv knob.)
- Capture-time conditions live in a scenario's
scenario.json and are funneled into create-project flags by capture-scenario.sh; they never reach the drive directly.
Agent roles (the per-role agent runtime)
Each role is a separate agent definition under agents/ with frontmatter (name, a description that is the auto-selection criteria, least-privilege tools, a strongly-recommended model, memory: project, color) and a body that is its system prompt. The roles communicate only through the artifacts on disk, the artifact is the inter-agent API.
agents/product-owner.md – the PO's facilitator: runs the intake interviews + drafts product-overview.md / nfrs.md / design-brief.md, authors the sprint's feature-request.md files at /plan, and is the approver at every HITL gate. Headless, the Human Proxy plays the PO.
agents/spec-author.md – the Spec Author (BA). At /plan, proposes the feature breakdown from product-overview.md + nfrs.md (feature-proposals.md, the PO's input). At /design phase 0, turns one feature's feature-request.md into the structured draft spec (feature-spec.{md,json} + stories + ACs).
agents/ux-designer.md – between phase 0 and 1, UI projects only: owns design-guide.{md,json} + ia.md and the UX adherence gate. Skipped for API/CLI/Infra-only features.
agents/architect-reviewer.md – phase 1, populates layer and architectural_notes, covers every nfrs.md Required item via architecture.json brief_ref, imports software-design-principles.
agents/test-strategist.md – phase 2, builds the Beck-style ordered test list.
agents/navigator.md – phase 4 PLAN + RED + REVIEW.
agents/driver.md – phase 4 GREEN + REFACTOR.
- Deploy + promote are deterministic (no agent). The orchestrator itself runs
consort-deploy (deploy the increment, poll reachable, run the feature verify) and lakebase-scm-merge (promote via PR + CI + merge), surfacing the deploy and promote gates to the PO. These phases log under the release-engineer label but spawn no LLM agent.
The orchestrator is the deterministic driver (consort-drive), not an LLM agent: it routes over workflow-state.json, hands each phase to the right role agent above, carries artifacts forward, and surfaces every gate to the PO. It writes no spec/code/test/deploy.
How the orchestrator runs them. The role defs are scaffolded into the project's .claude/agents/ (so Claude Code can discover + spawn them; the skill copy is the source). The driver computes the next action as a pure function of the recorded state, then spawns the role for that phase via claude -p --agent <role>. Routing is code, not a model: there is no LLM orchestrator session. Before spawning a role, the driver resolves the model from the project's .lakebase/consort-config.json via resolveConsortSettings (roles.<role>.model, the single source of truth for project settings). Resolution is consort-config.json role model ?? legacy .lakebase/agent-config.json (override ?? recommended) ?? built-in recommended ?? inherit: agent-config.json is honored only as a fallback for projects scaffolded before consort-config.json. The HIL sets per-project models at lakebase-create-project; each role's recommended model lives in its definition's model: (mirrored in RECOMMENDED_MODELS).
References
references/spec-format.md – full .consort/ directory layout + markdown ↔ JSON contract.
references/orchestrator-contract.md – how the agent DRIVING /sprint /design /build /deploy must behave: drive to completion via consort-next, surface only HITL gates + blockers, report outcomes (not process), verbose/eval narration opt-in. The orchestrator's counterpart to agent-operating-rules.md; the command templates load it.
references/next-schema.md – the consort-next / .consort/next.json "what next" surface the orchestrator contract drives on.
references/agent-logging.md – structured agent log format + per-role emit points. Every role emits what it is doing via consort-log (debug = reasoning, info = outputs) to the centralized .consort/agent-log.jsonl.
consort/config/schemas/ – JSON Schemas validated by spec-sync.ts.