Skip to content

Development Workflow ​

KAIROS is a Human-in-the-Loop (HITL) pipeline. Every phase produces a concrete artifact that the user validates before the next phase begins, except three gates that continue on their own when nothing needs a decision (see Gates that continue on their own). The AI does the work; the human controls the gate.

Gates only work if the orchestrator is your primary agent

Every gate below is an interactive AskUserQuestion prompt — but only when the orchestrator runs as the session's primary agent (claude --agent orchestrator-agent, started at launch). Typing @orchestrator-agent or "use the orchestrator" inside an already-open chat dispatches it as a subagent instead, which unconditionally loses AskUserQuestion — every gate below silently degrades to a text menu, and the orchestrator dies if the parent session ends mid-pipeline. See Claude Code setup for the full explanation.

The pipeline, phase by phase:

PhaseAgentProducesGate
0Orchestrator + Impact Assessment (+ optional Context Extractor)00b-impact.md + derived pipelineStart gate
1PM Agent01-requirements.md✅ / ✏️ / ⏭️ / ⛔
2Architect Agent02-architecture.md✅ / ✏️ / ⏭️ / ⛔
3Implementer (test-first, code-first, or Layered Mode)Code + 03-implementation.mdPlan gate, then ✅ / ✏️ / ⏭️ / ⛔
4Code Reviewer (review wave)04-review.mdone combined review gate ✅ / ✏️ / ⏭️ / ⛔
4bSecurity Reviewer (optional, review wave)04b-security-review.mdsame gate
5Test Verifier (review wave)05-test-verification.mdsame gate
5bQA Plan Agent (optional)05b-qa-plan.md✅ / ✏️ / ⏭️ / ⛔
6Release Planner06-deployment-plan.md✅ / ✏️ / ⛔
6bDocumentation Agent (optional)06b-documentation.md, then the documentation files✅ / ✏️ / ⛔

Phases 4, 4b and 5 run together as one review wave: the active reviewers read the same code, in parallel where the host allows it, and you answer one gate for all three (see Review Wave).

Phase 3 routes to one of three paths, chosen from the design's facts right before the plan: the TDD Implementer (plan gate, then RED → GREEN → REFACTOR), the code-first Implementer (plan gate, then code and the tests the project calls for), or Layered Mode (Claude Code only, offered when the TDD path spans two or more layers) where an Implementer Lead defines binding contracts and the Orchestrator then runs Tests / Backend / Frontend / Database layer agents in stages before the Lead aggregates their output.

