Skip to content

Loops · dev-team

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
npx skilldrop-cli install --loop build

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:

npx skilldrop-cli install --loop --pack dev-team

The loop alone, without its stage skills (each stage falls back to an inline version):

npx skilldrop-cli install --loop build --no-skills

In Claude Code, the dev-team plugin includes it:

/plugin install dev-team@skilldrop

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

#StageWhat it doesSkillsGate
1shape
generate
Turn a requirement or defect into one vertically-sliced unit of work with acceptance criteria.user-story-splitter, bug-triage, codebase-tour—
2implement
generate
Write the code and its tests against the acceptance criteria, challenging the result each round.feature-implement-loop—
3verify
verify
Judge the diff that now exists. The script decides; the panel explains.pre-merge-reviewG2 — a script decides
READY · NOT READY · BLOCKED
4decide
gate
A human merges. Design disagreements surfaced at G2 are adjudicated here, not argued in the diff.council-reviewG2.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

  1. 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, run codebase-tour on the slice first: where the change goes, the commands that test it, and the traps, each cited to a file.
  2. 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's cap governs returns from G2, not the inner skill's rounds.
  3. 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, or BLOCKED.
  4. Honour the gate. NOT READY returns to implement, up to cap (3) times. On the third return, stop looping and emit BLOCKED naming what did not converge. Never edit the gate to make it pass.
  5. Decide at G2.1. The merge is a human's. Escalate design disagreements surfaced at G2 to council-review rather than arguing them inside the diff; RECONSIDER and SPLIT both 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

Anti-patterns to avoid

Source

LOOP.md · loop.json on GitHub · Why loops