Speckit.Run
Run a contiguous speckit pipeline sequence with BLOCKING checkpoints at every gate
---
description: Run a contiguous speckit pipeline sequence with BLOCKING checkpoints at every gate
---
## Input
`$ARGUMENTS` — parse the following flags:
- `--target <seq>` **(required)** — pipeline subsequence, e.g. `specify→plan→tasks`. Reordering rejected.
- `--checkpoints <list>` *(optional)* — comma-separated non-code gate names to BLOCK. Code-action gates (`implement`, `codereview`, `audit`) always BLOCK regardless.
- `--force` — bypass the spec-exists / no-log guard (FR-023).
- `--break-lock` — surface and clear a stale lock from a prior session.
---
## Initialization
Helper prefix: `.specify/scripts/bash/`. Invoke each helper from the repo root.
1. Run `check-prerequisites.sh --json`. Parse `FEATURE_DIR` (absolute path) from output.
2. Run `run-target.sh validate "$TARGET"`. On exit ≠ 0: print the validation error, stop.
3. If `--break-lock`:
- Run `run-lock.sh break "$FEATURE_DIR"`. Print the prior lock's `session_id` and `created_at`.
- Ask: "Confirm prior session is dead and lock can be cleared? (yes/no)." On "no": stop.
4. FR-023 guard (skip if `--force`): if `$FEATURE_DIR/spec.md` exists and `$FEATURE_DIR/decisions-log.md` absent — halt with: "spec.md exists but no decisions-log.md found. Re-invoke with `--force` to start a fresh run."
5. Run `run-lock.sh acquire "$FEATURE_DIR"`. On exit ≠ 0 — halt (§Halt: lock-conflict).
6. Set `STAGE` = first stage in `--target`.
---
## Per-Stage Loop
Repeat until `STAGE = __END__`. On any failure, jump to §TERMINATE with the appropriate kind.
### a. Completeness check
run-completeness.sh "$FEATURE_DIR" "$STAGE"
If output = `complete`: write a `stage-skip` entry to `decisions-log.md`, then route:
```bash
ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
run_id=$(grep '^run_id=' "$FEATURE_DIR/.run/run-lock" | cut -d= -f2-)
printf '## stage-skip:%s · %s\n\n- author: orchestrator\n- status: success\n- run_id: %s\n\nArtifact present.\n\n' \
"$STAGE" "$ts" "$run_id" >> "$FEATURE_DIR/decisions-log.md"
run-route.sh "$FEATURE_DIR" stage="$STAGE" criterion="artifact already present"
Advance: STAGE = run-target.sh next "$TARGET" "$STAGE". Continue loop.
b. Emit stage-start
run-emit-event.sh "$FEATURE_DIR" stage-start stage="$STAGE"
c. Store pre-dispatch HEAD (ADR-030)
git rev-parse HEAD > "$FEATURE_DIR/.run/pre-dispatch-head"
d. Code-gate BLOCKING pause
Only if STAGE ∈ {implement, codereview, audit}:
→ about to dispatch: $STAGE
review the prior stage output in $FEATURE_DIR/decisions-log.md
type `proceed` to continue or `abort` to stop
Wait for user input. On abort: TERMINATE(abort).
e. Pre-dispatch sentinel check
run-lock.sh check-sentinel "$FEATURE_DIR"
On exit 1 (abort file present): TERMINATE(abort).
f. Dispatch subagent
LOG_OFFSET=$(wc -c < "$FEATURE_DIR/decisions-log.md" 2>/dev/null | tr -d ' ' || echo 0)
Use the Task tool. Pass the following to the subagent:
Feature directory:
$FEATURE_DIR(absolute path) Stage:$STAGERun
/speckit.$STAGEfor this feature. Then write a FR-006-conforming record to$FEATURE_DIR/decisions-log.md. Schema:.specify/contracts/decision-log-entry.md. The halt_directive block MUST include:
halt: trueorhalt: falsereason: <required when halt=true>failure_class: <required when halt=true — one of: temporal, semantic, permission>Do NOT skip writing the canonical log entry.
Wait for Task completion before proceeding.
Per-stage diff capture:
pre_head=$(cat "$FEATURE_DIR/.run/pre-dispatch-head" 2>/dev/null || true)
if [[ -n "$pre_head" ]]; then
git diff "$pre_head"..HEAD --name-only > "$FEATURE_DIR/.run/stage-diff-${STAGE}.files"
git diff "$pre_head"..HEAD > "$FEATURE_DIR/.run/stage-diff-${STAGE}.patch"
fi
Produces stage-diff-<stage>.files (changed file list, always shown) and stage-diff-<stage>.patch (full diff, read on request). Both live in $FEATURE_DIR/.run/ and are swept by the next run-lock.sh acquire.
Schema validation:
run-validate-entry.sh "$FEATURE_DIR/decisions-log.md" "$LOG_OFFSET"
On exit 1 or 2: TERMINATE(halt) — schema-violation.
g. Post-dispatch checks (code-action stages only)
Only if STAGE ∈ {implement, codereview, audit}:
Sandbox check:
run-check-sandbox.sh "$FEATURE_DIR" "$STAGE"
On exit ≠ 0: TERMINATE(permission-failure) — include violation list in halt message.
Postcheck:
run-postcheck.sh "$FEATURE_DIR" "$STAGE"
On exit 0 (postcheck: no findings): continue to step h.
On exit ≠ 0: present findings, then prompt:
postcheck findings above — type `proceed` to override (recorded) or `abort` to stop
On proceed: proceed to step h with POSTCHECK_OVERRIDE=true.
On abort: TERMINATE(abort).
h. Route
NEXT_STAGE=$(run-target.sh next "$TARGET" "$STAGE")
run-route.sh "$FEATURE_DIR" from="$STAGE" to="$NEXT_STAGE" reason="subagent complete"
If POSTCHECK_OVERRIDE=true, use reason=postcheck-override instead.
Read stdout:
| Verdict | Action |
|---|---|
continue |
Advance STAGE → continue loop |
halt:<reason> |
TERMINATE(halt) with that reason |
abort |
TERMINATE(abort) |
skip:<stage> |
Advance STAGE → continue loop |
Advance: STAGE = NEXT_STAGE.
When run-target.sh next outputs __END__: TERMINATE(clean).
TERMINATE
On every exit path, run in this order before stopping:
run-serialize.sh "$FEATURE_DIR" <kind>
run-lock.sh release "$FEATURE_DIR"
<kind>: clean | halt | abort | permission-failure
Then present the appropriate halt message (§Halt Messages), or on clean:
Pipeline complete. Stages run: [list]. Artifacts in
$FEATURE_DIR.
Halt Messages
Every message is self-contained: stage, failure class, re-trigger command.
subagent-halt-directive
$STAGEhalted with blocking findings. Address the findings in$FEATURE_DIR/decisions-log.md, then re-run: `/speckit.run
Maintain Speckit.Run?
Let people know it's listed here — add the badge (live metrics, light/dark aware) or a plain link to your README or docs.
[Speckit.Run on getagentictools](https://getagentictools.com/loops/colin-prologue-speckit-run?ref=badge)