build
Take an agreed requirement to merged code through a capped generate-verify-gate loop, with a mechanical gate that decides and a human who owns the merge.
- Use it when
- Use when the user wants to implement a story, fix a triaged bug, or ask whether a change is safe to merge.
- Comes with
- The dev-team pack
- Where you decide
- Verify (G2): a script decides
- Decide (G2.1): you decide
- Size
- 4 stages · 2 gates · up to 3 revision rounds
Installs the loop as an invokable skill, plus every skill its stages run.
Other ways to install
Every loop in its pack, with their skills:
The loop alone, without its stage skills (each stage falls back to an inline version):
In Claude Code, the dev-team plugin includes it:
The loop
%%{init: {'theme':'base','themeVariables':{'fontFamily':'Segoe UI, Helvetica, Arial','fontSize':'15px','lineColor':'#9AA5B1'},'flowchart':{'curve':'basis','rankSpacing':70,'nodeSpacing':50,'padding':16}}}%%
flowchart LR
classDef gen fill:#E8F0FE,stroke:#4C7DF0,stroke-width:1.5px,color:#1A3A8F;
classDef review fill:#FDEAEA,stroke:#E05B5B,stroke-width:1.5px,color:#8A1F1F;
classDef gate fill:#FBE3A2,stroke:#D9971E,stroke-width:2px,color:#6B4500,font-weight:bold;
classDef ship fill:#E6F7EC,stroke:#34A853,stroke-width:2px,color:#0F6B33,font-weight:bold;
shape["shape<br/><small>user-story-splitter +2</small>"]:::gen
implement["implement<br/><small>feature-implement-loop</small>"]:::gen
verify["verify<br/><small>pre-merge-review</small>"]:::review
decide["decide<br/><small>council-review</small>"]:::gate
G2{"G2 · mechanical"}:::gate
G2_1{"G2.1 · human"}:::gate
DONE(["complete"]):::ship
shape --> implement
implement --> verify
verify --> G2
G2 == "READY" ==> decide
decide --> G2_1
G2_1 == "PROCEED" ==> DONE
G2 -- "NOT READY (max 3)" --> implement
G2_1 -- "REVISE (max 3)" --> shape
Stages
| # | Stage | What it does | Skills | Gate |
|---|---|---|---|---|
| 1 | shape generate | Turn a requirement or defect into one vertically-sliced unit of work with acceptance criteria. | user-story-splitter, bug-triage, codebase-tour | — |
| 2 | implement generate | Write the code and its tests against the acceptance criteria, challenging the result each round. | feature-implement-loop | — |
| 3 | verify verify | Judge the diff that now exists. The script decides; the panel explains. | pre-merge-review | G2 — a script decides READY · NOT READY · BLOCKED |
| 4 | decide gate | A human merges. Design disagreements surfaced at G2 are adjudicated here, not argued in the diff. | council-review | G2.1 — you decide PROCEED · PROCEED WITH CONDITIONS · REVISE · RECONSIDER · SPLIT · BLOCKED |
The repo-scope loop: a requirement enters, merged code leaves, and nothing crosses a stage boundary without passing that stage's gate. This loop sequences skills — it never contains one. Every skill named below stays independently installable and runnable on its own.
How to run this loop
- Establish the unit of work. New capability →
user-story-splitter. Reported defect →bug-triage. The stage is done when there is one vertical slice with acceptance criteria a test can assert. Vague criteria are the single largest cause of a wasted round 3. In a repository nobody on the change knows yet, runcodebase-touron the slice first: where the change goes, the commands that test it, and the traps, each cited to a file. - Implement. Hand the slice to
feature-implement-loop, which runs its own capped generate-challenge-gate cycle internally. Do not re-implement its rounds here — this loop'scapgoverns returns from G2, not the inner skill's rounds. - Verify at G2. Run
pre-merge-review. Its script decides and its panel explains:python3 packs/dev-team/skills/pre-merge-review/scripts/gate.py. The exit code is the verdict —READY,NOT READY, orBLOCKED. - Honour the gate.
NOT READYreturns toimplement, up tocap(3) times. On the third return, stop looping and emitBLOCKEDnaming what did not converge. Never edit the gate to make it pass. - Decide at G2.1. The merge is a human's. Escalate design disagreements surfaced at G2 to
council-reviewrather than arguing them inside the diff;RECONSIDERandSPLITboth leave this loop rather than revising within it.
Verdicts
Defined in contracts/terminals.json. G2 emits READY / NOT READY / BLOCKED. G2.1 emits the council vocabulary. A revise-class verdict returns to the stage named in revise_to; a redirect-class verdict leaves the loop.
When a stage's skill is not installed
Skills install à la carte, so a stage may name a skill the target environment does not have. Name the missing skill and skilldrop as its source, do the minimal inline version of that stage, and record that the stage ran degraded. A missing skill is never a reason to skip a gate — the gate is the loop's whole value.
Run log (opt-in)
Only when the environment variable SKILLDROP_LOOP_LOG is set to a file path: after each gate's verdict, append one JSON line to that file. Nothing else is recorded, and nothing is sent anywhere. When the variable isn't set, or you can't read it, skip this section.
printf '%s\n' '{"ts":"2026-10-01T14:03:00Z","loop":"build","stage":"verify","gate":"G2","verdict":"READY","round":1}' >> "$SKILLDROP_LOOP_LOG"
Fields: ts (UTC), loop, stage, gate (null for a stage without one), verdict (the gate's exact word), and round (1 for the first attempt, counting returns under the cap). skilldrop loop-stats summarises the file: which gates pass first time, which loop back, and which end in BLOCKED.
Quality bar
- The gate decides, not the agent. G2's verdict is
gate.py's exit code. An agent that reasons its way past a red gate has broken the loop, not passed it. - The cap is honoured. Three returns to
implement, thenBLOCKEDwith what did not converge. A fourth round is a defect in this loop, not diligence. - Every stage leaves evidence. Each stage names its skill, its verdict, and its round number, so the run is auditable after the fact rather than asserted.
- Acceptance criteria exist before
implementstarts. A slice whose criteria a test cannot assert is not shaped; return it toshape.
Anti-patterns to avoid
- ❌ Calling a skill from inside a skill to "continue the loop." The loop sequences; skills do not chain. This is what keeps every skill portable to Cursor, Kiro, and Aider.
- ❌ Editing
gate.py, its config, or a test to turn G2 green. That converts a mechanical gate into a decorative one. - ❌ Treating
PROCEED WITH CONDITIONSasPROCEED. The conditions travel with the artifact; dropping them is how conditional approvals become unconditional ones. - ❌ Running
decidefor every change. G2.1 exists for escalated disagreement and the merge itself, not as a ceremony on top of a green gate. - ❌ Starting at
implementbecause the story "is obvious." Unshaped work is what produces a diff nobody can review against anything.