agentleFS
jsobolewski1jsobolewski1/fondue/skills/spec/SKILL.md

spec

Skill6 starsChanged 29 days agoMITView on GitHub

Specification-driven multi-model software development protocol. Use whenever a spec is started, continued, planned, implemented or reviewed. Read fondue/specs/<spec>/current-state.txt first; it names the live stage. fondue/specs/archive/ is history, never current truth. Bugs live in fondue/bugs/ and run on hunt instead.

168 other projects use a version of this.

Adopted by

Most recently taken up by

Used with

Projects with it also use backprop, ios-clean and 10 more.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • JuliusBrusseeSkill

    backprop

    Bug → spec protocol. When a bug is found or a test fails, trace the cause, decide whether a new §V invariant would catch recurrence, append to §B. This is the one non-obvious thing SDD does that plan-then-execute doesn't. Triggers on test failure, bug report, post-mortem, or explicit user ask.

    Also in 4 projects that use this

  • Saqlain-811Skill

    ios-clean

    Remove the DebugBridge SPM package and all #if DEBUG wiring from an iOS app. (gstack)

    Also in 5 projects that use this

  • Saqlain-811Skill

    ios-fix

    Autonomous iOS bug fixer. (gstack)

    Also in 5 projects that use this

  • bastosSkill

    ios-design-review

    Review iOS app UI/UX design quality using Apple's design principles and the Liquid Glass-era design language from WWDC25/26. Use when asked for a design review, UX critique, visual design assessment, or evaluation of an app's interface quality, design intent, alignment with the new Apple design system, or usability. Triggers: "design review", "UX review", "visual design critique", "review the UI", "does this design work", "evaluate this interface", "design feedback", "Liquid Glass review".

    Also in 5 projects that use this

  • ShreyRaviSkill

    plan-tune

    Self-tuning question sensitivity + developer psychographic for gstack (v1: observational). Review which AskUserQuestion prompts fire across gstack skills, set per-question preferences (never-ask / always-ask / ask-only-for-one-way), inspect the dual-track profile (what you declared vs what your behavior suggests), and enable/disable question tuning. Conversational interface — no CLI syntax required.

    Also in 7 projects that use this

  • timurgaleevSkill

    document-generate

    Generate missing docs for a feature, module or project as tutorials, how-tos, reference and explanation.

    Also in 6 projects that use this

  • +2 more from Saqlain-811

The file

We split this skill into the rules it gives an agent