Each HITL checkpoint is an interactive prompt (Claude Code's AskUserQuestion tool), not a text menu to reply to. Before it, if the phase's output has a Risks/Issues/Findings table with any row left undispositioned, the Risk Disposition Loop walks through those rows first — one at a time (or up to 4 per prompt), with Accept / Mitigate now / Escalate / Defer — instead of forcing an approve-or-reject on the whole table at once. Each row is worded so you can answer it with only that text in front of you: the open point in product or code words, two or three alternatives with what each costs, and the internal ids (T5, G13, AC-2) only as a trace in parentheses. When a row names an id you cannot place, the Orchestrator resolves it from the reports it holds before asking, and says so when it cannot. Only once every row has a disposition does the whole-artifact gate below appear; it marks one option as recommended based on the phase's own status, and always leaves a free-text option for detailed feedback:

  • ✅ Approve — continue to the next active agent
  • ✏️ Request changes — agent revises and re-presents. Chosen without typing anything, it asks what should change (answer an open question, describe the change, or go back to the gate) and never re-runs the agent with empty feedback
  • ⏭️ Skip next — approve this output, jump past the next active agent
  • ⛔ Stop — abort the pipeline

Only derived (or explicitly added) agents run. Order is never changed.

Gates that continue on their own ​

A gate with nothing to decide costs a round trip, and in real runs most of them resolved as a bare Approve. Three gates therefore continue without asking, under one rule: the Orchestrator runs every check it would run at the gate, and asks you only when one of them turns something up.

GateContinues when
Bug triagethe bug reproduced, its root cause was found, the triage does not call it not-a-defect, and the issue is not an older checklist template (the Start Gate comes next and shows the whole pipeline)
Requirements (Phase 1)effort is simple_fix or medium, and the analysis left no open question, no scope change and no blocking constraint, and the Risk Disposition Loop had nothing to ask you
Implementation (Phase 3, last wave)effort is simple_fix or medium, and the Risk Disposition Loop had nothing to ask you, no constraint was added, the tests pass, the artifact is valid, no file falls outside the plan and a reviewer is active next. The review wave is the check that follows

When one continues, the Orchestrator prints one line naming what runs next and the rows it accepted for you (low, and medium in a simple_fix), and logs it in _tracking.md. A significant_rework run keeps every gate after the triage (the effort is not known yet at the triage gate, and the Start Gate follows it). Reply every gate at the start gate, or set phase_gates: every_gate in ledger/run.md, to be asked at all of them.

To judge whether a gate that continues on its own is safe, compare what changed after it, not how often someone approved: a gate that continued is "approved" by construction, so an approval rate says nothing. The log line of every gate ends with two keys, auto-accepted: (rows the Orchestrator accepted for you) and, when you answered, off-recommendation: (rows you dispositioned differently from the (Recommended) option). Together with the MUST — from <phase> R<id> rows in ledger/constraints.md, they show whether a row that was accepted for you was promoted later, which is the case the continuation rule exists to avoid.

These always ask. The architecture, because it holds decisions. The implementation plan, because it is the last gate before source files change. The combined review gate (and a recheck that turns up a medium row, as before), because that is where you changed decisions in real runs (a low row promoted to Mitigate now), which no signal can predict. The QA plan, release plan and documentation draft, because they post to the tracker or write outside .kairos/. Continuing saves the minutes you spend answering, not the time the agents take or the days a gate sits unanswered.

Artifact Format — Markdown + Frontmatter ​

Every phase writes a single Markdown file: a small YAML frontmatter header carrying only what the orchestrator branches on — a verdict, the tallies its status rules threshold, a loop signal where a loop exists — followed by the report body (data model tables, issues lists, findings, runbooks — what the human actually reads at the gate). Every body opens with the same five-line ## Summary block — What / Decision / Needs your attention / Open / Next — so a gate is readable in seconds without scrolling the whole artifact. Open carries the ledger/open-questions.md IDs of the questions that phase left unanswered, which is what keeps an open point from being buried in a paragraph nobody rereads; the Orchestrator prints that block verbatim at the checkpoint rather than writing its own version of it, adds two counts of its own (rows dispositioned, and questions still open across every phase — a cross-check against what this one artifact claims), names the artifact path, and opens the full file only if you ask — the detail underneath is the next agent's prompt input, and putting all of it in front of you every phase is what turns a gate into a document review. Nothing in this pipeline parses these files with real code — every consumer is either the next agent reading it as prompt text or a human at a gate — so a full schema or a long issues list is plain Markdown, not JSON: unreadable as nested JSON, but a table that scans in seconds. Any Risks/Issues/Findings table carries a Disposition column, left empty by the agent and filled in by the Risk Disposition Loop above.


Phase 0: Prep & Pipeline Derivation ​

Pre-pipeline (optional, standalone — you launch it yourself):

  • Run context-extractor-agent first to produce 00-context.md (full-repo scan — stack, patterns, conventions). Launch it as the session's primary agent, the same way you launch the Orchestrator — see your host's setup page. Naming it with @ inside an already-open chat dispatches it as a subagent, and a subagent has no AskUserQuestion: its confirmation gate degrades to the text-menu fallback.

Pipeline start:

  • Developer provides a natural-language feature request (with optional issue reference)
  • Orchestrator loads 00-context.md, 00b-impact.md, and 00c-bug-triage.md if present. A triage on disk is attached to every later subagent prompt
  • Bug-Input Check: if the input reads as a bug report — a symptom against an expectation, a stack trace, reproduction steps, "this used to work" — and no 00c-bug-triage.md exists, the Orchestrator offers to run bug-triage-agent first. On accept it dispatches it with mode: orchestrated: the agent reproduces, finds the root cause, writes 00c-bug-triage.md, and returns without a gate of its own, which the Orchestrator then presents as it would any phase artifact
  • Impact Grounding: when a fact is needed and 00b-impact.md does not exist, the Orchestrator dispatches impact-assessment-agent with mode: orchestrated. A fact is needed on a derived run that covers analysis or development, and on a checklist or manual pipeline that names the agent. A run limited to review and delivery (finalizziamo) does not start it: the effort comes from an Effort: line, the issue's size: label or medium, the domains from the changed files, and the start gate prints one line saying the assessment did not run and that documentation-agent is not derived. It reads the issue and the code it touches and reports facts, never agent names: size and effort, domains touched, whether the project has a test suite, whether a contract changes, whether the issue asks for code at all. It reads in proportion to the change, so a one- or two-file issue costs a short read and a short artifact, and when a triage exists it starts where the triage's evidence stops instead of reading the same files again. The Orchestrator writes 00b-impact.md and resolves its Risks table row by row
  • Derivation: the Orchestrator applies one rule table to those facts (see Pipeline Templates). At this point it decides pm-agent, architect-agent, whether an implementer runs and code-reviewer-agent. The implementer itself is chosen right before the plan; the review agents at the implementation gate; QA plan, release planning and documentation at the review gate. A triage's recommended_entry can raise the impact assessment's effort, because it comes from a reproduction, but never lowers it: a quick-fix against a medium or larger measurement keeps that measurement and the start gate says so. The measurement still stands on its own evidence, since the assessment sizes the change around the triage's root cause (the tests that cover it, the callers it can break) and not the single symptom the triage reproduced
  • Manual QA setting (once per project, asked late): whether a person verifies features by hand is the one input to the QA plan rule that no code can supply, so it is stored in .kairos/.manual-qa, or read from the manual-qa: line of .kairos-cfg/config when the team committed the answer there, in which case it is never asked (see Customizing KAIROS). It is not asked at the start. The Orchestrator asks it at the gate that decides the QA plan (the review gate normally), and only when the answer could change that decision: the delivery area is selected, qa-plan-agent is not skipped, no VERIFICATION constraint already put the plan in, and the change leaves something for a person to check (no test file, an AC-n routed to manual verification, a frontend change). The question names that fact (No test file in this change: does a person verify by hand?), so it reads as a consequence of the change and not as "does a QA phase exist". A run that never reaches that point never asks
  • QA directory setting (once per project, only when a QA plan needs a file): asked before the QA plan runs when the issue belongs to an epic (the plan has to read the epic's existing file), and at the QA gate otherwise, when the plan turned out to need one. The answer is stored in .kairos/.qa-dir, or read from the qa-dir: line of .kairos-cfg/config when the team committed it there, which skips the question. The Orchestrator proposes docs/qa-plans/ and accepts any other path inside the project; the file is never written before you have approved the plan
  • Model settings (optional, Claude Code): model.<agent>: <alias> lines in config, in the project's .kairos-cfg/ (committed, shared with the team) or in ~/.kairos-cfg/ (yours alone), written by /kairos:setup; the older models files are still read, and the project beats your home folder. The Orchestrator reads them before each dispatch and passes the alias as the call's model, which outranks the agent's own model:; without the file every agent runs on its shipped model. It covers only the agents the Orchestrator dispatches, see Customizing models and Customizing KAIROS for the order the files are read in
  • Start gate: the Orchestrator shows the derived pipeline, the rule behind each agent, the size, the effort and auto-fix budget, the model lines in effect with the place each came from when there are any, and, when it ran this time, the impact assessment's ## Summary. One question: start, change the pipeline, re-run the impact assessment with your feedback, or stop. Start carries the recommendation even when the assessment escalated a risk, because an escalated question is one only you can answer and a re-run does not close it; Request changes is never the recommended option here. Change the pipeline is always offered, on a resumed run too: it is where you add or skip agents by clicking. It asks what to change (add an agent, skip an agent, or areas, effort and review loop in your own words), then lists the agents that can be added or skipped with the state each one has now, a few at a time because a prompt holds at most four options; the choice is stored as an override and the gate is shown again. Agents decided later (the review agents, QA plan, release plan, documentation) can be added or skipped here too, and the override then holds at the gate that decides them. Request changes appears only when the impact assessment ran in this session, because it re-runs that assessment. Pick it without typing anything and the Orchestrator asks what you want to change instead of waiting for text: answer the open questions now (each asked on its own, the answer written into ledger/open-questions.md), correct a measured fact, or go back to the gate. A free-text reply is a correction (effort medium, skip release-planner, add security-reviewer, only analysis, every wave, every gate), applied and stored in ledger/run.md as an override. Effort is stamped into every subagent's invocation prompt, so each agent enters Lean, Trimmed, or Full mode from a value you saw. simple_fix also sets the auto-fix budget to 1, widens the Risk Disposition Loop's auto-accept threshold to medium, and merges the plan and implementation into one step; medium sets the budget to 1; significant_rework asks for it
  • Questions and answers at the start gate: type a question at the gate (why XS?, does it touch the export module?, is the T3 test really needed?) and the Orchestrator answers it from the impact assessment, the ledger and the files the assessment cites, naming the file and line, then shows the gate again. It changes nothing by itself: if the answer shows that a measured fact is wrong, it says which correction would fix it and leaves the choice to you. A question is never re-run through the assessment and never filed as an open question, because the first regenerates the report without answering and the second leaves a question nobody owns. When you answer an open question from the Request changes menu, the Orchestrator re-runs the impact assessment whenever the answer changes what the change builds, touches or tests (a file, a test, a flow or a criterion added, removed or replaced) or names another size, effort, domain, test suite, contract change or change kind, and passes it the previous report and your answers. A re-run answers each of your points in one Feedback: line in the report's ## Effort, either accepted with what changed or not accepted with the line of code that shows otherwise; a question you already answered is applied and not asked again. An answer that picks what the assessment already assumed does not re-run it.
  • The issue is read first, before the folder is named, and the Orchestrator says what it found (## KAIROS Pipeline found: override block (...), no section, or a warning when the issue could not be read). A ## KAIROS Pipeline section is a decision you already made, so the run starts without asking: the Orchestrator prints the pipeline it is about to run and goes on. It still asks when something is not a decision you have seen (the issue could not be read, an unresolved escalation, an unknown fact that gates an agent, the architect skipped against its rule, an empty pipeline). An override block (Size:, Effort:, Epic:, Analysis:, Areas:, Auto-fix:, Skip:, Add:) is applied on top of the derivation; Analysis: names the folder of an earlier analysis run the issue was cut from, whose requirements, architecture and impact assessment every agent of this run is pointed to instead of redoing them (see Pipeline Templates). A checklist wins over it, and so does any pipeline that exists: the checked agents run, the impact assessment is started only when the checklist names it, and a phrase in your prompt that picks areas (analizziamo, finalizziamo) is ignored with one line. To change a saved pipeline, edit the issue's section; saying derive in your prompt drops a checklist in so many words
  • Areas and run intent: before the facts are gathered, one question, All areas (the default), Choose the pipeline myself or Decide each step (the next two items), limits the run to some of the four areas: analysis, development, review, delivery. Type area names in the question's free field to pick areas only, and add decide each step to the same reply (analysis, decide each step) to keep those areas and still be asked about each agent. An Areas: line in the issue answers it, and so does a phrase in the prompt that starts the run: analizziamo or analyse covers analysis, rendi ready covers analysis with the requirements and the design forced on, implementiamo covers all areas, finalizziamo or wrap up covers review. The start gate names the phrase that fired. A pipeline that already exists (the issue's section, a resumed run) always wins over a phrase. Inside the chosen areas the rules still derive each agent, and the start gate shows the areas that are not selected as one line. Run the same issue again later and the Orchestrator offers the remaining areas (see Areas)
  • Choosing the pipeline by hand: Choose the pipeline myself opens one dialog with a group per area, so you tick the agents yourself, the impact assessment among them. The pipeline is exactly your selection, no rule adds or drops an agent, and the effort is the assessment's when you ticked it, else medium. A run that has an issue saves it there as a checklist without asking, with every agent listed ticked or not, because a hand-picked pipeline is a decision no rule can rebuild. On Jira, where the plugin cannot write the description, the block goes in as a comment and is printed paste-ready. See Pipeline Templates
  • Deciding agent by agent: the same question has a third answer, Decide each step, for a run where you want the last word on every agent and not only on the areas. It covers all four areas and changes how the rules are used: at the start gate, at the implementation gate and at the review gate the Orchestrator still applies its rules, prints what they say, and then asks which agents of that point should run, with the rules' answer marked as the recommended one. You tick the agents that run. The start gate asks about the requirements and the design; the code review is asked at the implementation gate, with the test verification and the security review, because its rule depends on code being written. An agent you tick against the rules, or leave out against them, is stored as an Add: or Skip: override, so the issue write-back can offer to save it. The question is asked even at a gate that would otherwise continue on its own, because the question is the stop. The implementer is not part of it: which one runs still follows the design, and Add: <implementer> forces another. Write decide each step in the prompt that starts the run to answer the area question in advance, or reply it at the start gate to switch it on mid-way, and reply derive to go back to the rules. It is a second setting and not an area: next to a phrase of the table or to area names it keeps those areas and adds the questions (analizziamo e decidi tu ogni step asks about each agent of an analysis). It is never asked when the pipeline is already decided. An issue that carries a ## KAIROS Pipeline section (an override block or a checklist) starts without it, and a decide each step in the prompt does not override the section: the orchestrator says so in one line and goes on, so to decide agent by agent on that issue edit its section. Choosing All areas (reply full) is final too: no agent question is asked later, at any gate. Two agents belong to no area and run before the start gate: the bug triage, when your input reads as a bug report, and the impact assessment, which the rules need. In this mode the Orchestrator names them in one block before the first of them, and the triage gate always stops, so you read the triage before the assessment starts.
  • One issue, one folder. A folder is found by the issue reference, not by the slug (a reworded prompt for the same issue lands in the same folder), and a second folder is never offered for an issue, because it would split the ledger into two copies that drift apart. A large issue built slice by slice is one run per slice in that folder: on a finished run choose Start a new run, and the Orchestrator archives the finished run's reports under runs/run-<k>/ (with a snapshot of its tracking file and settings), keeps the ledger and the triage, rebuilds the impact assessment for the new slice and tells every agent where the earlier runs are. The tracking file stays one file, with a new run line in its log. A folder with only a context, impact or triage file is reused, not resumed. A run left in_progress or stopped resumes without questions and says where it restarts; the one thing it never skips is a gate the earlier session had open, which is shown again
  • If the invocation prompt already dictates an agent list, the Orchestrator shows it at the start gate as a proposal and applies it only if you say so
  • The Orchestrator saves the run's settings to ledger/run.md and creates _tracking.md, the one file it keeps open in your editor for the rest of the run (see Tracking File)
  • Size label (only when the run started from an issue and you confirmed the start gate): the Orchestrator sets a size:<XS|S|M|L|XL> label on the issue, replacing an earlier size: label, so the tracker can group an epic's issues by size. Skipped without a message where there is no tracker CLI or no labels, and when no size was measured (the impact assessment did not run). See Pipeline Templates
  • Issue write-back (only when the run started from an issue and you corrected something at the start gate): the Orchestrator offers to save the correction to the issue as an override block, never touching the rest of the description. On Jira, or with no tracker CLI, it prints a paste-ready block instead. A pipeline you picked by hand is saved without the question (see Choosing the pipeline by hand). See Pipeline Templates

Input: free-text feature request + optional issue reference + optional 00-context.mdOutput: 00b-impact.md, the agents decided so far, feature_folder path

Derived, then corrected

No menu: each agent runs because a rule fired on a fact, and the gate before it says which. Correct any decision at that gate; the correction holds for the rest of the run. Use Pipeline Templates to store corrections in your issue tracker.

Quick fix keeps the tests the project has

simple_fix routes to implementer-coder-agent, which is code-first: it writes the fix, then extends the tests of the modules it touched when the project has them, and test-verifier-agent runs whenever it wrote a test. Skipping tests needs a written reason in the plan.


Phase 1: Requirements Analysis (PM Agent) ​

  • Break down the feature into scope, constraints, and risks
  • Identify edge cases and integration points
  • Define acceptance criteria — trigger and observable outcome, verifiable by the developer in their own environment; the setup a heavier check needs is Phase 5b's, and the criterion still keeps its AC-n

Input: feature description + project contextOutput: a single Markdown file — frontmatter (status, counts) + body (scope, constraints, risks, success criteria) — see "Artifact Format" aboveSaved to: .kairos/<feature_folder>/01-requirements.md

HITL checkpoint

User reviews requirements, constraints and risks before any design work begins. Presented via AskUserQuestion, not a printed menu.

✅ Approve · ✏️ Request changes · ⏭️ Skip next · ⛔ Stop


Phase 2: System Design (Architect Agent) ​

  • Propose 3 design options, recommend one
  • Design database schema and API contracts
  • Define error handling and integration patterns
  • Behaviour Delta — only when the change alters what a user of an already-shipped flow can observe (N/A otherwise): for each affected flow, what the user sees before and after, including on any new rejection or limit, and every new limit recorded as a constraint with its unit named ("400 lock keys per request, about 200 rows at 2 keys per row"). Test Verifier and QA Plan read it as input. It exists because the late findings in real runs were all of this kind: a rejection the operator never saw, a cap answered in rows but enforced in keys

Input: 01-requirements.mdOutput: a single Markdown file — frontmatter (selected option, table/error-code counts) + design doc body (full data model, API contracts, tech choices) — see "Artifact Format" aboveSaved to: .kairos/<feature_folder>/02-architecture.md

HITL checkpoint

User reviews the selected design option and API contracts (in 02-architecture.md) before any code is written. Presented via AskUserQuestion, not a printed menu.

✅ Approve · ✏️ Request changes · ⏭️ Skip next · ⛔ Stop


Phase 3: Implementation ​

Right before the plan, the Orchestrator chooses the implementer from facts and prints the rule that chose it: no test suite or simple_fix → the code-first implementer-coder-agent; otherwise the architecture's test_first fact (yes → implementer-tdd-agent, no → the coder), and without an architecture a project with a test suite gets TDD. On the TDD path, Layered Mode is offered when two or more of backend/frontend/db are touched and the host is Claude Code.

Default: Implementer Agent ​

Works everywhere (Claude Code, API, local models). Recommended for all features.

This phase has two HITL checkpoints — a plan gate before any file is written, and a code gate after TDD is complete. Each checkpoint ends one Orchestrator invocation of the implementer and starts the next: the plan gate is not a pause inside a single run, it is the boundary between step 3a and step 3b.

Step 3a — Implementation Plan (no files written yet)

  • Analyse existing codebase patterns via grep
  • Output structured plan: files to create/modify, full test case list, TDD order, dependencies, risks
  • Write the plan to .kairos/<feature_folder>/03-implementation-plan.md and stop — no source file is touched

Step 3b — TDD Cycle (after plan approval)

  • Same implementer, re-invoked with the approved plan; PHASE 0 is skipped, not repeated
  • Write tests FIRST (RED phase)
  • Implement code to pass tests (GREEN phase)
  • Refactor and run the full suite once, coverage reported

Input: 02-architecture.md + project profileOutput: implementation plan → (approval) → code files + test files + coverage reportSaved to: .kairos/<feature_folder>/03-implementation-plan.md, then project paths + .kairos/<feature_folder>/03-implementation.md

One artifact per feature, not per pass

The implementer is re-invoked on the same implementation for three different reasons: a planned wave from a multi-wave plan, a review loop iteration driven by code-reviewer or test-verifier findings, and a fix pass or manual re-run after you answered a gate. All three append to the same 03-implementation.md: a ## Pass Log records why each pass ran, and ## Files Written is the union across all of them, each row naming the pass that last touched it. Loop iterations are additionally archived as 03-implementation-iter{N}.md, but those are a per-iteration trail — the base file stays the cumulative record.

This matters because three readers treat that table as everything the feature shipped: code-reviewer-agent picks what to review from it, release-planner-agent's Scope Coverage Check traces each in-scope item to it, and _tracking.md publishes it as Files Changed. A per-pass table made all three under-report with no error anywhere.

HITL checkpoint — Plan gate

User reviews the implementation plan (files, test cases, approach) before any code is written. Reject at zero cost.

The plan is a first-class artifact like every other phase output: written to disk unconditionally, opened in the editor (the one gate that still opens its artifact automatically, because it is the last one before source files change), and gated by the Orchestrator — never buried in the implementer's own transcript. Its Risks table goes through the same row-by-row Risk Disposition Loop as any other phase. Presented via AskUserQuestion, not a printed menu.

✅ Approve plan · ✏️ Revise plan · ⏭️ Skip next · ⛔ Stop

Waves continue on their own unless something needs you

A large plan is split into waves, and each wave ends with status: partial. The implementer sizes each wave by the output it will write, not by how many files it touches: the plan gives every file an estimated token count (new lines written times 12, only the added or changed lines for a file it modifies), and a wave holds at most 10,000 estimated tokens and 12 files. A plan of many small edits therefore needs fewer waves than before, and a plan of a few large files needs more. The Orchestrator still checks every wave the way it checks a gate: the artifact contract, the ledger, and the files the wave touched against the plan's file lists. It stops and asks you only when one of those checks turns something up: a new risk rated medium or above, a new constraint, a failing test, a file outside the plan, an Escalate, or a malformed artifact. Otherwise it writes one line to _tracking.md's log and starts the next wave. Setting wave_gates: every_wave in ledger/run.md, or saying so at the start gate, restores a gate after every wave. The last wave's gate follows the rule in Gates that continue on their own.

HITL checkpoint — Code gate

User reviews generated code and test coverage before the review phase. Presented via AskUserQuestion, not a printed menu.

✅ Approve · ✏️ Request changes · ⏭️ Skip next · ⛔ Stop

Layered Mode: Implementer Lead + layer agents (Claude Code only, optional) ​

Offered only when its rule holds: the TDD path, two or more of backend/frontend/db touched, and Claude Code as the host. The Orchestrator shows a short cost note and waits for confirmation before proceeding. (This mode was called Team Mode until v9.5.0; see Layered Mode setup for what changed.)

How it works, TDD across layers:

The same RED → GREEN → REFACTOR discipline as the single agent, split across the same two phases (3a plan, 3b execution), but the Orchestrator coordinates the work across specialists with ordinary subagent calls, one stage at a time:

  1. Step 3a, Lead analyzes the Architect output, scopes the layers in play and defines four binding contracts (API, database, test, pattern) before any layer agent starts. It writes 03-contracts.md and 03-implementation-plan.md, then stops. A contract that diverges from the Architect's output becomes a row in the plan's Risks table instead of a question the Lead cannot ask.
  2. HITL, Plan gate, Orchestrator-owned, the same gate as the single agent. The plan carries the layer scoping and the Test Contract's full test-case list, so approving it approves the test plan too.
  3. RED: the Orchestrator calls teammate-tests-agent alone. It reads the contracts from 03-contracts.md and writes the tests, which all fail: that is correct and expected.
  4. GREEN: the Orchestrator calls teammate-backend-agent, teammate-frontend-agent and teammate-database-agent in one message, one call each, only for the layers in scope. Each writes code to the contract and a report, 03-layer-<layer>.md.
  5. VERIFY: the Lead checks every layer against the contracts and runs the whole suite. This is the only stage that runs it, so parallel layers never share a build or a database. If something does not match, the Lead writes fix tasks to 03-verify.md, the Orchestrator calls only the layers named, and VERIFY runs again. A layer that misses the same contract field twice stops the run for your decision.
  6. REFACTOR: the implementation layers improve their code in parallel, with the tests staying green.
  7. CLOSE: the Lead re-runs the suite and coverage, updates the ledger and writes 03-implementation.md.

A review-loop or post-gate fix pass skips RED and REFACTOR: the Lead scopes the fix to the layers that own the files in question, those layers fix, and the Lead closes.

The Lead's old mid-run Test Plan Gate (between RED and GREEN) no longer exists: the 3a plan gate covers the same ground before any cost is incurred. Test quality itself is re-checked in Phase 5.

Input: 02-architecture.md + project profileOutput: contracts + implementation plan → (approval) → all layer files + contract compliance report + coverage reportSaved to: .kairos/<feature_folder>/03-contracts.md + 03-implementation-plan.md, then project paths + .kairos/<feature_folder>/03-layer-<layer>.md + 03-verify.md + 03-implementation.md

Layered Mode needs no setup

It does not use Claude Code's experimental Agent Teams and needs no flag. CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS is no longer read by KAIROS. The team/ agents ship with the plugin and are not mirrored to other tools, so use the single Implementer Agent anywhere but Claude Code.

ToolLayered Mode
Claude Code (plugin)✅
Cursor, VS Code Copilot, JetBrains, Codex CLI, OpenCode, Kimi Code❌ not offered

When is Layered Mode worth it?

Binding contracts reduce frontend/backend contract mismatches, and the stages cost more calls than one implementer: a lead call to plan, one to verify and one to close, plus a call per layer for each stage. The cost is not measured, so check _usage.md after your first runs. For the vast majority of features, the single agent is sufficient.


Review Wave (Phases 4, 4b and 5) ​

Code review, security review and test verification all read the same finished code, and none of them writes source. So once the code gate is approved, the Orchestrator starts every active reviewer at once, in parallel where the host supports it, one after another where it does not. Each still writes its own report (04-review.md, 04b-security-review.md, 05-test-verification.md); what changes is how you answer them.

  • One gate for the wave. You see the three ## Summary blocks together, the Risk Disposition Loop walks the rows of all three tables, and one decision closes the wave.

  • One fix pass. Every row you mark Mitigate now, across all three reports, plus any change you ask for, goes to the implementer as a single pass, followed by one recheck scoped to that fix. The recheck runs only the reviewers the fix calls for: Code Reviewer when it touched non-test code, Test Verifier when it touched tests or fixed a test-verification finding, Security Reviewer when it fixed a security finding or touched a file that review cited. Each skip is logged in _tracking.md, and a clean recheck continues without a gate. Older versions ran a fix pass and a recheck after each review phase.

  • One loop. If you gave the run an auto-fix budget, the Orchestrator retries on its own while code review or test verification reports a critical/high issue or an acceptance-criteria gap, then runs every reviewer one last time before the gate. Security findings never trigger an automatic retry; they wait for you. See Agentic Loop.

  • Who runs the tests. Inside a wave only Test Verifier executes the test suite; Code Reviewer keeps its static checks and lint, so the two never build into the same output at the same moment. Findings both reviewers raise on the same line are merged by the Orchestrator.

  • Who writes the ledger. Inside a wave none of the three reviewers writes constraints.md, decisions.md or open-questions.md. Each ends its own report with a ## Ledger Update block, and the Orchestrator applies the three blocks one after another once all have returned, allocating the new ids itself and keeping a row 🔴 open when two reviewers disagree about it. Two agents that read the same row and write it back in the same minute would otherwise overwrite each other. Parallelism costs nothing here: the slow work (reading code, running tests) stays parallel, and the write is a few seconds. Outside a wave a reviewer updates the ledger itself.

qa-plan-agent (5b) is not part of the wave. It runs after the wave's gate, on settled code, and can still lead to one more fix pass of its own, with the same recheck rule. QA plan, release planner and documentation do not run as a wave of their own either: the QA gate can end in a fix pass that changes the code the other two read, the release planner's final accounting has to see every row the others add, and documentation reads the deployment plan for its migration notes.


Phase 4: Code Review (Code Reviewer) ​

  • Check standards, naming, file structure
  • Verify security (no hardcoded secrets, input validation, auth checks)
  • Verify architecture and API contract compliance
  • Check performance (N+1 queries, memory leaks)

Input: generated code + test filesOutput: a single Markdown file — frontmatter (status, pass/fail checks, issue counts) + report body (full issues table with impact, file:line, description, fix, disposition)Saved to: .kairos/<feature_folder>/04-review.md

HITL checkpoint

Answered at the combined review gate, together with 4b and 5. NEEDS_FIXES issues you mark Mitigate now join the wave's single fix pass. Presented via AskUserQuestion, not a printed menu.

✅ Approve · ✏️ Request changes · ⏭️ Skip next · ⛔ Stop

Effort modes — Lean, Trimmed, Full

Every phase agent reads effort in the same priority order: the orchestrator's invocation prompt first (a human confirmed it at the Effort Check), then 00b-impact.md, then its own inference as a last resort.

Lean Mode (simple_fix) — here, Architecture Compliance and Performance collapse to a one-line N/A unless the diff actually adds an endpoint/schema/integration point or touches a loop/query/hot path; the dependency-changelog check only runs when a dependency version actually changed. Correctness, Security, Simplicity, and Standards always run in full — those are what actually catch bugs on a small diff.

Trimmed Mode (medium) — the Full process, minus the sections nothing downstream reads: Performance collapses to a one-line check unless the diff touches a loop, query, or documented hot path. Every other check runs in full.

Full Mode (significant_rework, or an unknown effort) — unchanged.


Phase 4b: Security Review — optional (Security Reviewer) ​

Adversarial pass — the agent asks "how do I break this" rather than checking compliance boxes. Only runs when explicitly selected. Read-only agent (model: opus).

  • Authorization and IDOR — including nested payload mutations (a PUT on parent A that can silently modify a child belonging to parent B)
  • Authentication on sensitive endpoints
  • Injection — SQL, command, template, NoSQL
  • Secret handling — hardcoded creds, secrets in logs or responses
  • Data over-exposure — full model serialization, unfiltered list endpoints
  • Input validation at the server boundary
  • Dependency risks — known CVEs, deprecated crypto
  • Contract enforcement — verifies that ownership constraints from 02-architecture.md are actually present in code; gaps are flagged regardless of direct exploitability

Input: implementation code + 02-architecture.mdOutput: a single Markdown file — frontmatter (status, finding counts) + report body (each finding's attack scenario, evidence, fix, and disposition; contract enforcement table)Saved to: .kairos/<feature_folder>/04b-security-review.md (written by the Orchestrator — the agent itself is read-only)

HITL checkpoint

Answered at the combined review gate. Findings you mark Mitigate now join the wave's single fix pass; none of them is ever retried automatically. Presented via AskUserQuestion, not a printed menu.

✅ Approve · ✏️ Request fixes · ⏭️ Skip next · ⛔ Stop

When to add the Security Reviewer

Select security-reviewer-agent whenever the feature touches: authentication or authorization, user-owned data, payment flows, or any write endpoint. KAIROS's own flagship example (PCI-DSS Stripe payments) is a clear case.


Phase 5: Test Verification (Test Verifier) ​

  • Verify test comprehensiveness (edge cases, error scenarios)
  • Report coverage (a threshold only when declared), flag redundant tests
  • Assess assertion quality

Input: test code + coverage reportOutput: a single Markdown file — frontmatter (status, execution/coverage summary) + report body (uncovered lines, AC mapping, issues table)Saved to: .kairos/<feature_folder>/05-test-verification.md

HITL checkpoint

Answered at the combined review gate. Gaps and issues you mark Mitigate now join the wave's single fix pass. Presented via AskUserQuestion, not a printed menu.

✅ Approve · ✏️ Request changes · ⏭️ Skip next · ⛔ Stop

Skips re-running tests on a clean first pass

implementer-tdd-agent already executes the test suite twice (RED and GREEN) and reports coverage in 03-implementation.md. On the first test-verifier invocation for a feature — no prior 05-test-verification.md, and GREEN shows a clean pass — Test Verifier reuses those results instead of re-running the suite. The static audit (comprehensiveness, assertion strength, determinism, hygiene, mocking, TDD reality check) always runs in full regardless; only the redundant command re-run is skipped. Any loop re-check, recheck after a fix pass, or standalone invocation always re-executes, at the rung Test Scope gives.


Test Scope ​

Until v9.7.1 every stop ran the whole suite: the implementer once, Test Verifier on every recheck, the Layered Mode lead at verify and again at close. On a project whose suite takes 25 minutes, a run with fix passes waited for it three to five times. Now each agent picks the cheapest run that can still catch what it is checking, in three rungs:

  1. Files: only the test files the change adds or touches.
  2. Related: those, plus the tests that exercise the changed production files. The agent uses the runner's own option (--findRelatedTests in Jest, related in Vitest, the matching test modules in pytest, the changed packages in Go) or the project's test-changed command, see Customizing.
  3. Full: the whole suite, with coverage.
AgentRuns the full suiteRuns less
Implementer, test-firstonce, in the last planned waveearlier waves: files. A fix pass or a loop iteration: related
Implementer, code-firstnever, unless a change to shared configuration forces it (Test Verifier owns the full run on this path)always related
Test Verifierits first run when no full run exists to reuse, and the review loop's final passevery other recheck: related, over the files the fix pass wrote
Layered Mode leadverify and close of the first passa fix round, a loop iteration or a post-gate fix pass: related

A run goes to the full suite whatever the rung when the change reaches something no test imports directly (a manifest or lockfile, build or test configuration, a shared helper, fixture or setup file, a migration), when the runner has no related selection and the tests cannot be matched by import or name, and when test-changed: off.

A related run measures only part of the code, so it never judges coverage. Test Verifier carries coverage_summary over from the last full run, writes scope: targeted in execution, and says in the report where the numbers came from. The loop's final pass runs the full suite and replaces them.

What this leaves open. After a fix pass outside a review loop, in a simple_fix (no Test Verifier) and when the code-first implementer wrote no test file (so Test Verifier does not run), the related tests are the last test run before you merge. Keep the whole suite in CI.

Writing tests that are cheap to run. Both implementers carry the rules in their test budget: assert at the lowest level that can see the outcome, create expensive setup once per file and not once per test, never wait on a real clock or network (fake the timer, fake the call), parameterize instead of copying a test, test one behaviour at one level, and keep end-to-end tests for what no lower level can see. Test Verifier flags a concrete violation (a real sleep, an application or database started in every test, the same behaviour asserted at three levels) as a medium issue under its Hygiene check.

Not measured: the rungs and the triggers come from reading where the suite ran in the agent files and from one report of a 25 minute run, and no run has used them yet. Read scope: targeted in the next 05-test-verification-recheck.md files, and look for a defect that reached the final pass and a related run missed.

Phase 5b: QA Plan (QA Plan Agent) — optional ​

  • Name the core: what the change fixes (the bug triage's root cause, or the requirement's outcome) and the one to three behaviours that mean it failed, so those cases come first
  • Build the coverage complement: what Test Verifier reported as uncovered, plus every AC-n with a gap, keeping only what a person can actually reach through the product. When Test Verifier did not run (every simple_fix), read the tests the implementer wrote and the existing tests of the changed files instead of assuming coverage either way: a criterion that an assertion the agent read covers is cited with its file:line and leaves the plan, one no test names stays
  • Keep a check for the tester only when it is manual for one of two reasons: no assertion can see the outcome (layout, focus order, the wording of a message on screen), or no developer environment can stage it (several applications, a configuration, two sessions on two machines, a role the developer lacks). A ledger row or decision that names such a check on a real device or setup counts too. Anything a unit, component or integration test could close is not a manual case: it is written as a risk row (automatable gap), and Mitigate now sends it through the fix pass to the implementer and the test verifier. "Not automated yet" is not "cannot be automated"
  • Write manual and exploratory test cases a person can execute without reading the code, each with the Setup it needs — applications, configuration, concurrent sessions, machines, roles — in product language: screens, actions, visible outcomes, no class names, files, database objects or pipeline IDs
  • Keep every case short, because testers read these as a procedure and the long ones were the complaint: at most 5 cases per issue (3 in a simple_fix), a Setup of one line, at most three steps of a few words each, a one-sentence expected result. No matrix of variants packed into one row: the same behaviour on several screens or modes is one case with at most three repeat with values, and a longer list means the variants share code the case already proves. The tester's part is meant to fit one page; a plan that cannot is scoped wrong, and the plan says so as a risk instead of growing
  • Say where each step happens and what each step produces. Setup opens by naming every surface the case touches once, with a short label and the product's own name for it (Phone: Android app · PC: web app in a desktop browser), and a case on more than one surface opens every step with that label, so nobody guesses between the app and the browser. The expected result has at most two parts, one per step where the tester looks, each opening with that step's number (after 3: …; after 4: …); something no step triggers or reads is a precondition, not an expected result. A developer's preparation happens before the first step, never between two steps. Regression retests and charters name their surface the same way
  • Never send the tester to the developer's tools: no browser dev tools, no scripts, no hand edits to the database, no hand-built requests. A case starts from a state the product can reach. When the only way to stage a precondition is technical, a developer prepares it and the case says so in its Setup; when no case can be written without it, the plan carries a risk row instead of a step for the tester
  • List the behaviour changes a tester will see and must not file as bugs
  • Answer any VERIFICATION constraint declared upstream — which case covers it, or a high risk row when none does; N/A when none was declared, which is the normal case
  • Select regression retests by grepping real callers of every changed symbol, and keep one only when no existing test exercises that caller: at most 3, each a one-line instruction, never a chain of actions
  • List test data and environment needs, each with the line of code that demands it, at most 4, with no run order (the case IDs carry the order)
  • Select the existing QA-n cases from the project-wide catalogue whose area this change touched, each with the changed file that puts it there
  • Append this run's reusable manual cases to .kairos/_qa-regression.md, retire the ones this change automated or removed
  • State UAT sign-off per AC-n for the gate, and carry pm-agent's Outcome Criterion through verbatim. The tester's part does not repeat that table: each case names the AC-n it checks
  • Say so when there is nothing to verify by hand. No manual case, no retest, no existing case and no charter makes the plan short (summary, core, complement, risks and sign-off) with delivery: none: nothing is asked, posted or written, and the Orchestrator prints one line. The gate still shows it, because a risk row may need a decision there
  • Recommend where the tester reads the plan, and let you choose when you approve it. Up to 3 checks (manual cases, regression retests and existing cases to re-run, counted together) and no epic: the recommendation is a comment on the issue. More than 3: a file. The tester's part is always written as one Markdown file, _qa-file.md, and a short comment, _qa-comment.md, carries the Core and a pointer line

Input: 05-test-verification.md (optional), 01-requirements.md, 03-implementation.md, 00c-bug-triage.md (optional)Output: a single Markdown file — frontmatter (status, coverage basis, case counts, regression-risk tallies) + the plan bodySaved to: .kairos/<feature_folder>/05b-qa-plan.md, plus _qa-file.md (the tester's part in full) and _qa-comment.md (the Core and a pointer, posted when the plan travels as a file)

HITL checkpoint

User reviews the plan before it goes to whoever will execute it. NEEDS_ATTENTION is not a loop trigger — nothing re-invokes an implementer from here; it means a regression risk or an unverifiable acceptance criterion needs a human decision first.

✅ Approve · ✏️ Request changes · ⏭️ Skip next · ⛔ Stop

Runs after the loop, and reaches the tester through the issue

Phase 5b runs only once the review loop has exited and the review gate has resolved — a QA plan written mid-loop describes code that is about to change again. It is also the one artifact whose reader sits outside the pipeline, so once you approve it the plan is delivered to the issue tracker when an issue reference was given. No jira/glab on the machine is fine: the Orchestrator prints a paste-ready comment instead of failing the phase. Nothing is posted or written to the repository before you approve the plan at its gate. That comment is the acceptance/QA split in practice: the issue's AC-n list stays developer-verifiable, and the setup a check really needs — two applications, a specific configuration, two sessions on two machines — travels with the plan instead of bloating the criteria. What the tester gets is an extract, not the report: core, cases (each naming the AC-n it checks), setup, expected behaviour changes, retests and test data, without the Summary, Coverage Complement, sign-off table and code evidence the gate reads and a tester cannot act on. Empty sections are left out, and the whole is meant to fit one page.

A plan with nothing to verify is not delivered. When the tester's part is empty because every outcome is asserted by a named test or no person can observe it, the plan says delivery: none, the Orchestrator skips the delivery question, posts no comment and writes no file, and prints QA plan: nothing to verify by hand. A change that still started the agent (a frontend change, or one with no test file) does not leave a comment on the issue with nothing in it to do.

You choose how the plan travels, when you approve it. Projects differ in where a QA person looks, so after you approve the plan the Orchestrator asks, every time and for a plan that has an issue and no epic, which way to deliver it. Comment on the issue: the whole plan is one comment, nothing is uploaded or written. File attached to the issue: offered on GitLab when glab is installed, the file is uploaded to the project and the comment carries the Core and the link; nothing enters the repository. File in the repository: written to the QA directory (the qa-dir: line of .kairos-cfg/config, or .kairos/.qa-dir when asked once per project, and only when this way is used) by documentation-agent, after you approve, and it lands in your working tree so it travels with the merge request; until that merge the link points at a file that is not on the default branch yet. The recommended option follows the size of the plan: a comment up to 3 checks, a file above that. No Jira CLI uploads files, so there the choice is a comment or the repository file. The upload is read from GitLab's documentation and has not been run against a real instance; when it fails the Orchestrator prints the path to attach by hand and a paste-ready comment instead of posting a pointer to nothing. Standalone, qa-plan-agent has no Orchestrator to ask: it follows its own recommendation, and for a file it leaves _qa-file.md in the feature folder and prints the path to copy it to.

An epic gets one cumulative plan. When the issue belongs to an epic (an Epic: line, or the tracker's own parent link), every issue of that epic writes into the same file, <qa-dir>/<epic>.md. Each run rewrites only its own ## <issue> section and its own row in the ## Issues table at the top, which lists every issue with its size; the other issues' sections are never touched. The comment goes on the epic, not on the child issue. Read across the epic's issues, that table is also the catalogue by size: the size: labels group them in the tracker, the table groups them in the plan.


Phase 6: Deployment Planning (Release Planner) ​

  • Define deployment steps (pre-checks → staging → canary 10% → full rollout)
  • Create rollback strategy with estimated time
  • Define monitoring metrics and alert thresholds

Input: verified code + architecture + identified risksOutput: a single Markdown file — frontmatter (rollback/monitoring summary) + runbook body (deployment steps, risk mitigation table, rollback checklist, monitoring)Saved to: .kairos/<feature_folder>/06-deployment-plan.md

HITL checkpoint

User approves the deployment runbook (06-deployment-plan.md). This is the final checkpoint of the numbered pipeline — approval closes this KAIROS run (Phases 1–6, or 1–6b if documentation-agent was also selected). It does not preclude running retrospective-agent afterward — a separate, standalone, non-orchestrated follow-up invoked directly by the user whenever they consider the feature done. Presented via AskUserQuestion, not a printed menu.

✅ Approve · ✏️ Request changes · ⛔ Stop


Phase 6b: Documentation (Documentation Agent) — optional ​

  • Read the project's existing documentation first (README, CHANGELOG format, docs directory) and match it
  • List the user-facing surfaces the change altered, from the architecture's contracts and what the implementer actually shipped
  • Draft the README, API reference, CHANGELOG entry and migration notes those surfaces need, as the exact text to be written; flag what it cannot write without inventing (a missing example, an undocumented error code) as a documentation gap
  • Once you approve the draft, write it into the project's documentation files

Input: 02-architecture.md, 03-implementation.md, 06-deployment-plan.md (optional), the project's existing docsOutput: 06b-documentation.md, then the documentation files it listsSaved to: .kairos/<feature_folder>/06b-documentation.md, then README, CHANGELOG and docs/** in the project

HITL checkpoint

The Orchestrator runs this phase in two calls, like Phase 3, because the agent that writes real files outside .kairos/ is a subagent and cannot ask you anything. The first call only drafts: documentation-agent writes 06b-documentation.md and touches nothing else. The gate on it is the Orchestrator's. The second call runs only after you approve: the Orchestrator calls the agent again to write the files listed in ## Docs Touched, exactly as the draft shows them, and the agent appends a ## Docs Written table to the report. A file whose anchor text changed since the draft is left alone and reported, and nothing outside .kairos/ is written before your approval. Resuming a run that stopped between the gate and the write shows the gate again.

✅ Approve · ✏️ Request changes · ⛔ Stop


Shared Ledger — Cross-Phase Project Memory ​

Each KAIROS run maintains three living files under .kairos/<feature_folder>/ledger/ that accumulate shared state across all phases, plus two files the Orchestrator alone keeps there:

FilePurposeSeeded byUpdated by
constraints.mdAll constraints with per-phase accountingPM Agent (or Context Extractor if run first)Every agent
decisions.mdArchitectural and implementation decisions logArchitect AgentAny agent; the Supersedes cell only by the Orchestrator
open-questions.mdCross-phase questions with answers, and deferred risksAny agent or human (via HITL gate)Any agent
run.mdThe run's settings: effort, active agents, auto-fix budget, wave gates, phase gates, whether a hand-picked pipeline is saved to the issue yet (manual_pipeline), and the agents dispatched but not yet returned (in_flight)Orchestrator, before Phase 1Orchestrator
loops.mdAuto-fix state while a retry is running, and the history of retries that did not convergeOrchestratorOrchestrator; the checker adds its convergence signal

run.md is what lets a pipeline resume in a later session with the same settings: the resumed run restores the effort, skips the agents that were never selected, and keeps the auto-fix budgets the human chose. loops.md keeps retry bookkeeping out of open-questions.md, so that file holds only what a person has to read.

run.md also records which agents were dispatched and have not returned. A report on disk never proves an agent finished: every agent writes its report before its ledger update and before it hands control back, so the file exists while the agent is still working. The Orchestrator therefore treats an agent as complete only when its call returns, and opens no gate and starts no other agent until then. The host delivers an agent's final report as a hand-back message a moment before the call's completion notice. The Orchestrator does not treat that message as the return, and it does not end its turn on it with text alone, because a notice that arrives after such a turn can fail to wake it. It does one bookkeeping step first, and a second one if no notice came with the first, and at the start of every turn it checks which notices it already holds. While it waits, its status line tells you what to do if nothing follows: reply continue. If the notice is there, the Orchestrator goes on to the gate. If it is not, or the notice says the agent stopped with background work of its own still running (a shell it left behind), and the agent's hand-back arrived, the agent has stopped writing and the host is only holding the call open: when its report has a final status and no test runner or build process is working in the worktree, the Orchestrator treats the call as returned, logs returned by hand-back and goes on without asking. In every other case it asks once whether the agent was stopped before it re-invokes anything, because the original may still be running. If a session ends first (a closed laptop, a stopped run), the next session finds the agent still marked in flight and re-invokes it, whatever report it left behind. The implementers, implementer-lead-agent and documentation-agent define a recovery mode; any other agent is re-run from the start with its first prompt and replaces its own report. A recovering implementer reads git status, the approved plan and the earlier 03-implementation.md, keeps the files that already match the plan, writes the ones that are missing and re-runs the tests before it reports.

Before v8.5.0 a third file, audit-log.md, kept one line per gate. That log now lives in _tracking.md (below); an existing audit-log.md is read, never written.

Feature folders written before v8.4.0 keep working. A folder with no run.md falls back to the effort stored in the audit log's header and asks once for anything else; loop sections found in open-questions.md are moved into loops.md the first time the Orchestrator touches them; a decisions.md table without a Supersedes column gains it on its next write.

How the ledger works ​

Forced accounting model — at the end of every phase, each agent must update the Status column of every existing constraint row before adding new ones. An unaddressed constraint stays 🔴 open and is visible to every downstream agent.

StatusMeaning
🔴 openNot yet addressed by any agent
✓ resolvedConstraint is satisfied — note how
⚠ deferredAcknowledged but deferred (tracked in risk)
♻ modifiedConstraint was changed — note new version
❌ droppedExplicitly removed — note justification

open-questions.md uses 🔴 open, ✓ answered, and ⚠ deferred. A risk the human chose to Defer at a gate is written ⚠ deferred, not 🔴 open: nobody will answer it, so it is left out of the open-question count every gate shows, and the release plan lists it as a risk knowingly taken. A deferred row written by an older version, still 🔴 open but marked deferred risk, is counted the same way.

An Escalate writes two rows that point at each other: the BLOCKING constraint names its question (BLOCKING — see Q7), and the question names the constraint. The two full re-walks (architect and release planner) close the constraint from the question's answer, so answering the question is enough.

Choosing Escalate no longer costs a round trip when you can answer now. The Orchestrator asks one follow-up in the same gate: up to two alternatives taken from the row's own Mitigation or Fix text, Keep it open and go on, Stop here, and a free field for your own answer. An alternative or your own words settles the row (Mitigate now, with your answer in its note, or Accept) and the run continues. Keep it open and go on files the question as before, for someone who can answer it, and the row keeps its Escalate, so the stop signals that read it (a gate that would have continued, a recheck) still fire. Stop here files it and stops the run, resumable at the open gate. A row that states a false premise offers only the last two. The gate's recommended option no longer flips to Request changes because a row was escalated: the recommendation follows the rows and your answer.

When a phase contradicts an earlier decision and the human Accepts that conflict at the gate, the Orchestrator records the change in decisions.md's Supersedes column. Later conflict scans skip the replaced decision instead of flagging it again. No phase agent writes that column: the agent being checked cannot switch off the check on itself.

Why this matters ​

Without the ledger, information can be silently dropped between phases: a SOC2 compliance constraint captured by the PM but not echoed into 02-architecture.md is invisible to the Implementer and Reviewer. The ledger eliminates this by making all cross-phase constraints and decisions explicit and persistent.

Constraint & Decision Conflict Scan — after every phase's own ledger update, the Orchestrator re-reads constraints.md and decisions.md and checks this phase's actual output against every row an earlier phase already resolved or recorded. A row's own Status cell only records what the acting agent claims happened — it never cross-checks itself against constraints or decisions from more than one phase back — so this is the only place that drift gets caught. A genuine contradiction becomes a high-impact row in the phase's own Risks/Issues table, resolved through the same HITL gate as everything else there.

At pipeline end, the Orchestrator counts 🔴 open items in open-questions.md and warns if any remain unresolved before shipping.

Layered Mode: only implementer-lead-agent reads and writes the ledger. The layer agents receive constraints through their binding contracts, not by direct ledger access.


Tracking File ​

The ledger is written for the agents. .kairos/<feature_folder>/_tracking.md is written for you: the Orchestrator creates it before Phase 1, opens it in your editor once, and rewrites it after every event, so the same tab stays current for the whole run. No agent writes it and no agent reads it: every value in it comes from the ledger and the phase reports, and nothing the pipeline does, a resume included, depends on its content. That is also why the rename from _recap.md breaks nothing.

SectionRewritten or appendedWhat it tells you
## Statusrewritten every eventcurrent phase, next step, what blocks the run, the questions and constraints still 🔴 open
## Issue Alignmentrewritten every eventevery AC-n as pending, covered, manual, later (it belongs to a slice this run does not build), gap, changed or dropped, and every scope change made along the way
## Logappended, never rewrittenone line per event: each gate and your answer (with the rows accepted for you and the rows you dispositioned off the recommendation), each wave or gate continued automatically, each fix pass, loop exit, resume and stop
## Phasesone section replaced per gatea few lines per phase, taken from that report's ## Summary

Every section that restates ledger rows (the status block and, once the run has finished, Open Questions, Open Constraints and Accepted Risks) is rewritten from one read of the ledger, so the file cannot disagree with itself: a question you answer or a constraint that resolves after the run has ended updates all of them, and is logged as an after run line.

A scope change is listed when a decision in ledger/decisions.md opens with Scope:. PM Agent, Architect Agent and the Orchestrator write that prefix when a decision widens or narrows what the issue asked, so the alignment section never has to guess.

Gates no longer open each report in the editor. The gate prints the report's path; reply open (or apri) and the Orchestrator opens it and shows the same gate again. The implementation plan is the one exception and still opens automatically.

At the end of the run the Orchestrator finalizes the file: Files Changed, the risks you chose to ship with, and the constraints still open. In Claude Code the model and token table is in a file of its own, _usage.md (see Usage). It then offers to delete the phase reports it now summarizes; the ledger and _tracking.md are never deleted. Last, it offers a sanitized copy of the summary inside the project, because .kairos/ may be gitignored. documentation-agent drafts it (step: summary), the Orchestrator no longer composes it: the agent reads each report's ## Summary, the ledger and the implementation's file list, never _tracking.md, redacts what should not leave .kairos/ (a security finding becomes its category and a takeaway that cannot be exploited, never an attack path), and writes .kairos/<feature_folder>/_project-summary.md. It ends the draft with a ## Target line: the path it proposes, taken from where the project already keeps its documentation, or docs/kairos-summaries/<feature_folder>.md when nothing points elsewhere. The copy has its own gate, and the Orchestrator owns it: it prints the path (reply open to read it) and asks Approve, Request changes or Stop, and a different path is a Request changes. Only after Approve does it call documentation-agent again to check that the target is a documentation file and write it. Nothing reaches the project before you approve. Folders from before v8.5.0 have a _recap.md written only at the end: a finished one is left as it is, and a resumed one gets a _tracking.md on first touch, with the old audit-log lines copied into its log.


Issue Tracker Integration ​

KAIROS supports Jira, GitLab Issues, and Bitbucket Issues. Provide an issue reference at the start of your request — each agent will post its validated output as a comment, building the full pipeline trace in the ticket history.

TrackerReference formatExample
JiraPROJ-42"Add Stripe payments — PROJ-42"
GitLab#42"Add Stripe payments — issue #42"
Bitbucket#42"Add Stripe payments — issue #42"
bash
# Jira (jira-cli):
jira issue comment add PROJ-42 "## PM Analysis\n\n..."
jira issue comment add PROJ-42 "## Architecture Design\n\n..."

# GitLab (glab):
glab issue note 42 --message "## PM Analysis\n\n..."

# Bitbucket (REST API):
curl -X POST "https://api.bitbucket.org/2.0/repositories/{workspace}/{repo}/issues/42/comments" \
  -u "${BITBUCKET_USER}:${BITBUCKET_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"content":{"raw":"## PM Analysis\n\n..."}}"

Error Handling ​

If any agent reports issues during its phase, the Orchestrator:

  1. Flags the problem to the user
  2. Asks whether to retry, skip, or abort the step
  3. Provides recommendations based on severity
  4. Continues to the next step when appropriate

Final Output ​

After all phases complete, the Orchestrator finalizes _tracking.md (see Tracking File) and presents a consolidated summary:

ANALYSIS (from PM Agent):
  - Scope, Constraints, Risks, Success Criteria

ARCHITECTURE (from Architect Agent):
  - Design Option Selected, Technology Choices
  - Integration Points, Database Changes, API Contracts

IMPLEMENTATION (from Implementer Agent):
  - Code Files Generated, Test Files Generated
  - Coverage Report, TDD Verification

QUALITY (from Code Reviewer):
  - Standards Compliance, Security Check
  - Performance Analysis, Issues Found (if any)

SECURITY (from Security Reviewer):
  - Findings ranked by exploitable severity
  - Attack scenarios
  - Contract enforcement status (ownership constraints verified)
  - IDOR / ownership gaps

TEST QUALITY (from Test Verifier):
  - Coverage Status, Test Quality Assessment
  - Missing Coverage (if any)

DEPLOYMENT (from Release Planner):
  - Deployment Steps, Risk Mitigation
  - Rollback Strategy, Monitoring Plan

Every KAIROS run produces

  • Production-ready code
  • Test suite sized to the acceptance criteria
  • Quality assurance report
  • Deployment plan with rollback procedure

Usage: model and tokens per agent ​

In Claude Code the Orchestrator keeps .kairos/<feature_folder>/_usage.md current: after every agent that returns it has scripts/usage.mjs rewrite the file, so a run stopped halfway still has its table, and nothing is added to the agents' own reports. /kairos:usage prints the same report on demand. It has one row per agent call and a total; for every agent the Orchestrator dispatched, the model that actually answered, the peak context (the largest prompt one request of that call carried) and the input, output, cache-write and cache-read tokens, with a flag on any agent whose model differs from the models lines in effect (see Customizing KAIROS) or its own model: line. Under that table a second one shows the orchestrator's own session, the one line the agent rows leave out: it is a session total, kept out of the total above, and it also covers other issues run in the same session and any conversation after the run, so read it as an upper bound.

The figures are measured by scripts/usage.mjs from the subagent transcripts Claude Code writes under ~/.claude/projects/, not reported by an agent about itself (a model asked its own name can be wrong). Each response is counted once, and the four token kinds stay apart because they are billed differently. Claude Code does not document the transcript format, so the script is best effort: when it finds nothing it understands, it says so and _usage.md is not written. /kairos:usage --feature <folder> reports every session of a feature; with no argument it reports the latest session, primary agent included. Every turn rereads its whole context, so tokens grow with turns times context and the peak is where to look first; Keeping token use down shows how to compact earlier and how to read the effect here. It needs Node 18 or later. OpenCode and Kimi Code have no such transcripts and print nothing.

KAIROS Framework v9.7.1 — Released under the AGPL-3.0 License.