Before executing project helpers, read runtime selection and operating rules.
GSD Path LoopOne invocation = one bounded pass. The bundled deterministic helper loop_run.py owns the gates — atomic claim, verify, finish, status — and its output is the only gate authority; do not reimplement that logic in model reasoning. The model owns what the helper cannot: reading the spec's prose, dispatching one fix worker, and feeding failures back. Fill new specs from the canonical LOOP.md template; a filled dogfood example lives at examples/ci-repair.LOOP.md.
Run every helper command from the repository root — relative paths in the
spec (log:, skip_when:, verify:) resolve against the working
directory. Use the bundled copy of the helper next to this file. When the
repository has a .project/, first run the bundled
scripts/discussion_records.py pending --repo <absolute-root>; when
.project/discuss/ANSWERS.md is absent, continue. A pending follow-up owned
by loop work blocks the pass with links to ANSWERS.md.
This skill never advances a gsd-path phase gate: it wraps bounded work, it does not route the pipeline.
Process
- Read the spec. Read the whole LOOP.md: machine fields and prose sections (Goal, Worker scope, Feedback route, Human gates, Stops, Output). The prose binds the worker brief below.
- Claim. Before verify or worker dispatch, run
python3 scripts/loop_run.py claim --spec <path>. The atomic result is the only admission decision. Onrun, retain the returnedclaimand admitted limits for this pass. Onskipwithrecovery.recoverable: false, another pass still owns its admitted lease: report that the loop is already active and stop without finishing or dispatching work. On anotherskipwithout an expired claim, report the reason and stop; no outcome exists to finish. Only when the helper returnsrecovery.recoverable: trueand the expiredclaim, close that exact prior claim as recovery before stopping:python3 scripts/loop_run.py recover --spec <path> --claim <returned claim>. The helper derives the elapsed time, completed verify cycles, and truthful result from the latest verify (pass,fail, orblockedwhen none completed). Never start work under a prior claim. - Baseline verify. Run
python3 scripts/loop_run.py verify --spec <path> --claim <retained claim>. The helper enforces the claim's one admitted wall-clock deadline across every verify command and every later verify invocation. Onpass, the goal is already green: recordpasswithfinishfor the retained claim and--iterations 0, report, and stop. A green baseline never dispatches a worker. - One bounded worker. On
fail, dispatch ONE fix worker (v1: single worker, no fan-out) with the exact failing commands and output tails from the helper, plus the spec's Worker scope. The worker fixes the smallest failed unit named by the Feedback route — not the whole goal. - Independent verify. The wrapper re-runs
verifywith the same--claim; worker claims are not evidence. Onfail, feed the new failing output back to the worker. The helper appends each verify result and refuses a verify beyondmax_iterationsfix → verify cycles. Stop when that limit or the admittedwall_clockis spent, whichever comes first. - Blocked. When the worker cannot proceed, or the only remaining fix
needs a Human gates action, stop with
BLOCKED: <reason>naming the gate — never perform the gated action to unblock. - Finish. Every admitted pass has exactly one terminal outcome. Append it
with
python3 scripts/loop_run.py finish --spec <path> --claim <retained claim> --result pass|fail|blocked|skipped --iterations <n> [--notes ...] [--rescue]. The helper checks<n>against its verify events and derives elapsed time from the claim. Use the exact same claim for baseline pass, successful repair, exhausted verification, human-gate block, or another terminal stop. Rerunning the identicalfinishis the only completion retry. - Report. Close per the AGENTS.md asking conventions: Outcome —
what changed, or why nothing ran; Review — a Markdown link to the
spec's log path (or the spec itself when no record was written), resolved
absolute path printed if the host cannot render links; Next — the one
question or action now required.
python3 scripts/loop_run.py status --spec <path>gives the aggregate counters when the user asks how the loop is trending;acceptance_ratedivides accepted by accepted plus rejected — blocked and skipped runs are not evaluations.wall_clock_per_accept_secondsdivides total all-run wall clock by accepts, so blocked and rejected runs raise it.
Rules
- Never commit, push, tag, or mutate git state — a loop pass leaves version control to the user.
- Never edit tests to match broken code. If the test is the bug, say so in the report and stop; weakening a verifier is a human-gate action.
- Never touch paths the spec's Worker scope declares read-only.
- Verify output tails are persisted to the spec's log; a verify command must never echo secrets or credentials.
- Human gates are never-auto: reaching one means
BLOCKED: <reason>, not a judgment call. - The helper's atomic
claimoutput decides whether a pass runs.checkis preview-only and never authorizes verify, worker dispatch, or mutation. - A pass that cannot honestly reach green stops per the spec's Stops and records the truth; silent partial success is the worst outcome.