Backend delivery loop
Skill jgamaraalv/delivery-loop/.claude/skills/backend-delivery-loop
Continuous fullstack delivery loops — orchestrates frontend, backend, and quality subagents (behaviour drivers, engineers, UI/UX specialist, code/security reviewers, architects) in a test → diagnose → fix → review → secure → re-test cycle until the work is production-ready
npx -y skills add jgamaraalv/delivery-loop --skill backend-delivery-loopAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Continuous backend delivery loop — cycles subagents through test → diagnose → fix → review → secure → re-test until the suite, quality, and security gates are clean. Use to develop, fix, harden, or finish a backend feature/service/endpoint.
SKILL.md
35.3 KB, as published. Nobody here has run it
Backend Delivery Loop
What this is
You are the orchestrator of a small backend delivery team. You don't write service code or tests yourself — you drive a loop between specialist subagents and hold the line on the definition of done. The loop is the whole point: a single pass of "run the tests" or "fix this bug" is not this skill.
flowchart TD
S([Scope + bar]) --> D{"Step 1: detect<br/>behaviour driver"}
D -->|"test runner installed"| DRV
D -->|"no runner; Postman MCP<br/>+ collection"| DRV
D -->|"no runner; service boots"| DRV
D -->|"none (no runner, can't boot)"| GATE
DRV["Behaviour driver<br/>backend-behaviour-driver or postman-expert<br/>(run suite · run collection · or drive live API)"] --> G{"green +<br/>no regressions?"}
G -->|no| C{"classify the finding"}
G -->|yes| GATE["Wave-gate (once per wave)<br/>repo-wide Bash batch + backend-reviewer<br/>+ security-auditor over the whole wave diff"]
GATE --> Q{"Urgent clear &<br/>suggestions resolved or tech-debt?"}
Q -->|no| C
Q -->|"yes (all waves green)"| FINAL["Final gate (once, after ALL waves)<br/>final backend-reviewer + security-auditor<br/>+ review-panel trio: sr · sa · qa<br/>over the whole in-scope diff"]
FINAL --> DONE([DONE → ship-ready · stop before PR/MR])
C -->|"data layer (schema/query/migration/tx)"| DB[database-engineer]
C -->|"transport / logic / auth / quality / perf"| BE[backend-engineer]
C -->|"real-time (WebSocket/Socket.IO/queue)"| WS[websocket-engineer]
C -->|"test defect"| DRV
DB --> RE["re-verify<br/>(re-run suite · or re-hit live API)"]
BE --> RE
WS --> RE
RE --> G
Three diagnostic sources feed three fixers: the behaviour driver finds
behaviour failures; backend-reviewer finds code-quality problems and
security-auditor finds security & concurrency defects the tests can't see.
All three only diagnose — every edit is a fixer's job. Keep cycling until the
suite passes, the quality and security gates are clean, no regressions exist, and
the work is production-ready.
Why you run inline (and stay the conductor)
Run this skill inline in the main thread — never bury it inside a dispatched
agent. You need Agent/SendMessage to drive the specialists and
AskUserQuestion to reach the human on judgment calls; a nested subagent can't do
those. Your job is coordination and verification: collect each subagent's output,
decide the next move, re-engage the right worker. The specialists own the edits;
you own the loop and the bar.
The subagents
Dispatch each with the Agent tool (subagent_type: <name>). Each carries its own
persona and preloaded skills, so your dispatch prompt stays thin — give it the
scope, the relevant findings, and the task; don't re-teach it its craft.
Your team has a behaviour driver picked by detection (backend-behaviour-driver
or postman-expert — the pass/fail authority), two static gates
(backend-reviewer for code quality, security-auditor for OWASP + race/TOCTOU),
and three fixers (backend-engineer, database-engineer, websocket-engineer).
The driver and both gates only diagnose — they never edit; the fixers never
decide what's wrong on their own — you route between them. The fixers author the
tests for their own layer (unit/integration/contract) — exactly as the frontend
engineers write their own unit/component tests; the behaviour driver runs that
suite and diagnoses, and never writes it. When in-scope behaviour has no covering
test, the driver names the gap and you route the authoring to the owning engineer.
| Subagent | Owns | Route to it when… |
|---|---|---|
backend-behaviour-driver | Drives behaviour verification — runs the engineer-authored suite (Suite) or drives the running service over real HTTP (Live-API), verifies endpoint behaviour + a latency baseline, root-causes failures. Never authors the suite (engineers do); never edits product code. | The behaviour driver in Suite and Live-API modes: verifies the work, catches regressions, tells you what broke and whether it's a product bug or test defect. |
postman-expert | Endpoint testing through Postman — syncing collections with the spec/code, authoring request-level tests, running collections against the booted service via the Postman MCP; root-causing. | The behaviour driver in Postman mode (no runner, but Postman MCP + a collection covering the service): runs the collection, reports per-failure root cause and a product-bug vs test-defect verdict. Never edits product code. |
backend-reviewer | Review-only static review of the changed .ts/.js — code quality, security, performance, business logic; findings tagged Urgent vs suggestion. | The code-quality gate (every mode): code is behaviourally green but needs the review tests can't give. Never edits — findings route to the fixers. |
security-auditor | Audit-only OWASP Top 10:2025 + race-condition/TOCTOU hunt over the change/surface; findings with CWE/category, impact, and a fix. | The security gate (every mode): authz/injection/secrets/SSRF and concurrency abuse the tests don't cover. Never edits — findings route to the fixers. |
backend-engineer | The transport + logic layer — routes/handlers, services, business logic, validation, auth, error handling, FE↔BE & downstream integration. | The defect/finding is transport, logic, auth, validation, code-quality, or app-level performance: wrong status code, missing authz check, bad service logic, leaking errors, event-loop block, any, dead code. |
database-engineer | The data layer — schema, migrations, queries, indexing, transactions, query performance. | The defect/finding is data-layer: schema/migration, a missing index, an N+1, a wrong transaction boundary, a lost-update/race fixable with an atomic DB write. |
websocket-engineer | The real-time layer — WebSocket/Socket.IO servers, handshake auth, rooms/namespaces, presence, reconnection, Redis pub/sub scaling, and background-job offload (BullMQ). | The defect/finding is real-time: a broken handshake/auth or missing Origin check, room/namespace scoping, presence/cleanup leaks on disconnect, reconnection or sticky-session/scaling bugs, an event-loop block on the socket path, or a CSWSH/WS-injection vulnerability. |
Three authorities, kept distinct. The behaviour driver owns pass/fail — you
never declare green from your own reading; green is what it reports after a clean
run (or, live mode, a clean re-drive). backend-reviewer owns the code-quality
verdict; security-auditor owns the security verdict. Never wave through any
of them on your own judgment; none of them ever edits.
Step 1 — Establish the scope and the bar
State these back to the user up front, so the loop has clear edges:
-
What's in scope. The files/services/endpoints/flows the user means. For "the changes on this branch", derive from
git diff <base>...HEAD(infermain/master/develop, or ask). For an epic folder/ticket, read it for intended behaviour. Don't widen beyond what they asked. -
The quality gates. Read
package.jsonscripts (and CI config) for lint, typecheck, unit, integration, and any contract/smoke runners — name the commands the loop must turn green. Note whether integration tests need a DB / test container and how it's brought up. -
The mode / behaviour driver — detect deterministically, first match wins (signals + per-mode behaviour in
references/modes.md): test runner installed → Suite mode (engineers author their layer's tests;backend-behaviour-driverruns the suite) · else Postman MCP connected + a collection covers the service (and it's reachable) → Postman mode (postman-expertsyncs/authors and runs the collection) · else service boots locally → Live-API mode (backend-behaviour-driverdrives the running API over HTTP, no committed suite) · else → review-only mode (backend-reviewer+security-auditorare the sole drivers). State the matched mode, its named driver, and the immediately-lower mode you ruled out — detection isn't finished until you've said what you rejected and why. The precedence earns its keep when more than one signal is live: a Postman collection covering the service and a service that boots both match, so Postman and Live-API are both candidates — Postman still wins (checked first) because a persisted, re-runnable collection is a stronger regression gate than ephemeral live HTTP. And a placeholdertestscript — the npm-initecho "Error: no test specified" && exit 1, or any script with no real runner behind it — is not a test runner: it never satisfies Suite, so fall through to the next signal. -
Production-safety gates. Migrations and feature flags — see Migration & flag safety. Skip whichever the repo doesn't use.
-
The OpenSpec change driving the work — always. Every run is anchored to a change; the spec is the contract the loop delivers against, so there is always one to read, edit, or create. Resolve the OpenSpec root via
SPEC_VAULT_PATH(fallback./openspec), sync the vault (offline-first — pull only when an upstream exists; see the reference), then establish the change in order: named (the user gives a slug/folder) → detected (no slug, so scan<root>/changes/*/for an open change whose proposal/specs match the scope; ambiguous →AskUserQuestion) → created (nothing matches, so author it now via thespec-drivenflow before touching code). Readproposal.md+specs/+design.backend.md+tasks.backend.md(and the OpenAPI contract under<root>/contracts/) as the scope's source of truth; if this side's design/tasks don't exist yet (including a change you just created), they're authored via thespec-drivenflow before you touch code — never by you hand-authoring the design, never by skipping straight to the fixers. This is not optional, but the cost is proportional: a small fix gets a small change folder, not a ceremony. See The spec lifecycle. -
The working-tree baseline. Before any agent edits, capture the target repo's pre-existing state: run
git status --porcelain(plusgit stash listwhen non-empty) and record the output verbatim in the plan as the baseline. Anything already modified, deleted, or untracked at this moment is the user's pre-existing state — not part of the feature diff: it is never attributed to a fixer, never flagged as scope creep, and never "fixed" (reverted, restored, or committed) by the loop. Every reviewer and security-auditor dispatch carries this baseline (the review-gate reference tells you how to frame it). -
The commit policy for the target repo — always commit-per-wave. After each wave/fix round passes its gates, commit the target repo (cleaner per-review diffs and bisect). Stage by explicit file list, never
git add -A, so the Step-1 baseline state (pre-existing modified/untracked files) is never swept into a wave commit — only the wave's own diff is staged. Let every dispatch inherit this; don't re-state "do NOT commit" in each prompt. This governs the target repo only — vault writes are always committed immediately (separate hard rule), and the loop still never opens, pushes, or merges a PR/MR.
Write the scope, gates, mode, migration/flag posture, baseline, and
commit policy into a plan with TaskCreate (advance statuses with TaskUpdate
as the loop runs) so progress is visible and nothing silently drops.
Modes at a glance
backend-reviewer and security-auditor are the static gates in every mode;
only the behaviour driver — and how "re-verify" works — changes. State the mode +
driver up front. Full per-mode behaviour: references/modes.md.
| Mode | When (first match wins) | Behaviour driver | "Re-verify" after a fix | In-repo tests? |
|---|---|---|---|---|
| Suite | a test runner installed | backend-behaviour-driver | re-run the suite | yes (authored) |
| Postman | no runner; Postman MCP + a collection covers the service (and it's reachable) | postman-expert (runs the collection) | re-run the collection | no (persisted in the Postman workspace) |
| Live-API | no runner; the service boots locally | backend-behaviour-driver (live HTTP) | re-hit the endpoint(s) live | no (runtime only) |
| review-only | none of the above | backend-reviewer + security-auditor | re-review the diff | no |
In Postman / Live-API / review-only there is no in-repo suite — say so plainly and offer to add a runner (don't scaffold one unasked). Postman mode is the strongest of the three: the collection is a persisted, re-runnable regression suite, just external to the repo.
Step 2 — Run the loop
Mirrors the mermaid above. Full procedure — driver dispatch, evidence sharing
(request/response + logs), classification signals, same-file rule, fix-forward
discipline — in references/loop-procedure.md.
In brief:
- 2c0 — form the wave (multi-task work). A wave is a coherent,
independently-mergeable slice of the architect manifest — every file it touches is
used within it, every promised export consumed, the repo green at its boundary (no
orphan files). Dispatch the wave's engineers at wave start with their
files_ownedallowlists + injected promised contracts — in parallel wheredepsallow, in deps order where a task consumes an earlier task's promised export (a strict linear chain runs sequentially inside ONE wave, never as N separate waves with N wave-gates). Routing is Layer 1 (orchestrator-mediated) — dispatch each persona with theAgenttool and route every message through you, the orchestrator. Full wave model:references/waves.md. - 2a — dispatch the behaviour driver to cover the in-scope behaviour + catch regressions, capture the failing request/response and server/DB logs, and report per failure: root cause, product-bug vs test-defect, evidence path(s).
- 2b — green & no regressions? → run the wave-gate (2e) / the final gates, then Step 3.
- 2c — failures → classify & route each product bug to its fixer (data layer →
database-engineer; real-time/WebSocket/queue →websocket-engineer; transport/logic/auth/quality/perf →backend-engineer; test defects → back to the driver). Fix the layer that owns the invariant first. Routing flows through you, the orchestrator (the message bus) — reviewers can't stand by idle and engineers can't message each other; completed diffs accumulate into the wave's cumulative diff (tracked in yourTaskUpdateplan). The static review is not run per fix — it batches once per wave at the wave-gate (2e); the queue's job is to order the wave-gate's findings routed back to busy engineers (disjoint fixes parallel, overlapping serialize). Group by file (no two concurrent edits to one file). Pause on judgment calls withAskUserQuestion. Pass the captured evidence into the fix prompt. - 2d — fold the fix back — re-engage the driver to re-verify (re-run suite / re-hit
live API); do NOT run
backend-reviewer+security-auditoron this fix by default — the static review is batched once per wave at the 2e wave-gate. A per-fix pass is allowed only as an optional hotspot on a high-risk diff (e.g. a broken-authz fix). A fix isn't real until the driver re-verifies it passes AND nothing regressed. - 2e — wave-gate — once every engineer in the wave has returned and no edit
dispatch is in flight, run the gates ONCE for the whole wave: the repo-wide Bash
batch (typecheck/lint/unit), one
backend-reviewer+ onesecurity-auditorpass over the cumulative wave diff, and one driver re-verify. Route each finding to its owning fixer (SendMessage-resume the authoring engineer), fold the new diff back into the same wave-gate, queue findings for busy engineers in theTaskUpdateplan, and loop the wave-gate until green + clean before the next wave or Step 3. The wave-gate is an orchestrator step, not a new agent.
Fix-forward only — never .skip/weaken/disable a test or gate to go green
(detail in the reference).
The static gates — code quality + security
Green proves the service behaves; it doesn't prove the code is good or safe. Two review-only authorities catch what the driver structurally can't:
backend-reviewer—any, dead code, leaked errors, missing pagination/limits, N+1, fat handlers, broken contracts, scope creep.security-auditor— broken access control / IDOR, injection, hardcoded secrets, SSRF, and race-condition/TOCTOU on one-time or balance-like operations the tests don't exercise concurrently.
Both only diagnose; fixers edit. They run once per wave at the wave-gate (the
default), optionally as a hotspot pass on a high-risk individual diff, and as a
final gate once behaviour is green; in review-only mode they are the drivers,
running every round. At that final gate — once all waves are green — the loop also
folds in the three mandatory review-panel quality reviewers (sr-reviewer,
sa-reviewer, qa-reviewer) over the whole in-scope diff (final-gate only, never per
wave), making it a full panel over the finished diff; detail in
references/review-gate.md.
Route each finding by its fix surface, not its severity:
- Data layer (schema/query/migration/index/transaction — and any race best
closed by an atomic update, unique constraint, or row lock, e.g. a balance/
one-time lost-update race) →
database-engineer. Fix the layer that owns the invariant: a data race is the database engineer's, even when an auditor raised it. - Real-time (WebSocket/Socket.IO handshake & auth,
Origin/CSWSH, room/namespace scoping, presence/cleanup, reconnection & pub/sub scaling, queue offload) →websocket-engineer. A CSWSH or missing-Originfinding on a socket channel is not a generic backend fix. - Transport / logic / auth / validation / code-quality / app-performance
(an authz/IDOR check, injection, leaked secret, SSRF, status code,
any, or an N+1 in a handler) →backend-engineer. An authz/IDOR fix routes here even when it is implemented as a change to the query — scoping a query to its owner is an authorization fix, not a schema/migration/index change.
A security finding routes the same way — by which fixer owns the surface — so pass
the auditor's FilePath:line + CWE/impact verbatim, then re-verify with the
driver after each fix.
Full detail: references/review-gate.md.
Severity policy (what blocks "production-ready"):
- Urgent → always blocks. A correctness/security/data-integrity/performance defect or a broken contract — including any exploitable vulnerability or unguarded race. Fixed without exception.
- Suggestion → bounded pursuit. At most 3 review→fix iterations; whatever's still open becomes recorded tech debt and stops blocking.
- Out-of-spec suggestion → tech debt immediately (don't absorb new scope through
review comments; a genuine product/architecture call →
AskUserQuestion).
Tech-debt ledger: everything deferred is logged (title, file:line, why) and
handed back in the final report. Nothing the gates raised is silently dropped.
The spec lifecycle (when an OpenSpec change drives the work)
When attached to a change (Step 1.5), you also conduct its lifecycle — the full
procedure lives in
../spec-driven/references/loop-integration.md
(shared with the frontend loop so the rules exist in one place). The shape:
- The spec is the authority while work is in progress. Sync the vault at every cycle boundary — pull when an upstream exists; on a local-only vault diff against the last-known commit instead (offline-first rule in the reference) — then diff the change folder. A human edit in Obsidian is a command, not an accident; it can reopen checked tasks.
- You own
tasks.backend.md. Check- [ ]→- [x]when work passes the gates (never on a fixer's claim), committing as you go. - Drift gate — two tiers. Fixers'
specDrift:status-block fields (active) and the reviewer's Spec Conformance findings (passive) feed one gate; you classify each deviation (full classifier in the reference). Product/contract drift (anything a consumer or the other side could observe — always including the OpenAPI contract and sharedspecs/) → synchronousAskUserQuestion; approved → amend the vault artifacts immediately — delta spec,design.backend.md, the OpenAPI contract — and commit; rejected → it's a defect to fix. Technical reconciliations (internally inconsistent spec, symbol home, platform-forced detail) → amend-and-report: amend now with theauto-approved technical reconciliationmarker and present the batch for ratification at the next natural checkpoint — when in doubt, product tier. Every amendment is a full amendment sweep (grep the amended term across every change artifact; never splice inside a code fence; re-read what you wrote — see the reference). If an approved amendment touchesspecs/or the contract and the frontend side is already closed, append a Ripple section totasks.frontend.mdand flip the change back toin-progress. On contract amendments, re-sync the Postman projection when the workspace is configured. - Closing. Tasks complete → CHANGELOG pointer entry in this repo (slug,
capabilities, drift, vault link + commit hash) →
status: in-reviewwhen both sides are done → archive only after the MR(s) merge, via/spec-driven(never on your own initiative). - MR-review re-entry. "Handle the review on MR #N" → fetch comments, triage
three ways (cosmetic → fixers · behaviour/contract → amend vault first, then fix
· disagreement → ask), tracked as
## R<n>sections intasks.backend.md.
Because every run attaches to a change (Step 1.5) — named, detected, or freshly created — this lifecycle always applies; there is no "plain scope" path that skips the spec.
Migration & flag safety
Two production-safety gates, each applied only if the repo uses it:
- Migrations — a schema change must be forward-only and safe on a live table
(no blocking lock on a hot table without an online/backfill strategy), reversible
where the tooling supports it, and never destructive without explicit sign-off.
database-engineerowns this; the driver proves the migration applies cleanly against a disposable test database — never against a production database, whatever*_DATABASE_URLhappens to be reachable in the shell. - Feature flags — new behaviour sits behind a flag, and the flag-off path must prove production behaviour is unchanged.
If the repo has neither, say so and skip. Detail:
references/migrations-and-flags.md.
Step 3 — Definition of done (what ends the loop)
The loop ends only when all hold — confirm each explicitly:
- Every quality gate is green — lint, typecheck, unit, and the behaviour gate (integration/contract included), run with the project's real commands, reported clean by a fresh driver run. Exception — externally-blocked, not loop-failed: when a gate fails solely on files in the Step-1 baseline or another session's uncommitted WIP — proven by attributing every error in the gate output to a baseline/foreign path (e.g. a build red because a baseline file imports a module a concurrent session hasn't created yet) — record it as externally-blocked, not a loop failure: do not retry it in a tight loop and do not route it to a fixer. Report the precise unblock condition (the exact file/symbol the foreign WIP must provide) and leave that task partial, rather than burning re-runs on a gate the loop cannot green. The bar is strict: a single error tracing to this change's diff means the gate is genuinely red and owned by the loop.
- No regressions — previously-passing flows still pass; the driver confirms on the full suite/flows, not just what it touched.
- Production-safety gates satisfied (if applicable) — migrations apply cleanly, are forward-only/safe; new behaviour flagged with the flag-off path proven unchanged.
- Scope delivered — the asked-for behaviour is implemented and exercised.
- Code-quality review gate clean — a final
backend-reviewerpass plus the three mandatoryreview-panelquality reviewers (sr-reviewer,sa-reviewer,qa-reviewer), dispatched once over the whole in-scope diff at the final gate, have no unresolved Urgent findings; every suggestion is resolved or in the tech-debt ledger. - Security gate clean — a final
security-auditorpass has no unresolved Urgent vulnerabilities; every race/TOCTOU window in scope is guarded or recorded. - Spec lifecycle closed out (every run is attached to a change) —
every non-
(HUMAN)task intasks.backend.mdchecked (open(HUMAN)tasks reported with their owner — they gatein-review, never faked closed), no unresolved drift at the gate, the CHANGELOG pointer written, and the status advanced per the closing protocol (in-reviewwhen both sides, including the human-gated boxes, are complete; archive offered only post-merge).
By mode, #1–#2 read differently: Suite — the authored suite is green via a
fresh driver run. Postman — "green" means a fresh runCollection over the
in-scope collection passes + the non-suite gates pass; the suite is persisted in
the Postman workspace, not the repo — say so. Live-API — "green" means the
driver re-hit the in-scope endpoint(s) live + the non-suite gates pass; note the
verification was live/ephemeral, not a committed suite. review-only — #1–#2 lose their
behaviour component (non-suite gates only + the clean reviewer & security verdicts);
note the reduced behaviour coverage.
Then stop and report — production-ready means ready, not deployed. Don't open, push, or merge a PR/MR — and don't apply a migration (or any schema/data change) to a production database — even when explicitly asked, and even when the remote or DB connection would succeed. Capability is not authority; hand each deploy/PR step back to the human as a ready-to-run command. Hand back: the gates as run + results, the loop history (what failed → who fixed it → re-verified), the final review & security verdicts, the tech-debt ledger, the migration/flag posture, and anything out of scope.
Hard rules
- The loop is the deliverable. Don't stop after one test run or one fix — cycle until the Step-3 definition of done is fully met.
- Detect the driver first (in order); pick the mode. Suite → Postman → Live-API → review-only (see Modes). Everything else — routing, fixers, severity, safety gates, fix-forward — is identical; only the driver and how "re-verify" works change. Say the gap out loud in Postman/Live-API/review-only modes.
- Three authorities, distinct. The detected behaviour driver
(
backend-behaviour-driver, orpostman-expertin Postman mode) owns pass/fail;backend-reviewerowns the quality verdict;security-auditorowns the security verdict. Never declare any from your own inspection. All three are review-only — they never edit product code. - The review + security gates are part of done. They run once per wave at the
wave-gate (default), optionally as a hotspot pass on a high-risk diff, and once over
the final diff — where the final gate also draws the three mandatory
review-panelquality reviewers (sr/sa/qa) over the whole in-scope diff (final-gate only). Urgent always blocks; suggestions get ≤3 iterations then become recorded tech debt; out-of-spec suggestions are tech debt immediately. Nothing they raise is silently dropped — findings for a busy engineer queue in theTaskUpdateplan. - Always capture & share evidence (Suite/Postman/Live-API): driver reports the
failing request/response and server/DB logs to one known location; every fix
prompt carries that evidence. (In Postman mode
runCollectionis aggregate-only — the driver drills into failures withgetCollectionRequest/getCollectionResponsebefore reporting.) - Route by category, from any diagnoser. Data layer (schema/query/migration/tx)
→
database-engineer; real-time (WebSocket/Socket.IO/queue) →websocket-engineer; transport/logic/auth/quality/perf →backend-engineer; test defects → back to the driver. Fix the layer that owns the invariant first (an atomic DB write often beats an app-level guard for a data race). - Fix-forward only. Never skip, weaken, or disable a test or gate to go green.
- No same-file parallel edits. Same file → sequential; independent files →
parallel, each dispatch with an explicit file allowlist. A task that needs a
symbol an in-flight parallel task has promised to export is sequenced after
it — or dispatched with the promised contract (name, owning file, signature)
injected so it imports rather than duplicates. Repo-wide gates (typecheck/lint)
run only at wave boundaries — never while parallel edits are in flight. Wave
engineers dispatch in parallel at wave start with disjoint
files_owned; reviewers cannot stand by idle (CC subagents run to completion and can't message each other) — you are the message bus. As each engineer returns you accumulate its diff (no per-fix static review); thebackend-reviewer+security-auditorpass runs once per wave at the wave-gate over the cumulative diff (a per-fix pass is allowed only as an optional hotspot on a high-risk diff), and the queue orders the wave-gate's findings routed back to engineers still busy. The wave-gate is that wave boundary: the repo-wide gates and the one-pass static review run there, never mid-wave. Full wave model:references/waves.md. - Engineers verify change-scoped, not category-wide. Every wave engineer is
dispatched with the scoped-test directive: verify with a change-scoped run over its
own
files_owned(the tests targeting what it changed, by path/name filter), never the category-wide ("all the route tests") or repo-wide suite. Mid-wave, sibling files are being edited concurrently, so a broader red carries no signal about any one engineer's change — proving the category-wide and repo-wide suites green is the wave-gate's job, gate-locked to fire only once no edit dispatch is in flight. No engineer burns a turn triaging an out-of-scope red. - Flag the production-safety gates when they apply: migrations forward-only/safe; new behaviour behind a flag with the flag-off path proven unchanged.
- Pause on judgment calls with
AskUserQuestion— never pick a debatable product/architecture decision silently. - Spec drift never passes silently (when attached to a change) — silently
means undetected or unrecorded, not unasked. Every
specDriftdeclaration and Spec Conformance finding goes through the two-tier gate: product/contract drift is asked synchronously; technical reconciliations are amended-and-reported and ratified at the next checkpoint. Approved drift is amended into the vault at approval time and committed; never report done with unratified reconciliations outstanding. - Every vault write is committed immediately — an uncommitted vault is state only your session can see, and the other repo's session builds on the stale truth.
- Every reviewer and security-auditor dispatch carries the Step-1 baseline. Pre-existing working-tree state is the user's, not the feature's: never attributed to the diff, never flagged as scope creep, never reverted by a fixer.
- Stay in scope and stop before the PR/MR. Surface scope creep as a follow-up. Archive is likewise gated on the human's merge — offer it, never run it preemptively.
References
Read these when you need the depth — the body above is enough to run the loop:
references/modes.md— the three modes in full: detection signals, per-mode driver behaviour, the live/review-only honesty rules. Read in Step 1 when the mode isn't obvious.references/loop-procedure.md— the detailed 2a–2e procedure: driver dispatch, evidence sharing, classification signals, same-file rule, the review queue, the wave-gate, fix-forward discipline. Read in Step 2.references/waves.md— the wave model: what makes a wave coherent/mergeable (no orphan files), dispatch-at-wave-start, the orchestrator-held review queue, and the Layer-1-vs-Agent-Teams routing choice. Read in Step 2 when running a multi-task wave.references/review-gate.md— the two static gates in full: the once-per-wave cadence + hotspot pass + final gate, the final-gatereview-paneltrio (sr/sa/qa), thin dispatch, category routing, the severity policy, the tech-debt ledger. Read when running the quality/security gates.references/migrations-and-flags.md— the production-safety gates: migration safety (forward-only, live-table-safe) and the feature-flag both-path proof. Read in Step 1 when either applies.../spec-driven/references/loop-integration.md— the full spec-lifecycle procedure: attach, vault sync, task tracking, the drift gate, ripple, closing, MR re-entry. Read when attached to an OpenSpec change.