11 rules. 0 are common, 5 are distinctive, and 6 are very specific to this project.

  • 0

    Common

    Most of the 145 edited versions we read keep these.

  • 5

    Distinctive

    This author's own choices. Worth a look.

  • 6

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    read 00-brief.md, the knowledge base (engine: Knowledge base), and every earlier attempt's plan.md and reopen.md if the spec was reopened, …

    line 87
  2. Very specific:

    read 01-research.md if it exists, and do their own research if needed

    line 88
  3. Very specific:

    write the research results and their own intended approach, with the invariants they would state, into 02-reviewer-research.md

    line 89
  4. Distinctive:

    only then open the draft, and write the review

    line 90
  5. Very specific:

    Every audit topic gets new sessions for each of its roles, whatever Sessions: says: its author on Draft, its reviewer on the first Review.

    line 123
  6. Distinctive:

    by default it writes the documents itself: Every review has closed by then, so its neutrality is no longer at stake (engine: Roles every …

    line 153
  7. Very specific:

    Landed work: When the new state is implementation:01:Draft, or a reply closed a phase or an audit topic, it appends the line to landed.md.

    line 185
  8. Very specific:

    Commit points: When brief, pre-plan and plan end, when each phase and each audit topic ends, on a reopen after the move to attempts/, when …

    line 188
  9. Distinctive:

    When the User asks, the Arbiter reads anything (engine: Roles every process has), and in handover it reads whatever the request needs.

    line 218
  10. Distinctive:

    Tests Auditor: - after the last phase, finds the behaviours of the spec's code that can break with no test failing, and adds or fixes the …

    line 304
  11. Distinctive:

    Conventions Auditor: - after the Tests Auditor, brings the spec's code in line with the project's rules, making only changes that keep …

    line 305

“Common” is measured: kept by at least 6 in 10 of the 145 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

spec — from idea to merged code

A spec goes from the User's brief to merged code through fixed stages. Each AI session holds one role. Sessions take turns and share nothing but the files in the spec folder and fixed control messages.

This skill runs on the fondue engine. Read protocol/engine.md at the plugin root, ../../protocol/engine.md from this skill's directory, before anything below. The engine holds state, turns, replies, rulings, review, and commits. This skill fills in the engine's hooks: stages, roles, artifacts, transitions, the turn table, and what counts as a Blocker.

Glossary

The engine's glossary holds, with these additions:

  • Kind - specs: a spec's folder is fondue/specs/<spec>/.
  • Stage - one of brief, pre-plan, plan, implementation, audit, handover, then the engine's done or abandoned.
  • Phase - one numbered part of the implementation. NN is always two digits, from 01.
  • Role - the engine's User and Arbiter, and Architect, Architecture Reviewer, Coder, Code Reviewer, Tests Auditor, Conventions Auditor, Handover Writer.
  • Topic - pre-plan and plan, whose author is the Architect and whose reviewer is the Architecture Reviewer; phase-NN and audit-fixes, whose author is the Coder and whose reviewer is the Code Reviewer; audit-tests and audit-conventions, whose authors are the Tests Auditor and the Conventions Auditor respectively and whose reviewer is the Coder; and handover, whose author is the Handover Writer and whose reviewer is the Architecture Reviewer.
  • Attempt - one approach to the spec's goal, from brief to its end: pre-plan/, plan/, audit/ and review/. The live attempt sits at the spec root. A failed one is moved to attempts/NN/ (see Reopening).
  • Approved artifact - the signed brief, plan/plan.md, and each plan/phase-NN.md once plan has closed. Changing one is a User question (engine: User questions).
  • Invariant - a property the approach guarantees once the spec is done, under the conditions it states: the inputs, callers, loads and timings it holds under, and the failures of the components it depends on. The draft states them (see pre-plan/NN-draft.md), and the Architecture Reviewer attacks them.
  • Lens - one of the audit's two checks, tests or conventions. Each runs as its own topic, audit-tests or audit-conventions: a lens topic (see audit).
  • Audit topic - audit-tests, audit-conventions or audit-fixes. In a state, part is the word after audit-.
  • Audit finding - an entry of audit/findings.md: shaped like an engine finding, with an id, a title, a severity, a description with its anchor, and a proposed solution, but written outside any review and cited as audit/findings.md#<id>. Its severity follows the Blocker rules of audit-fixes, and the Code Reviewer judges it by them, whatever the entry records.

Folder layout

fondue/specs/
  <spec>/
    current-state.txt, roster.md, 99-user.md, stats.md     (engine)
    landed.md
    pre-plan/
      00-brief.md
      01-research.md
      02-reviewer-research.md
      03-draft.md, 04-draft.md, ...
    plan/
      plan.md
      research.md
      phase-01.md, phase-02.md, ...
    audit/
      findings.md              (only when an auditor found what it may not change)
    review/
      pre-plan/   00-request.md, 01-review.md, 02-answer.md, ...
      plan/       ...
      phase-01/   ...
      audit-tests/  audit-conventions/  audit-fixes/
      handover/   ...
    handover/
      00-request.md, 01-request.md, ...
    reopen.md                  (only while a reopen is pending)
    question.md                (engine: User questions)
    advice/                    (engine: Advisors)
    attempts/                  (only after a reopen)
      01/
        pre-plan/  plan/  audit/  review/  reopen.md
  archive/
    <spec>/

Stages

The spec starts as the engine's Starting a spec says, with first state brief. Its start question, after the roster, is Sessions: fresh, the default, or continue (see implementation and roster.md).

brief

User writes pre-plan/00-brief.md, the spec's starting document: alone, with the Arbiter in one of the ways the engine's Starting a spec offers, or with any other AI help they choose. The stage ends when the User signs the brief off. Whenever the Arbiter shows the User a draft of the brief, it asks for the sign-off or the changes (engine: Asking the User). The Arbiter commits and sets pre-plan:Draft.

Amending the brief. A ruling may change a signed brief later: its goal or its scope. Unlike the engine's amendment of an approved artifact, the brief is edited, because it is the User's own document. The User edits it, or the Arbiter does in the User's words, and a line under the title says Amended <date>: <what changed>; ruling in 99-user.md. The User signs off the change. The Arbiter commits the amendment, and the role whose turn is next applies the amended brief. When the change takes the frame away from the drafts written so far, the User may restart the attempt.

A Mode: line in a brief is ignored: every spec runs every stage. On continuing a spec whose brief has one, the Arbiter tells the User, who lets it run on or, until plan has closed, restarts the attempt (see Reopening).

pre-plan

Pre-plan settles how the goal is reached: the approach, the decisions that shape it, the invariants it guarantees, and the phases with the gate each must pass. The technical decisions inside each phase belong to plan.

Architect reads the knowledge base (engine: Knowledge base), researches what the approach rests on and what the code already has, records both in 01-research.md, writes the first draft 03-draft.md and opens review/pre-plan/ with 00-request.md.

Reshape before you add. Code that already does part of what the goal needs is reused, or reshaped until it fits, before anything new is built beside it. A draft that adds a parallel version of something the code has, or builds around code it could change, says why reshaping it is worse. Why: an author who treats the existing code as fixed builds workarounds and near-duplicates, and every later spec pays for both.

Why two planning stages: a frame the reviewer rejects throws away everything built on it. Approving the approach first means that only a draft is thrown away, never a set of detailed phase files. The evidence is in design-notes.md.

Architecture Reviewer's first turn runs in this order, and the order is the rule:

  1. read 00-brief.md, the knowledge base (engine: Knowledge base), and every earlier attempt's plan.md and reopen.md if the spec was reopened, and decide how they would implement it
  2. read 01-research.md if it exists, and do their own research if needed
  3. write the research results and their own intended approach, with the invariants they would state, into 02-reviewer-research.md
  4. only then open the draft, and write the review

Why: a reviewer who reads the draft first finds problems inside its frame and never questions the frame.

Every pre-plan review attacks the invariants. For each invariant the draft states, the reviewer looks for a concrete scenario under which the approach, or any decision the draft carries, technical ones included, breaks it: an input or a caller that is hostile or merely unusual, a load, a timing, a component that is slow or fails. Then they compare the draft's invariants with their own from 02-reviewer-research.md and with the brief. A scenario is written as its steps and what it ends in, and its claims about a mechanism follow the engine's Research rule. A scenario outside the conditions an invariant states does not break it. An invariant the draft leaves out is a finding when the brief names it, when the goal cannot be met without it, or when it keeps existing behaviour the change must not break; so is an invariant whose conditions leave out a case the brief or the goal needs. Any other guarantee the reviewer wants is a question for the User inside the finding (engine: User questions), because what the spec guarantees is part of what it delivers. Why: a review asked whether a design is right finds problems inside the design's own argument; a review asked to break a stated property looks where the argument is silent.

Rounds follow Review. Every accepted fix goes into a new draft file with the next free number. Draft files are never edited. The stage closes on verdict approved or closed, and the final draft is the subject that verdict names.

plan

Plan turns each phase of the approved approach into technical decisions and tasks. Architect copies the final draft to plan/plan.md with cp - never by re-typing it - researches what the technical decisions rest on into plan/research.md, writes plan/phase-NN.md for every phase, and opens review/plan/ naming the phase files. The Architecture Reviewer reviews the phase files against plan.md and the research, and checks with diff that plan.md is identical to the final draft. Answer turns edit phase files in place and name the files touched. The stage closes on verdict approved or closed.

Plan may not change the approach. A plan-stage RESULT that shows the approach cannot work leads to Reopening.

implementation

How long a Coder and a Code Reviewer live is the roster's Sessions:. With fresh, the default, every phase gets a new Coder and a new Code Reviewer: the Arbiter spawns each of them before its first turn and sends it no more turns once the phase closes. With continue, the pair spawned for the attempt's first phase takes every later phase too, and the Arbiter sends it each phase's turns by its handles. Why fresh is the default: a session kept into the next phase re-reads the context it carries on every call of that phase, and in the measured runs that cost more than a new session reading the plan and one phase file. continue is an experiment for specs with small phases, where it may cost less. design-notes.md has the arithmetic and the results so far.

Coder implements the phase under the engine's Code turns: commit, build green, every gate the phase file names reported. Before writing code, it reads the knowledge base (engine: Knowledge base) for what is already there. Code Reviewer checks that the change is correct, introduces no problems and keeps the project's rules on structure, such as layering, boundaries or dependencies, under the same section's limits. The rest of the project's rules, style included, are the audit's (see audit). The Code Reviewer reads the knowledge base too, for code the change rebuilds. Anything missing, such as a test or a case, is a finding.

The stage closes when the last phase closes.

audit

The audit reviews the spec's whole code, git diff <sha>..HEAD with <sha> the commit on the first line of landed.md, through two lenses, each its own topic, in this order: audit-tests, then audit-conventions. In both, the auditor is the author: it makes the changes itself, under the engine's Code turns (commit, build green), and a new Coder reviews them. Why the auditor writes the change: a finding of this kind comes with its fix already worked out (the mutant and the test that kills it, or the rule and the edit that meets it), and handing it on costs a Coder a turn to type it again. Why a Coder reviews: checking these changes takes running them. This skill overrides the engine's Code turns for the reviewer of a lens topic: it may run the build and the commands its turn names (see Turns), and before it replies it leaves the branch checked out at the commit it found, with a clean tree. Why after the last phase: a test written in one phase can be made vacuous by a defence a later phase adds, and only a review of the whole range sees both.

The Tests Auditor asks of every behaviour the spec's code adds or changes whether some test fails when it breaks. It mutates that code, with the project's mutation tool where it has one and otherwise by hand (a condition negated, a boundary moved, a call or a finally removed, a constant changed), runs the tests that cover it, and reverts. A mutation run is scoped to the diff: it mutates only the files or classes the audit's diff adds or changes, never the whole module around them, and runs only the tests that cover them. Why: a run over whole modules spends most of its time on code the spec never touched and on the slow tests that cover it. For each mutant that survives, it adds the test that kills it, or changes the test that should have. It confirms the kills with a targeted rerun, never a second full pass: only the files or classes that had survivors, against only the tests it added or changed, plus, for a test it changed, the files or classes that test covers. Why: an added test can only kill more mutants, so the rerun needs only the survivors and those a changed test may no longer kill. It changes test code only, and never a test a phase file fixes, such as an invariant's gate, because changing it departs from an approved artifact. It lists in its request each surviving mutant it judges equivalent, one that no test can tell apart from the code, with the reason. Every mutant that led to a change is in the request as a RESULT: the mutation, the command, survived before the change, killed after. Its tree holds no mutation when it commits.

The Conventions Auditor checks the spec's code, the Tests Auditor's tests included, against the project's rules: its written ones (agent instructions, coding standards, contributing guide) and the conventions the code around it follows. Each change cites its rule or the code it follows. Every change it makes keeps behaviour: the build stays green and no test changes what it expects. A name, a key or any other decision a phase file fixes is outside its scope, because changing it departs from an approved artifact. It never rewrites history: a breach in the commits themselves, such as a refactoring inside a behaviour commit or a commit subject line over the project's length limit, is named in its request and left as it is. Why: a rewrite changes the shas that landed.md and every review name.

Outside an auditor's scope. What an auditor finds and may not change, such as a bug in production code, a test expectation that a rule would change, or a decision a phase file fixes, it appends to audit/findings.md as an audit finding, changing nothing for it. Ids continue from the highest one in the file. An audit finding against a decision a phase file fixes is a User question, written in the engine's question shape (engine: User questions). A finding of its reviewer that it accepts and may not fix within its scope goes there too: its answer says #<id> accepted, moved to audit/findings.md#<new id>, and it reverts any change of its own the finding shows wrong.

audit-fixes. When audit/findings.md exists after both lens topics have ended, the topic audit-fixes runs like a phase, with the findings file in place of a phase file. A new Coder fixes each audit finding, challenges one it holds wrong, or declines a Nit, and its request lists every id as #<id> fixed in <commit>, #<id> challenged: <position> or #<id> declined (Nit). An audit finding that is a User question it asks with a QUESTION reply before it touches that decision. A new Code Reviewer reviews the fixes, the challenges and the declines against all of the project's rules, not only those on structure, because no lens runs after it. No mutation run checks the fixes; as on any phase, the Code Reviewer asks for the test each fix needs. Why the auditor may not fix these itself: a Tests Auditor that may change production code can change it to fit its test, and a Conventions Auditor that may change behaviour can change it without anyone asking for it.

Nothing to change. An auditor replies nothing to change when it committed nothing and has nothing to list in a request: no equivalent mutant, no commit breach. It then opens no review; whatever it appended to audit/findings.md is judged in audit-fixes. Otherwise it opens a review. Why: an equivalent mutant or a commit breach that nobody reviews is a claim nobody checks. A lens auditor or an audit-fixes Coder that opens a review without having committed names its request file as the subject, and its Build: reports a build at HEAD run on that turn.

Every audit topic gets new sessions for each of its roles, whatever Sessions: says: its author on Draft, its reviewer on the first Review. Why: under continue, the Coder and Code Reviewer at hand wrote and approved the range under review.

The stage closes when its last topic ends.

Reopening

Not a stage: the way out of plan, implementation or audit when the approved approach turns out not to work, and out of pre-plan, plan, implementation or audit when the User restarts the attempt. What the new attempt needs most is the previous plan and why it failed, so both are carried forward on disk, never through a message.

Not every broken decision needs a reopen. When the author and the reviewer agree that plan.md or a phase file must change and the change keeps the approach, it is an amendment: the author asks the User (engine: User questions), and the approved file stays as it is. A reopen starts a new attempt when the approach cannot work, or when the User rules a restart.

  1. Evidence. The role that hits it, whichever it is, writes reopen.md at the spec root and replies BLOCKED, naming it in the reply's sentence. The file holds the RESULT, the plan.md lines of every decision the RESULT breaks, and the state it was found in. A role that writes code leaves the tree at its last green commit. A BLOCKED with no reopen.md is an ordinary BLOCKED.
    • On the User's own ruling, with no RESULT, the User may restart the attempt in any state of pre-plan, plan, implementation or audit, e.g. when a ruling changes the brief under the drafts, or when the pair is anchored on a frame the User has given up. The Arbiter first waits for the reply of any turn in flight, appends its stats.md row (engine: On every reply, step 1), and neither advances the state nor sends a turn. It then writes reopen.md itself, in the User's words only: the ruling, the state, and the assumptions the User says the ruling removes.
  2. Ruling. The User reopens, abandons the spec (engine: abandoned), or rules the problem local and names who fixes it. Not every broken task breaks the approach. On a local ruling, the Arbiter moves the text of reopen.md into the ruling's Evidence: in 99-user.md and deletes the file. Why: a reopen.md at the root says a reopen is pending.
  3. The move. On a reopen, the Arbiter moves pre-plan/, plan/, audit/, review/ and reopen.md into the next attempts/NN/, sets the Handle cells of the Architect, the Architecture Reviewer, the Coder, the Code Reviewer and both auditors in roster.md back to -, commits fondue/specs/<spec>/ and sets brief. roster.md, 99-user.md, stats.md and landed.md stay at the root: they span attempts.
  4. The brief. The User writes a new pre-plan/00-brief.md. It may start from the previous one, and it says whether the goal has changed.
  5. The new pair. A fresh Architect and a fresh Architecture Reviewer, and later a fresh Coder and Code Reviewer for the new attempt's first phase, whatever Sessions: says. Why: the pair that designed and approved the failed frame is the pair most anchored to it, and a Coder or Code Reviewer kept from the failed attempt carries that frame in its context.
  6. What they read. Every attempt's plan/plan.md, if it has one, and its reopen.md: what was planned, and why it failed. The Architect also reads landed.md, for the Landed work section. The research files of earlier attempts are a source: a FACT carried forward is restated in the new research with its origin, and a RESULT about the mechanism that failed is re-run. Drafts, reviews and phase files of earlier attempts are never read. Why: they argue for the frame that failed, while plan.md states it and reopen.md states what broke it.

The new attempt then runs from brief like the first, with its phases numbered from 01 again. Its draft carries two more sections (see pre-plan/NN-draft.md).

handover

Handover first brings the project's documentation up to date with what the spec changed, then writes whatever further document the User asks for.

The update is the topic handover. It always runs, unless the project has neither a knowledge base (fondue/kb/index.md) nor a project skill (.claude/skills/*/SKILL.md): then the state goes straight to handover. A new Handover Writer, from its roster.md row, takes handover:Draft. <sha> is the commit on the first line of landed.md, where the spec's code begins. The Handover Writer:

  1. runs kb.py write --since <sha> (protocol/kb.md) when the knowledge base exists. Then it runs kb.py status --since <sha> until it reads clean, fixing a card by hand where a name is dead.
  2. checks against the code every project skill that covers what the spec changed: the skills kb.py touched <sha> lists, or, when kb.py finds no modules, the skills the spec's diff shows it touched. A section the spec made wrong or incomplete is rewritten in place to describe the code as it now is. A feature that no skill covers is named in review/handover/00-request.md, and whether to write a skill for it is the User's call, after the update.
  3. commits the documents on their own, never with a spec folder, and opens review/handover/. When fondue/kb/ is ignored, it stages no card, and the request's subject names the changed cards as files next to the range (protocol/kb.md: Commits). When nothing needed changing, it commits nothing, opens no review, and replies nothing to update.

A new Architecture Reviewer reviews it against plan.md and the code. Why a reviewer: these documents steer every later spec, and a card or skill that is confidently wrong sends the next Architect the wrong way. Why a new session: the one from pre-plan and plan carries a frame the code has since replaced. The topic closes on approved or closed, and the state becomes handover.

Further documents. User decides whether any further document is needed, e.g. a project-level skill. The Arbiter writes the User's request into the next handover/NN-request.md, and then:

  • by default it writes the documents itself. Every review has closed by then, so its neutrality is no longer at stake (engine: Roles every process has). And it is the one session that followed the whole spec: every ruling, every reopen, every scope change.
  • when the User names the roster's Handover Writer, it sends the request to the one that wrote the update, or spawns it from its roster.md row if the update did not run.
  • when the User names another model and effort, it spawns a Handover Writer with them (engine: Starting a role) for that request alone, and keeps its handle in its own context like an advisor's: the roster's Handle cell stays with the one that wrote the update.

Whoever writes a document commits it on its own, never with a spec folder. When the Arbiter writes it there is no turn and no reply: it adds a stats.md row with the Role Arbiter, the Result handover written, and - for Counts, Tokens and Time, and the state stays handover. On entering handover the Arbiter sends no turn: it asks the User for a further document or the close of the stage (engine: Asking the User), and again after each document. The stage closes when the User tells the Arbiter to close it. The Arbiter then takes the spec to the engine's done, and does any git work the User asks for, e.g. a merge or a push. It makes no remote write the User has not asked for.

State

current-state.txt is <stage>[:<NN>|:<part>][:<Step>]. NN appears in implementation only, and part in audit only: tests, conventions or fixes, for the topic audit-<part>. Step appears in pre-plan, plan, implementation and audit, and in handover while the update runs. Examples: brief, pre-plan:Review, plan:Answer, implementation:03:Draft, audit:tests:Review, handover:Review, handover, done, abandoned.

Transitions

The engine's rows hold. This skill adds:

statereplynext state
briefUser signs the brief offpre-plan:Draft
pre-plan:Review / pre-plan:AnswerDONE, approved / closedplan:Draft
plan:Review / plan:AnswerDONE, approved / closedimplementation:01:Draft
implementation:NN:Review / implementation:NN:AnswerDONE, approved / closedimplementation:<NN+1>:Draft; after the last phase, audit:tests:Draft
audit:tests:DraftDONE, nothing to changeaudit:conventions:Draft
audit:tests:Review / audit:tests:AnswerDONE, approved / closedaudit:conventions:Draft
audit:conventions:DraftDONE, nothing to changeaudit:fixes:Draft when audit/findings.md exists; otherwise handover:Draft (handover when the update is skipped, see handover)
audit:conventions:Review / audit:conventions:AnswerDONE, approved / closedaudit:fixes:Draft when audit/findings.md exists; otherwise handover:Draft (handover when the update is skipped, see handover)
audit:fixes:Review / audit:fixes:AnswerDONE, approved / closedhandover:Draft (handover when the update is skipped, see handover)
handover:DraftDONE, nothing to updatehandover
handover:Review / handover:AnswerDONE, approved / closedhandover
handoverDONEhandover (User asks for another document, or closes the stage: done)
plan:<Step>, implementation:NN:<Step>, audit:<part>:<Step>BLOCKED with reopen.md, User rules to reopenbrief (see Reopening)
pre-plan:<Step>, plan:<Step>, implementation:NN:<Step>, audit:<part>:<Step>User rules to restart the attemptbrief (see Reopening)

The last phase is the highest NN in plan/. Besides listing that folder, the Arbiter looks at the disk only to check whether audit/findings.md exists and, on the way to handover, whether the project has a knowledge base or a project skill (see handover).

What the Arbiter does on a transition

  • Landed work. When the new state is implementation:01:Draft, or a reply closed a phase or an audit topic, it appends the line to landed.md. A topic that ended on nothing to change gets none.
  • Fresh sessions. With Sessions: fresh, a new phase spawns a new Coder and a new Code Reviewer. With continue, only the attempt's first phase does, and later phases reach the same pair by its handles. A reopen spawns a new Architect and a new Architecture Reviewer, and the new attempt's first phase a new Coder and Code Reviewer. Each audit topic spawns new sessions for its roles: its auditor or Coder on Draft, its reviewer on the first Review. handover:Draft spawns a new Handover Writer, and the first handover:Review a new Architecture Reviewer.
  • The writer's tokens. handover:Draft and handover:Answer may run kb.py write, so their replies get the engine's KB writer row (engine: stats.md).
  • Commit points. When brief, pre-plan and plan end, when each phase and each audit topic ends, on a reopen after the move to attempts/, when the brief is amended, when the update closes, and when handover ends.

Who reads and writes what

R = reads, W = writes (and reads). A role reads nothing in the spec that this table does not give it.

artifactArbiterArchitectArch. ReviewerCoderCode ReviewerTests / Conventions AuditorHandover Writer
current-state.txt, roster.md, 99-user.mdWRRRRRR
stats.mdW
landed.mdWR, after a reopenR, first lineR, first line
pre-plan/00-brief.md (User writes)W the template and a draft the User asks for (engine: Starting a spec); R at sign-off; W an amendmentRR
pre-plan/01-research.mdWR
pre-plan/02-reviewer-research.mdRW
pre-plan/NN-draft.mdWR
plan/plan.mdWRRRRR
plan/research.mdWR
plan/phase-NN.mdlistsWRR, own phase; all in audit-fixes and when reviewing a lens topicR, own phase; all in audit-fixesR
review/pre-plan/, review/plan/W request, answersW reviews
review/phase-NN/, review/audit-fixes/W request, answersW reviews
review/audit-tests/, review/audit-conventions/W reviewsW request, answers, own lens topic
audit/findings.mdchecks it existsR, in audit-fixes and when reviewing a lens topicR, in audit-fixesW, appends
review/handover/W reviewsW request, answers
handover/NN-request.mdWR, when sent one
reopen.mdmoves; writes on a restart the User rulesWWWWW
question.mdmoves into a rulingWWWW
advice/W
attempts/NN/plan/plan.md, attempts/NN/reopen.mdmovesRR
attempts/NN/pre-plan/*research.md, attempts/NN/plan/research.mdR, as a sourceR, as a source
fondue/kb/ (project, engine: Knowledge base)RRRRRW

When the User asks, the Arbiter reads anything (engine: Roles every process has), and in handover it reads whatever the request needs. A Handover Writer sent a request reads it and what it names. The User reads and may write anything, including 99-user.md directly.

Artifacts

roster.md

As the engine says, with one more line under Skill:, **Sessions:** fresh | continue: whether a Coder and a Code Reviewer live for one phase or for every phase of an attempt (see implementation). The Arbiter asks the User for it with the rest of the roster; fresh is the default. The default roster runs every role at effort high, on Opus, except the Architect, which runs on Fable. The reasons for the default roster are in design-notes.md next to this skill. Only the User reads that file, when choosing a roster. The rows of the Tests Auditor, the Conventions Auditor and the Handover Writer are in every roster, because the audit and the update at handover always run. The audit's Coder and Code Reviewer come from the Coder and Code Reviewer rows. A continued spec whose roster lacks a row this skill requires, e.g. one whose roster has no auditor rows, gets the engine's roster step for that role (engine: Starting a spec) before the role's first turn: the Arbiter asks the User for its agent, model and effort.

landed.md

Owned by the Arbiter, and appended when the implementation of an attempt starts and whenever a phase or an audit topic closes; a topic that ended on nothing to change gets no line. It records where the code of each phase and each audit topic ends, so a reopened spec can tell which commits belong to which phase or topic. It works whether or not the spec folder is committed.

attempt-<NN> implementation starts at <sha>
attempt-<NN> phase-<NN> closed at <sha>
attempt-<NN> audit-<part> closed at <sha>

<sha> is git rev-parse HEAD when the line is written. It is a command the Arbiter runs, not an artifact it reads. attempt-<NN> is the number the live attempt would take in attempts/: one more than the highest there, or 01 if there is none.

pre-plan/00-brief.md

Written and signed off by the User; the Arbiter writes its template, and a draft when the User asks (engine: Starting a spec). It states what the spec must deliver, everything known that matters, and what is still open. A good brief leaves the Architect knowing the goal and what research the approach needs. Its open questions are the ones whose answer shapes the approach. A technical question may be listed too, marked (technical), and the draft passes it to the phase that answers it.

# <spec title>

## Goal
<what exists when the spec is done, and any property it must keep>

## Context
<everything known that matters: code areas, constraints, prior decisions>

## Open questions
<unknowns whose answer shapes the approach; a technical one, for plan, ends with `(technical)`>

pre-plan/01-research.md and 02-reviewer-research.md

Owned by Architect and Architecture Reviewer respectively. Each reads the other's. Every entry is under the engine's Research rule.

Pre-plan research covers what the approach, the phase split, a gate or an invariant rests on, e.g. whether a library provides a capability at all. Which API it offers, and how it is configured, is research for plan.

01-research.md opens with Existing code: for each capability the approach needs, what the code already has that does it or comes close, as a FACT anchored in the code, and whether the approach reuses it, reshapes it, or adds something new. A card or the index is how you find it, never the anchor. Each new says why the closest existing code is not reshaped instead. When nothing comes close, the entry says where you looked.

02-reviewer-research.md also holds the reviewer's own intended approach, written before they open the draft (see pre-plan): a few lines on how they would deliver the brief and the decisions they would take.

pre-plan/NN-draft.md

The high-level delivery plan, owned by the Architect, numbered from 03 up. It states the approach, the decisions that shape it, each with the alternatives it rejects, and the phases. What it reuses, reshapes and adds, from Existing code, are decisions that shape it. Each phase states what it delivers and the gate it must pass. The draft answers every open question of the brief that shapes the approach, and names the phase that will answer each of the others.

Invariants. The draft states the invariants the approach guarantees: every one the brief names, the ones the goal cannot be met without, and, for a change to existing behaviour, the ones that keep what it must not break, such as "requests that succeed today still succeed, below the configured limits". Each is one checkable sentence, such as "a refused request holds no worker thread, under any load", with the conditions it holds under, the decisions it rests on, and the gate that shows it holds. A gate that runs only the load or the inputs the goal describes shows the goal, not an invariant: an invariant about hostile callers or failing components needs a gate that brings them. When an invariant rests on a mechanism the spec does not control, the claim about it is a RESULT run against the part of the mechanism that decides it, not against a helper next to it. For example, which identity a request is charged to is decided where the request is authenticated, not in a parser of the credentials it carries. A spec that changes no behaviour, such as a rename, states that as its one invariant. Why: a property nobody wrote down cannot be attacked, so a review without invariants falls back on looking for anything wrong, which never ends.

What goes in the draft is decided by one test: would getting this wrong change the approach, the phase split, a gate or an invariant? If so, it belongs in the draft. So does a decision an invariant rests on, technical or not. If not, it is a technical decision and belongs to plan: a config value, a label name, a class, an API call, a task list. Why: every technical decision a draft carries can be wrong and costs a whole new draft to fix. It also crowds the review, so findings about the frame arrive rounds late.

A draft in a reopened spec carries two more sections:

  • Earlier attempts - for each one: its approach in a few lines (for an attempt with no plan.md, what its reopen.md names), why it ended, the assumptions its reopen.md shows broken or the User's ruling rules out, if any, and why this approach does not rest on them.
  • Landed work - every commit the spec has landed so far, by phase or audit topic and by attempt, including a phase or topic that never closed: keep, amend or revert, each with its reason. An amend or a revert is a phase of this plan like any other. The boundaries are in landed.md: the commits of a phase or topic are those after the line before it, up to its own sha. The commits after the last line belong to the phase or topic that never closed.

plan/research.md

Owned by the Architect, under the engine's Research rule. It covers the mechanisms that the technical decisions in the phase files rest on. The Architecture Reviewer reads it, and may re-run a RESULT as the anchor of a finding.

plan/plan.md

A verbatim copy of the final draft. It is never rewritten or summarised, because it carries that draft's approval. From here on it is the plan, and pre-plan is history.

plan/phase-NN.md

The technical design of one phase: what the Coder needs to build it without making a decision that is not theirs. It holds an introduction, the essential knowledge, the phase's technical decisions, and the tasks that complete the phase, each with how it is tested and its gate.

A technical decision is a choice that fixes a contract, is visible outside the phase, or would be expensive to reverse, e.g. a config key, a metric name and its labels, a histogram's buckets, a wire format, which library API to call. A decision that more than one phase depends on is made in the first of those phases and restated in the others. What the Coder's first build or grep finds - file and importer counts, test counts, paths, line numbers - stays out. Why: a count in a plan can be wrong and costs a round to find, while the Coder finds it in minutes.

Every research FACT the phase depends on, from pre-plan or plan research, is restated in the phase document, together with what it was verified against. A pointer to the research is not enough. Why: Coder and Code Reviewer never read the research, so a mechanism reaches implementation only if the Architect carries it forward.

A phase that adds to a module names the extension point it uses, verified in the code, when the module has one.

A task whose gate shows an invariant of plan.md names that invariant, so the Coder builds the gate to fail when it breaks.

A phase document may list skills for its phase on top of those in roster.md.

review/<topic>/

As the engine says. The subject of pre-plan is a draft file, of plan a list of phase files, of phase-NN, the audit topics and handover a commit range, and, when an audit topic's author committed nothing, its request file. phase-NN and the audit topics are code topics: their requests and answers carry Build: and Gates:. The request of a lens topic also carries the Since: field below, and the mutants and commit breaches the audit section asks for (see audit). handover changes documents only, so it runs no build. Its request carries two more fields, and its answers repeat KB::

- **Since:** <sha> - the spec's code is git diff <sha>..<the commit before the subject, or HEAD when the subject is a file>
- **KB:** kb.py status --since <sha> - clean        (only when the project has a knowledge base)

handover/NN-request.md

Written by the Arbiter in the User's own words: what to write, what it is for, and where the finished document belongs, usually in the project and not in the spec folder. A Handover Writer is sent nothing else.

Roles

The engine's User and Arbiter, and:

  • Architect - author of the research, drafts and plan. Lives across pre-plan and plan of one attempt.
  • Architecture Reviewer - reviews drafts and phase files for whether they meet the brief, answer its questions, state invariants that hold under every concrete scenario, within their stated conditions, that the reviewer can build, and are deliverable and testable. Lives across pre-plan and plan of one attempt. A new session reviews the update at handover.
  • Coder - implements the phases, reviews the auditors' changes, and fixes what audit/findings.md lists. Lives for one phase, or with Sessions: continue for every phase of one attempt. A new session takes each audit topic.
  • Code Reviewer - reviews the phases and audit-fixes. Lives as long as the Coder.
  • Tests Auditor - after the last phase, finds the behaviours of the spec's code that can break with no test failing, and adds or fixes the tests, changing test code only. Lives for its topic.
  • Conventions Auditor - after the Tests Auditor, brings the spec's code in line with the project's rules, making only changes that keep behaviour. Lives for its topic.
  • Handover Writer - brings the knowledge base and the project skills up to date with the spec, at handover. Lives for the rest of the spec.

The User also decides any further handover document, and the Arbiter writes it unless the User names a Handover Writer.

Turns

The engine's A turn, with this table:

staterolefolderthe turn
pre-plan:DraftArchitectpre-plan/read the knowledge base, research the approach and Existing code, write 03-draft.md, open review/pre-plan/; after a reopen, read every earlier attempt's plan.md and reopen.md first
pre-plan:ReviewArchitecture Reviewerreview/pre-plan/review the draft the newest file names, attacking each invariant (first turn: see pre-plan)
pre-plan:AnswerArchitectreview/pre-plan/answer every finding of the newest review; a new draft file if any fix was accepted
plan:DraftArchitectreview/pre-plan/copy the final draft the newest file names to plan.md, research the technical decisions, write the phase files, open review/plan/
plan:ReviewArchitecture Reviewerreview/plan/review the phase files the newest file names, against plan.md and plan/research.md, attacking each invariant through the technical decisions
plan:AnswerArchitectreview/plan/answer every finding of the newest review, editing phase files and plan/research.md in place
implementation:NN:DraftCoder (new for phase NN)plan/implement phase-NN.md, commit, build green, open review/phase-NN/
implementation:NN:ReviewCode Reviewer (new for phase NN)review/phase-NN/review the commit range the newest file names; never run the build or the test suite
implementation:NN:AnswerCoderreview/phase-NN/fix what was accepted, commit, build green, answer
audit:tests:DraftTests Auditor (new)plan/mutate the spec's code, add or fix the tests that kill the survivors, append what it may not change to audit/findings.md, commit, build green, open review/audit-tests/ (see audit)
audit:tests:ReviewCoder (new for the first review)review/audit-tests/review the subject the newest file names; may run the build, apply any mutation, write and run throwaway tests, and check out the commit before the subject, then leave the branch checked out at the commit it found, with a clean tree
audit:tests:AnswerTests Auditorreview/audit-tests/fix what was accepted or move it to audit/findings.md, commit, build green, answer
audit:conventions:DraftConventions Auditor (new)plan/bring the spec's code in line with the project's rules, append what it may not change to audit/findings.md, commit, build green, open review/audit-conventions/ (see audit)
audit:conventions:ReviewCoder (new for the first review)review/audit-conventions/review the subject the newest file names; may run the build and check out the commit before the subject, then leave the branch checked out at the commit it found, with a clean tree
audit:conventions:AnswerConventions Auditorreview/audit-conventions/fix what was accepted or move it to audit/findings.md, commit, build green, answer
audit:fixes:DraftCoder (new)audit/fix, challenge or decline each audit finding in findings.md, asking the User any that is a question, commit, build green, open review/audit-fixes/
audit:fixes:ReviewCode Reviewer (new for the first review)review/audit-fixes/review the subject the newest file names, against audit/findings.md; never run the build or the test suite
audit:fixes:AnswerCoderreview/audit-fixes/fix what was accepted, commit, build green, answer
handover:DraftHandover Writer (new)plan/update the knowledge base and the project skills, commit, open review/handover/ (see handover)
handover:ReviewArchitecture Reviewer (new for the first review)review/handover/review the commit range the newest file names, against plan.md and the code
handover:AnswerHandover Writerreview/handover/fix what was accepted, commit, answer
handoverthe Handover Writer the User names; otherwise the Arbiter writes it, with no turn (see handover)handover/write what the newest request asks, where it says

Reply keywords for turns with no verdict, beyond the engine's request opened: nothing to change, nothing to update and handover written.

What counts as a Blocker

  • On pre-plan, a finding is a Blocker only if it is wrong about the approach, the phase split, a gate or an invariant. A finding about a technical decision is a Nit at most, however wrong the decision: it belongs to plan, and the Architect carries it there. So is a technical decision the draft should not carry. The exception is a broken invariant: a concrete scenario, within the conditions an invariant states, under which the approach or any decision the draft carries breaks it is a Blocker, technical decisions included, because the decision is then wrong about the approach. It is answered by a decision that keeps the invariant: never by taking the decision out of the draft, and never by narrowing the invariant's conditions unless the User rules so. A decision an invariant rests on that the draft leaves to plan, or passes on as (technical), is a Blocker too. An invariant the draft does not state is a Blocker when the brief names it, when the goal cannot be met without it, or when it keeps existing behaviour the change must not break; so is an invariant whose conditions leave out a case the brief or the goal needs, and an invariant no gate can show. In a reopened spec, a draft that rests on an assumption an earlier reopen.md shows broken or rules out is a Blocker, and so is landed work the draft does not account for. A draft that adds what the code already has, or builds around code it could reshape, without saying why reshaping is worse, is wrong about the approach. So is an Existing code entry that misses code the reviewer can anchor.
  • On plan, a finding is a Blocker when a technical decision is wrong, breaks an invariant of plan.md under a concrete scenario within its stated conditions, rests on a mechanism with no RESULT, or is left for the Coder although it fixes a contract or crosses phases; when a task's gate cannot fail; or when the phase files do not deliver what plan.md says. A wrong detail the Coder's first build or grep would expose (a count, a path) is a Nit at most.
  • On phase-NN, a finding is a Blocker when the change is wrong, breaks an invariant of plan.md under a concrete scenario within its stated conditions, introduces a problem, breaks a project rule on structure, such as layering, boundaries or dependencies, or leaves out what the phase file asks for, a test or a case included. Code that rebuilds what the code already has, where the phase file does not ask for it, is a problem it introduces.
  • On audit-tests, a finding is a Blocker when a changed test pins behaviour that plan.md or the code's contract says is wrong; when a mutant the request gives as a RESULT does not survive without the change or is not killed with it; when the change touches anything but test code, or a test a phase file fixes; when a test the auditor adds can pass or fail by timing alone; when a mutant the auditor calls equivalent is killed by a test the reviewer shows as a RESULT; when a survivor the auditor sent to audit/findings.md can be killed by test code alone; or when the reviewer shows, as a RESULT, a surviving mutant of the spec's code that neither the request nor audit/findings.md accounts for. The reviewer need not search for surviving mutants.
  • On audit-conventions, a finding is a Blocker when a change alters behaviour, a test's expectation included; when it applies a rule the project does not have, or reads one wrongly; when it changes a decision a phase file fixes; or when it rewrites history.
  • On audit-fixes, a finding is a Blocker as on phase-NN, with audit/findings.md in place of the phase file and all of the project's rules in place of its rules on structure. A challenged or declined audit finding is a Blocker when it holds and is a Blocker by these rules, whatever severity its entry records; one that is a Nit by them never is.
  • On handover, a finding is a Blocker when a card or a skill says something the code contradicts; when something the spec changed is missing from them, in what a module offers, its extension points or its boundaries, or in what a skill describes; when kb.py status --since <sha> is not clean; or when a card explains why, or a skill carries history. The reviewer may run kb.py status, which spends no tokens.
  • The Architecture Reviewer judges against the brief, the research and the plan, and at handover against plan.md and the code. The Code Reviewer judges against plan.md, the phase file or audit/findings.md, the code and the project's rules on structure (all its rules in audit-fixes), and never opens pre-plan or plan/research.md. The Coder reviewing a lens topic judges against plan.md, the phase files, audit/findings.md, the code and the project's rules.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.