pi-gauntlet 8.5.1 → 8.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/README.md +12 -12
- package/extensions/phase-tracker.test.ts +47 -0
- package/extensions/phase-tracker.ts +5 -1
- package/package.json +1 -1
- package/skills/brainstorming/SKILL.md +3 -3
- package/skills/brainstorming/reference/amendment-surface.md +3 -3
- package/skills/brainstorming/reference/pr-subject.md +1 -1
- package/skills/brainstorming/reference/spec-finalization.md +57 -25
- package/skills/brainstorming/reference/spec-pr.md +26 -15
- package/skills/gauntlet-handoff/SKILL.md +1 -1
- package/skills/gauntlet-resume/reference/brief-contract.md +6 -4
- package/skills/loop-implementation/SKILL.md +6 -6
- package/skills/loop-implementation/reference/interrupted-recovery.md +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v8.6.0 - 2026-11-15
|
|
4
|
+
|
|
5
|
+
- Replace the spec approval gate with four rows: `1` plan engine, `2` loop engine, `3` council explanation, and `4` draft-PR handoff. Mark exactly one row `[recommended]`: context reading above 25% recommends row `4` when available; otherwise zero acceptance rows or a bundled row recommends row `1`, and the default is row `2`. Bare `approve` takes the recommended row. The loop engine is no longer labeled experimental.
|
|
6
|
+
- Plain `1` or `2` now grants automatic application of later amendments within the original problem statement; add `--amends-stop` to require human approval instead. Redraws still stop for approval. Use `--fund-rounds=N` on row `1` to fund up to N extra fix rounds per task after its escalated round on the plan engine and `--allowance=N` on row `2` for the loop run allowance.
|
|
7
|
+
- Breaking reply grammar: old `2` changes from plan-with-grant to loop-with-grant, old `4` changes from loop-without-grant to draft-PR handoff, and old `5` and `6` leave the valid range. Gate suffixes `; fund N fix rounds` and `; allowance N` are replaced by `--fund-rounds=N` and `--allowance=N`, with no aliases for the old digits or suffixes.
|
|
8
|
+
- Add a model-visible `Context: <p>% of window` line to `phase_tracker` status (`Context: unknown` when unavailable), without adding it to the TUI.
|
|
9
|
+
|
|
3
10
|
## v8.5.1 - 2026-11-13
|
|
4
11
|
|
|
5
12
|
- Housekeeping excludes spec and plan folders from content checks, keeps specs outside the file budget, and checks specs-only selections instead of ending empty. Fully superseded specs get a Delete-or-Keep card in every run, without a Ticket pick or hotfix-bounds gate; outside references recommend Keep. With no argument, checkout changes select uncommitted files and disclose commits ahead of the unfetched local ref; a clean checkout selects unpushed changes after fetching, with stops for divergent history, remote containment and squash receipts.
|
package/README.md
CHANGED
|
@@ -36,16 +36,16 @@ pi-gauntlet's only hard dependency is pi-cohort - every gate that dispatches a r
|
|
|
36
36
|
Concretely, one change through the gauntlet:
|
|
37
37
|
|
|
38
38
|
0. *(Optional)* Before there's even a spec, `/skill:shape-ticket` can create one tracker issue or repair a comma/whitespace list of issue refs - shaping each into a Context/Problem/Idea/Acceptance Criteria ticket, grounded by a repository audit, an AC integrity check, and a cheap council roast. Repair finishes preparation for all tickets before presenting exact-diff confirmations sequentially in ref order; each approval writes that ticket before the next gate, and may include one optional gated comment for a Reporter note or overlap evidence. The audit checks factual claims, Idea fit, AC mechanisms against cited repo guidance, and already-stated observable legs in configured sibling checkouts. It reports in-motion work and attempts a best-effort scenario through authorized current-system reads, without promising reproduction or a fix; missing access or nothing to observe is reported, not a new approval gate. Implementer detail moves into the gated Reporter note; brainstorming reads that note with the ticket so the spec retains the detail. A failed roast is retried once, then surfaced inline at the gate if it fails again. It's a tool, not a phase: no worktree, no plan/phase tracker, runs from any repo state. The agent may start it on its own when the ask is "file a ticket" or another skill routes there; the write still waits for your yes on the presented diff. Similarly, `/skill:chase-bug` triages a raw bug report into an evidenced verdict - and can hand off to shape-ticket, brainstorming, or a bounded hotfix - before any spec exists.
|
|
39
|
-
1. Opt in with `/skill:brainstorming` and describe the change. The command is the reliable discovery-and-entry path; explicit prose requesting brainstorming/the gauntlet also supplies consent when the skill is already loaded or an available instruction or route identifies it. An ordinary implementation request or an agent recommendation is not consent. A leading run of GitHub references (`#N`, `owner/repo#N`, or a `/pull/N` or `/issues/N` URL), separated by whitespace or commas, resolves each reference as a PR first: related open, same-repository, non-fork PRs on one base form one rework subject, including drafts. Admission runs in listed order and relatedness is checked before provisioning; the first retained PR is home, whose existing branch rebases onto the fetched PR base by default, then member commits replay onto it in listed order. The first intent word `merge-forward` opts out and keeps the merge path. An unresolved conflict after its scoped helper aborts that step and continues to the spec with the repair as Task 1. A single non-PR reference follows the ticket path. The first non-reference token starts intent text; mid-sentence references and other ticket/free-text subjects keep their existing paths. The combined code, PR-carried specs, claims, and review threads are the brainstorm input, with each PR's provenance retained; only home's bound ticket supplies acceptance criteria, while member tickets supply context. A single PR retains the same rework path without member replays or a close offer. The combined state is judged against constraints from the fetched current base HEAD, not the fork point or the PRs' proposed policy edits; see the [PR-subject contract](skills/brainstorming/reference/pr-subject.md) and [PR-head worktree owner](skills/using-git-worktrees/reference/pr-head.md). **`brainstorming`** sets up an isolated worktree (on the existing branch for PR rework), explores the codebase, and turns the subject into a written spec - when its recon finds a cited case that the ask is the wrong change (misdiagnosed, wrong-sized, already solved, a band-aid, or cutting across a sound pattern - including a repo convention that is itself debt) and can name the alternative, question one is a framing question (`as framed`, `pivot: <alternative>`, or `smaller or none`); otherwise it opens with one sentence naming what it checked, and every approach it proposes ends with a `Pattern:` line naming what it follows or cuts across; when the run starts from a ticket, the spec carries the ticket's acceptance criteria verbatim, each with a disposition (`in-scope`, `deviates:`, `deferred:`, `venue:`, `elsewhere:` for a row another repo's part delivers), scope cuts come only from your answer to a cut question and are listed at the gate, the conformance gate checks the in-scope ones, and `/skill:check-delivery` verifies `venue:` rows before the prod deploy. A multi-model critique runs on it automatically. If the spec replaces a known prior spec, brainstorming marks the predecessor with a `> **Superseded by:**` banner under its title (default format, syntax overridable via `.pi/gauntlet-overrides.md`; candidates come from brainstorming's scout recon, never a mechanical sweep). **You read and approve the spec - human gate 1.**
|
|
40
|
-
2.
|
|
39
|
+
1. Opt in with `/skill:brainstorming` and describe the change. The command is the reliable discovery-and-entry path; explicit prose requesting brainstorming/the gauntlet also supplies consent when the skill is already loaded or an available instruction or route identifies it. An ordinary implementation request or an agent recommendation is not consent. A leading run of GitHub references (`#N`, `owner/repo#N`, or a `/pull/N` or `/issues/N` URL), separated by whitespace or commas, resolves each reference as a PR first: related open, same-repository, non-fork PRs on one base form one rework subject, including drafts. Admission runs in listed order and relatedness is checked before provisioning; the first retained PR is home, whose existing branch rebases onto the fetched PR base by default, then member commits replay onto it in listed order. The first intent word `merge-forward` opts out and keeps the merge path. An unresolved conflict after its scoped helper aborts that step and continues to the spec with the repair as Task 1. A single non-PR reference follows the ticket path. The first non-reference token starts intent text; mid-sentence references and other ticket/free-text subjects keep their existing paths. The combined code, PR-carried specs, claims, and review threads are the brainstorm input, with each PR's provenance retained; only home's bound ticket supplies acceptance criteria, while member tickets supply context. A single PR retains the same rework path without member replays or a close offer. The combined state is judged against constraints from the fetched current base HEAD, not the fork point or the PRs' proposed policy edits; see the [PR-subject contract](skills/brainstorming/reference/pr-subject.md) and [PR-head worktree owner](skills/using-git-worktrees/reference/pr-head.md). **`brainstorming`** sets up an isolated worktree (on the existing branch for PR rework), explores the codebase, and turns the subject into a written spec - when its recon finds a cited case that the ask is the wrong change (misdiagnosed, wrong-sized, already solved, a band-aid, or cutting across a sound pattern - including a repo convention that is itself debt) and can name the alternative, question one is a framing question (`as framed`, `pivot: <alternative>`, or `smaller or none`); otherwise it opens with one sentence naming what it checked, and every approach it proposes ends with a `Pattern:` line naming what it follows or cuts across; when the run starts from a ticket, the spec carries the ticket's acceptance criteria verbatim, each with a disposition (`in-scope`, `deviates:`, `deferred:`, `venue:`, `elsewhere:` for a row another repo's part delivers), scope cuts come only from your answer to a cut question and are listed at the gate, the conformance gate checks the in-scope ones, and `/skill:check-delivery` verifies `venue:` rows before the prod deploy. A multi-model critique runs on it automatically. If the spec replaces a known prior spec, brainstorming marks the predecessor with a `> **Superseded by:**` banner under its title (default format, syntax overridable via `.pi/gauntlet-overrides.md`; candidates come from brainstorming's scout recon, never a mechanical sweep). **You read and approve the spec - human gate 1.** Rows 1/2 approve and pick the plan/loop engine respectively; row 3 explains the council audit; row 4 approves the content only: it writes `**Engine:** deferred` under `**Amend-grant:** none`, pushes the branch, opens a draft PR carrying just the spec, prints the URL, and ends the flow - no plan, no loop, no handoff brief. For a coordinated spec, it first pushes every companion branch to origin, then opens one home draft PR; it creates no companion PRs. A later `brainstorming #N` reconstructs the recorded companions from their origin branches before re-presenting the implementation gate; the [publication and re-gate owner](skills/brainstorming/reference/spec-pr.md) defines all-member preflight, recovery, and cleanup. After confirming the live remote and local branch match the worktree commit, cleanup removes an owned tree and conditionally deletes the local branch at that pinned commit. A host-owned checkout or failed remote check keeps tree and branch, with a per-repo reason. Row 4 is withheld on a PR subject (`Withheld: draft PR - #N already exists`) and when the branch's diff against the default branch is not spec-only. A later `brainstorming #N` on that PR classifies it from the diff alone: one added spec carrying the marker plus banner-only predecessor edits re-presents the gate with 1/2 (3 only when the spec commit carries a council audit) and skips gather, questionary, council, and scout; a spec-only diff without the marker prints `spec-only PR without the gate marker - running lint and council` and takes the normal brainstorm path with the carried spec as the draft; any other diff takes the rework path. Approval at that re-gate writes `**Engine:**`, `**Amend-grant:**`, and `**PR:** <owner/repo#N>` as a new commit on the PR branch and chains into planning or the loop as usual. Before approval, PR rework's sole write/run exception outside the spec directories permits only the base sync (rebase or merge), each member replay or merge, their conflict helpers' edits to the conflicted files, and their scoped conflict tests; other subjects have no implementation code yet.
|
|
40
|
+
2. Choosing the plan engine (row 1) runs **`writing-plans`**, which decomposes the approved spec into atomic, independently-verifiable tasks, grouped into parallel waves where they don't touch the same files. Choosing the loop engine (row 2) runs **`loop-implementation`**: the plan phase is skipped and a stamped acceptance-criteria ledger replaces the task plan. Both engine rows auto-apply amends by default; `--amends-stop` retains amendment review. With amend permission, the loop auto-applies unreachable-row cuts and funds conformance rounds up to the allowance when the cap blocks. Redraws and exhausted attempt or repair allowances still stop; an interrupted return recovers without a human turn with or without amend permission. See [Loop engine operations](doc/configuration.md#loop-engine-operations).
|
|
41
41
|
3. **`subagent-driven-development`** executes the plan in waves, with task implementers followed by one integrated `wave-reviewer` after the scoped test gate passes. The reviewer checks anchored spec clauses and code quality together; repairs stay on the current tree and pass the same gate before re-review. TDD-locked: red, green, refactor. Independent implementation, review, and council batches remain parallel, but their dispatches are foreground: the orchestrator waits for terminal results before accepting work or advancing a phase.
|
|
42
|
-
The loop alternative to step 3 runs one fresh `loop-implementer` per seed or row iteration, without implement-phase reviewers. Each row starts with the shared allowance (default 4); approval replies such as `
|
|
42
|
+
The loop alternative to step 3 runs one fresh `loop-implementer` per seed or row iteration, without implement-phase reviewers. Each row starts with the shared allowance (default 4); approval replies such as `2 --allowance=6` override it for one run. With or without amend permission, attempt `escalateAfter + 1` (default 4), clamped to the last allowed attempt, escalates once per row on `escalationLoop.implModel` (the main-loop model when unset); later attempts use the ordinary worker model. The allowance also bounds seed and exit-verification repair counts; verification repairs use the same escalation model and count home repair commits plus an unmatched `pending: verify` reservation. Stagnation supplies a row-local hint, not an early stop. An interrupted return is one failed attempt: recovery is unconditional with or without amend permission, before checking allowance. The driver signals only identity-matching jobs, skips absent or mismatched jobs, deletes the jobs file, resets to the saved pre-dispatch HEAD and runs `clean -fd`, then restores the saved ledger and commits the failed attempt. Continue recovery even with a surviving job or remaining dirt. Wrong HEAD or an unwritten repair repeats reset and repair, counting each pass against the same allowance until the repair lands on the saved HEAD or the existing exhaustion stop fires. With no pending dispatch, a dirty entry or restored tree instead lists paths and asks for typed `discard` or Stop only; discard resets to HEAD, cleans and resumes the suspended entry or restore sequence before dispatch or verification. An admitted `unreachable:` target failure becomes an audited scope cut under amend permission, never a passing row. At a row stop, `retry <n> | <hint>` adds one attempt to that row, while `rows +N` raises every row's allowance. Attempts never reset and there is no total iteration cap. Ledger refresh completes implement when every row is closed; verify step 1 runs the gate set: deduplicated (owning checkout, command) pairs from done rows' recorded checks, with ownership from the ledger. Gate output goes to logs; the driver keeps exit codes and paths, not test output. CI on push owns the full run.
|
|
43
43
|
|
|
44
44
|
Approval authorizes every paid or external action named in an AC or Design, with its runner and inputs, for the whole flow. A count or wording deferring it to later approval does not withhold authorization. The worker runs it whenever an attempt needs it without asking and reuses its output for local rechecks; evidence commands name local replay or fixtures. Missing prerequisites and unnamed actions still fail as `unreachable:`.
|
|
45
45
|
|
|
46
46
|
These are the loop stops this recovery and authorization contract keeps or touches, not the driver's whole stop set. Missing capabilities or references, malformed grants, unresolved verification entrypoints, repeated-evidence amendment handling and failed refresh guards retain their own text. The driver renders only stops named in its skill and references; another failed dispatch consumes an attempt, not an invented menu or approval.
|
|
47
47
|
|
|
48
|
-
| Stop |
|
|
48
|
+
| Stop | Without amend permission (`2 --amends-stop`) | With amend permission (default `2`) |
|
|
49
49
|
|---|---|---|
|
|
50
50
|
| Row attempts reach effective allowance; seed repairs reach allowance; escalation model unavailable for a row's escalated round | Retry, `rows +N`, amend, stop | Same |
|
|
51
51
|
| Verification repairs reach allowance; escalation model unavailable for a verification repair | Amend, stop | Same |
|
|
@@ -57,7 +57,7 @@ These are the loop stops this recovery and authorization contract keeps or touch
|
|
|
57
57
|
| Dirty tree with no dispatch pending; on resume, admission question or missing-history stops (unrecoverable pre-dispatch ledger/tuple, or unreadable child attribution with no tuple) | Stops | Stops |
|
|
58
58
|
| Dispatch returns an async handle despite `async: false` | Stops | Stops |
|
|
59
59
|
|
|
60
|
-
A budget reply does not supply a missing escalation model. A reopened row already at allowance takes the row stop
|
|
60
|
+
A budget reply does not supply a missing escalation model. A reopened row already at allowance takes the row stop with or without amend permission; with amend permission, verify stays active without a phase reset. Resume's admission question lists commits and dirt and explains that answering `interrupted` discards them through reset to the pre-dispatch HEAD and `clean -fd`. See [loop stop boundaries](doc/configuration.md#loop-stop-boundaries) for the reply and continuation details.
|
|
61
61
|
|
|
62
62
|
4. **verify**: the parent first runs the plan's full verification command set for waves, or the ledger gate set for loop; only a passing result permits whole-diff code review, then the **conformance gate**. A review fix invalidates that result, so the parent reruns the same set before the next review or conformance gate. Loop conformance repairs and finish also use the gate set, never the ledger's full `verification:` command. When the overrides file declares a happy path for the touched paths (see [Project-specific overrides](#project-specific-overrides)), the parent runs it once here, between code review and the conformance gate, and the reviewer reads its transcript as runtime evidence - a hang or a failed request shows up in the audit with the transcript quoted - as a gap when an origin clause ties to it, otherwise as a `happy-path: failed - unattributable` line - never as a silent green. The conformance subagent reads the finished code and docs against your *original words* from step 1, not the plan, and reports per-requirement: delivered, partial, missing, drifted, or unauthorized. Unauthorized rows - shipped surface no human input asked for, whether it crept in or was laundered through the spec - follow their recommendation like every other row: a contained removal auto-runs, anything another requirement leans on is deferred with a plain-language "I'd cut it / I'd keep it" recommendation. Inside a brainstorming-entered flow this gate is machine-blocked from being skipped. Compatible executable recommendations auto-run through an isolated fix-and-re-audit loop with no prompt; anything still open surfaces as a numbered decision brief - one item per decision, the problem in plain words first, lettered options each with a one-line consequence, and `Recommended: <letter> - <reason>` or `No recommendation - pick one`. Reply with one line per item (`1. B`), or bare `1` to take every recommendation (no-recommendation items are re-asked by number); a current `CONFORMS` / no-concerns result goes straight to the branch options with no extra conformance sign-off.
|
|
63
63
|
5. **`finishing-a-development-branch`**: PR, draft PR, squash, keep, or discard; PR rework's row 1 offers a lease push of the rebased home branch to the existing PR (`Base:` records in `merge:` form push non-force). A spec whose header carries `**PR:**` (approved at a spec-PR re-gate) and no `## Rework record` replaces the two create rows with `Push to PR #N and mark it ready for review` and `Push to PR #N, keep it a draft` (`Push to PR #N (already ready for review)` when the PR is already ready): both push without force after strip-and-seal, the first then runs `gh pr ready`, neither rewrites the PR body, and both are withheld when origin's branch head is no longer an ancestor of local HEAD. For coordinated specs, these [header-linked rows 1/2](skills/finishing-a-development-branch/reference/spec-pr.md#push-rows-12) deliver companions in recorded order before one home seal carrying every companion PR URL, then push home and apply its readiness choice. Row 1 makes companion drafts ready too; row 2 creates drafts but never converts an already-ready PR back to draft. Companion URLs appear in the shipped summary, companions first and home last, not in the unchanged home PR body; keep that summary for cross-repo review because successful home delivery removes receipts. A spec still carrying `**Engine:** deferred` stops finishing (and `gauntlet-resume`) with `spec approved for handoff only - run brainstorming #N` before any phase change, verification, or push. The PR-rework push appends a `## Rework` block naming absorbed PRs while retaining the original description bytes; the header-linked `**PR:**` push leaves the body untouched. Only after a successful rework push and home-description edit does one gated confirmation show the exact close comments and eligible member targets, linking home; declining or any other finish option leaves members open. Closing never deletes member branches, and finish posts no review-thread replies. Its `Before:` handle includes the full portable pre-rework SHA and the local `refs/gauntlet/pre-rework/pr-<N>` ref in the rework checkout. The [finishing owner](skills/finishing-a-development-branch/SKILL.md#pr-subject-row-1-push-to-the-pr-branch) defines the landing and body-update contract. Once a PR exists, run `/skill:gatekeep-pr <pr>` to verify it before merging - it judges the diff against the spec at the PR's head (the acceptance-criteria dispositions and Design you approved; the PR description when no spec applies) - rows the spec defers or deviates are settled, every other row needs its mechanism (code, tests, docs) - and against the rubric; whatever can be seen only after merge is left to step 6. **Human gate 2** - the only other decision you make.
|
|
@@ -72,7 +72,7 @@ flowchart LR
|
|
|
72
72
|
T -.-> R
|
|
73
73
|
B --> G1{{human gate 1:<br/>approve spec}}
|
|
74
74
|
G1 --> P[plan]
|
|
75
|
-
G1 -.
|
|
75
|
+
G1 -.row 4.-> H[draft spec PR]
|
|
76
76
|
H -.brainstorming re-entry.-> G1
|
|
77
77
|
P --> I[implement<br/>waves + reviews]
|
|
78
78
|
I --> V[verify]
|
|
@@ -89,7 +89,7 @@ In create mode, `shape-ticket` runs one bounded overlap check after clarificatio
|
|
|
89
89
|
|
|
90
90
|
Use `/skill:shape-ticket --skip-overlap <ask>` to bypass discovery explicitly. Repair mode never discovers candidates. Bypass still retains source reads, known conflicts, integrity checks, roast, approval, and source revalidation. Incomplete search coverage is disclosed, not treated as proof of no overlap; independent sessions can still race, so this is not a uniqueness guarantee.
|
|
91
91
|
|
|
92
|
-
Between gate 1 and gate 2, both engines take named authorized recommendations under the spec's amend grant and run one bounded escalated execution round before eligible stops; exhausted allowances, cap and admission failures, waves stagnation and redraws still stop, and budget-only grants supply no amend permission. Planning takes concrete baseline `narrow` or `amend` recommendations under that permission; `fix-first` enters ticket shaping's own gate. An implementer-evidenced text correction to a drafted AC is an amendment, not a redraw; ticket rows, row add/remove and problem or component boundary changes still require redraw approval. See [execution continuation](doc/implement-engines.md#stops-models-and-telemetry). Once gate 1 picks an engine, task breakdown, implementation and reviews proceed within those limits;
|
|
92
|
+
Between gate 1 and gate 2, both engines take named authorized recommendations under the spec's amend grant and run one bounded escalated execution round before eligible stops; exhausted allowances, cap and admission failures, waves stagnation and redraws still stop, and budget-only grants supply no amend permission. Planning takes concrete baseline `narrow` or `amend` recommendations under that permission; `fix-first` enters ticket shaping's own gate. An implementer-evidenced text correction to a drafted AC is an amendment, not a redraw; ticket rows, row add/remove and problem or component boundary changes still require redraw approval. See [execution continuation](doc/implement-engines.md#stops-models-and-telemetry). Once gate 1 picks an engine, task breakdown, implementation and reviews proceed within those limits; row 4 parks the approved spec in a draft PR and planning starts only when someone runs `brainstorming #N` on it and approves at the re-gate. Changing an approved spec later goes through brainstorming's `Amending an approved spec`: a fresh-context reviewer clears evidence-backed factual corrections on its own, escalations reach you as one readable batch, and only a redraw is a full stop - not a third numbered gate. That's the mechanism. What follows is the machinery behind it.
|
|
93
93
|
|
|
94
94
|
### Multi-repo runs
|
|
95
95
|
|
|
@@ -99,7 +99,7 @@ The approved home spec records `## Legs`, including each leg's scope, rules and
|
|
|
99
99
|
|
|
100
100
|
Home overrides and settings govern flow policy. Each leg's own overrides and settings govern checkout operations, directories and verification; absent configuration uses defaults. Recorded `contract:` lines are authoritative for every spec with `## Legs`, including one-member runs: amend the home block and affected companion file before using a changed contract. Finish does not replace them by rereading overrides. Legacy specs without `## Legs` are home-only and retain the finish-time reread.
|
|
101
101
|
|
|
102
|
-
|
|
102
|
+
Row 4's draft-PR handle is one home draft PR plus companion branches on origin, with no brief, companion PRs or receipts. `brainstorming #N` preflights every recorded companion before provisioning them from origin and re-gating under the [publication and re-gate contract](skills/brainstorming/reference/spec-pr.md). Cleanup runs companions first, then home, removing owned trees and deleting local branches only after a live remote equality check and confirmed removal; each leg reports its read-back state even when another cleanup fails. This supersedes the kept-local-branch cleanup in the [spec-only draft-PR design](doc/specs/2026-10-28-spec-only-draft-pr.md); a remote branch deleted after handoff now needs restoration from a clone that still has it, not the cleaned-up machine. PR lists still take the rework path. The separate `gauntlet-handoff` / `gauntlet-resume` route carries every member in the brief's `legs:` block. Resume starts only from the home primary, validates companion repository, branch and home pointer, and announces per-leg HEAD and dirty drift. On that route a missing companion worktree requires a live-validated completion receipt; draft-PR re-entry instead uses the published origin branch. The [brief contract](skills/gauntlet-resume/reference/brief-contract.md#coordinated-brief-grammar) owns the brief grammar and admission rules.
|
|
103
103
|
|
|
104
104
|
One finish choice spans all legs. PR, draft PR and squash deliver companions in declaration order, then seal and deliver home; keep preserves all legs, and discard lists all legs before one confirmation. Verification and conformance run per leg; home's passing tests do not credit companions. Delivery failure stops without rollback and reports shipped and unshipped legs. A retry from the brief validates home-owned receipts and skips only proven deliveries; stale PR heads are updated, and failed post-squash verification reruns without another squash. See the [delivery and recovery contract](skills/finishing-a-development-branch/reference/legs.md).
|
|
105
105
|
|
|
@@ -145,7 +145,7 @@ Run by a human against pi-cohort >= 7.1.0, before a pi-gauntlet release claims t
|
|
|
145
145
|
6. Primary session, idle trackers, spec tracked on main: `/skill:gauntlet-resume doc/specs/<x>.md` creates the worktree and asks the approval question; approval leaves `phase_tracker` at plan in_progress with brainstorm `⊘ (resume: ...)`.
|
|
146
146
|
7. Fresh idle session, same seed: the registered worktree is reused (no creation) and the question repeats. Run once on a consumer whose `## using-git-worktrees` override lays worktrees out as sibling dirs, once on `.worktrees/`.
|
|
147
147
|
8. After writing-plans commits the plan beside the seeded spec: `/skill:gauntlet-handoff` then a fresh `/skill:gauntlet-resume <brief>` restores plan phase; a fresh `/skill:gauntlet-resume <worktree>` reaches "Spec with plan" with task evidence from the plan commit.
|
|
148
|
-
9. Spec approved with `2`, then `/skill:gauntlet-handoff` and a fresh `/skill:gauntlet-resume <brief>`: the closing line is followed by `Standing grant active: <sentence>` and the next amend batch applies without a menu. A spec approved with `1` prints `No standing grant.`; a spec with two `**Amend-grant:**` lines stops before any tracker call, naming both lines.
|
|
148
|
+
9. Spec approved with `2`, then `/skill:gauntlet-handoff` and a fresh `/skill:gauntlet-resume <brief>`: the closing line is followed by `Standing grant active: <sentence>` and the next amend batch applies without a menu. A spec approved with `1 --amends-stop` prints `No standing grant.`; a spec with two `**Amend-grant:**` lines stops before any tracker call, naming both lines.
|
|
149
149
|
|
|
150
150
|
## Key concepts
|
|
151
151
|
|
|
@@ -637,7 +637,7 @@ Anything a wrapper skill contains beyond trigger phrases is misplaced - move it
|
|
|
637
637
|
|
|
638
638
|
Settled skill-owned turns carry a machine-readable first line identifying a gate, question, or terminal outcome. Programs answering these turns use the [gate inventory and reply contract](doc/gate-contract.md); the rendered row bodies define valid replies.
|
|
639
639
|
|
|
640
|
-
Choose
|
|
640
|
+
Choose the loop engine with row 2, configure the per-row allowance and worker model, and operate the planless ledger through [Loop engine operations](doc/configuration.md#loop-engine-operations). Its `--allowance=N` flag shows the resolved default; `2 --allowance=6` sets six attempts per row for one run. Auto-apply amends is the default; add `--amends-stop` to retain amendment review. Resume preserves an existing allowance or migrates a legacy cap after pending recovery. Specs without an Engine header use waves.
|
|
641
641
|
|
|
642
642
|
| Want to ... | Read |
|
|
643
643
|
|---|---|
|
|
@@ -652,8 +652,8 @@ The conformance gate's model, the spec council's roster, and the phase-tracker's
|
|
|
652
652
|
| `closureReview.enforce` | phase-tracker | `true` | conformance gate on/off - [detail](./doc/configuration.md#conformance-gate-model) |
|
|
653
653
|
| `closureReview.model` | phase-tracker | unset (inherits) | conformance reviewer model - [detail](./doc/configuration.md#conformance-gate-model) |
|
|
654
654
|
| `closureReview.maxFixRounds` | phase-tracker | `5` | fix rounds before escalation - [detail](./doc/configuration.md#conformance-gate-model) |
|
|
655
|
-
| `escalationLoop.implModel` | phase-tracker | unset (main loop) | execution escalation
|
|
656
|
-
| `loopEngine.maxIterationsPerRow` | phase-tracker | `4` (floor `1`) | fresh-ledger per-row allowance; run override
|
|
655
|
+
| `escalationLoop.implModel` | phase-tracker | unset (main loop) | execution escalation with or without amend permission; review escalation remains separate - [detail](./doc/configuration.md#escalation-loop) |
|
|
656
|
+
| `loopEngine.maxIterationsPerRow` | phase-tracker | `4` (floor `1`) | fresh-ledger per-row allowance; run override with `2 --allowance=N` - [detail](./doc/configuration.md#setting-and-command-resolution) |
|
|
657
657
|
| `loopEngine.escalateAfter` | phase-tracker | `3` (floor `1`) | pre-dispatch threshold; escalated attempt index is value + 1, clamped to the last allowed attempt - [detail](./doc/configuration.md#setting-and-command-resolution) |
|
|
658
658
|
| `phaseModels.plan` / `.implement` / `.verify` / `.ship` | phase-tracker | unset (no switch) | `provider/id[:level]` applied persistently at that phase's start - [detail](./doc/configuration.md#phase-models) |
|
|
659
659
|
| `flowGuards.enforce` | phase-tracker | `true` | phase gates on/off - [detail](./doc/configuration.md#phase-tracker) |
|
|
@@ -586,6 +586,53 @@ test("tracker registration is model-only and phase_tracker requests sequential e
|
|
|
586
586
|
}
|
|
587
587
|
});
|
|
588
588
|
|
|
589
|
+
for (const row of [
|
|
590
|
+
{ name: "exactly 25 percent", read: () => ({ tokens: 250000, contextWindow: 1000000, percent: 0 }), expected: "25.0% of window" },
|
|
591
|
+
{ name: "just above 25 percent", read: () => ({ tokens: 250001, contextWindow: 1000000, percent: 25 }), expected: "25.1% of window" },
|
|
592
|
+
{ name: "exactly 26 percent", read: () => ({ tokens: 260000, contextWindow: 1000000, percent: null }), expected: "26.0% of window" },
|
|
593
|
+
{ name: "zero tokens", read: () => ({ tokens: 0, contextWindow: 1000000, percent: 99 }), expected: "0.0% of window" },
|
|
594
|
+
{ name: "fractional percentage", read: () => ({ tokens: 1, contextWindow: 3, percent: 33 }), expected: "33.4% of window" },
|
|
595
|
+
{ name: "missing reader", read: undefined, expected: "unknown" },
|
|
596
|
+
{ name: "no usage", read: () => undefined, expected: "unknown" },
|
|
597
|
+
{ name: "null tokens", read: () => ({ tokens: null, contextWindow: 1000000, percent: null }), expected: "unknown" },
|
|
598
|
+
{ name: "zero window", read: () => ({ tokens: 250000, contextWindow: 0, percent: 25 }), expected: "unknown" },
|
|
599
|
+
{ name: "negative window", read: () => ({ tokens: 250000, contextWindow: -1, percent: 25 }), expected: "unknown" },
|
|
600
|
+
]) {
|
|
601
|
+
test(`status context: ${row.name}`, async () => {
|
|
602
|
+
const h = harness();
|
|
603
|
+
const tool = h.tools.find(t => t.name === "phase_tracker")!;
|
|
604
|
+
const ctx = { ...h.ctx, getContextUsage: row.read };
|
|
605
|
+
const result = await tool.execute("status", { action: "status" }, undefined, undefined, ctx) as {
|
|
606
|
+
content: { text: string }[];
|
|
607
|
+
};
|
|
608
|
+
assert.equal(result.content.map(c => c.text).join("\n").split("\n").at(-1), `Context: ${row.expected}`);
|
|
609
|
+
});
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
for (const row of [
|
|
613
|
+
{ name: "known", usage: { tokens: 1, contextWindow: 3, percent: 33 }, expected: "33.4% of window" },
|
|
614
|
+
{ name: "unknown", usage: undefined, expected: "unknown" },
|
|
615
|
+
]) {
|
|
616
|
+
test(`status context stays out of details, TUI and widget: ${row.name}`, async () => {
|
|
617
|
+
const state = phases({ brainstorm: "in_progress" });
|
|
618
|
+
const h = harness({ hasUI: true, branch: enteredBranch(state) });
|
|
619
|
+
Object.assign(h.ctx, { getContextUsage: () => row.usage });
|
|
620
|
+
await h.emit("session_start");
|
|
621
|
+
const widgetBefore = h.widgets.at(-1);
|
|
622
|
+
assert.match(widgetBefore!, /brainstorm/);
|
|
623
|
+
const tool = h.tools.find(t => t.name === "phase_tracker")! as any;
|
|
624
|
+
const result = await tool.execute("status", { action: "status" }, undefined, undefined, h.ctx);
|
|
625
|
+
assert.equal(result.content[0].text.split("\n").at(-1), `Context: ${row.expected}`);
|
|
626
|
+
assert.deepEqual(result.details, { action: "status", phases: state });
|
|
627
|
+
const rendered = tool.renderResult(result, {}, { fg: (_color: string, text: string) => text });
|
|
628
|
+
assert.match(rendered.text, /Phases:[\s\S]*brainstorm/);
|
|
629
|
+
assert.doesNotMatch(rendered.text, /Context:|of window/);
|
|
630
|
+
await h.emit("session_switch");
|
|
631
|
+
assert.equal(h.widgets.at(-1), widgetBefore);
|
|
632
|
+
for (const widget of h.widgets) assert.doesNotMatch(widget!, /Context:|of window/);
|
|
633
|
+
});
|
|
634
|
+
}
|
|
635
|
+
|
|
589
636
|
test("all-complete plan activity auto-completes an active implement phase", async () => {
|
|
590
637
|
const h = harness({ branch: implementBranch() });
|
|
591
638
|
await h.emit("session_start");
|
|
@@ -1312,8 +1312,12 @@ export default function (pi: ExtensionAPI) {
|
|
|
1312
1312
|
}
|
|
1313
1313
|
|
|
1314
1314
|
case "status": {
|
|
1315
|
+
const usage = ctx.getContextUsage?.();
|
|
1316
|
+
const context = usage && usage.tokens !== null && usage.contextWindow > 0
|
|
1317
|
+
? `${(Math.ceil(usage.tokens * 1000 / usage.contextWindow) / 10).toFixed(1)}% of window`
|
|
1318
|
+
: "unknown";
|
|
1315
1319
|
return {
|
|
1316
|
-
content: [{ type: "text", text: formatStatus(phases) }],
|
|
1320
|
+
content: [{ type: "text", text: `${formatStatus(phases)}\nContext: ${context}` }],
|
|
1317
1321
|
details: { action: "status", phases: { ...phases } } as PhaseTrackerDetails,
|
|
1318
1322
|
};
|
|
1319
1323
|
}
|
package/package.json
CHANGED
|
@@ -34,7 +34,7 @@ Treat the flag as discovery control, not harness authorization. The command reli
|
|
|
34
34
|
|
|
35
35
|
## Checklist
|
|
36
36
|
|
|
37
|
-
Work through the items below **in order**. After a user answer or completed side task, resume the current checklist step and perform the next authorized action in the same turn, advancing once that step's required decisions and approvals are satisfied. Continue until a required question is unanswered, an existing approval is pending, the user explicitly pauses, or a failed required tool or unavailable required resource blocks progress. This is your own checklist to follow, not a `plan_tracker` plan - brainstorming is open-ended exploration, and `plan_tracker` is execution-only (the implement phase). The terminal state is the user review gate; after approval route 1
|
|
37
|
+
Work through the items below **in order**. After a user answer or completed side task, resume the current checklist step and perform the next authorized action in the same turn, advancing once that step's required decisions and approvals are satisfied. Continue until a required question is unanswered, an existing approval is pending, the user explicitly pauses, or a failed required tool or unavailable required resource blocks progress. This is your own checklist to follow, not a `plan_tracker` plan - brainstorming is open-ended exploration, and `plan_tracker` is execution-only (the implement phase). The terminal state is the user review gate; after approval route 1 to `/skill:writing-plans` and 2 to `/skill:loop-implementation` per the gate; 4 ends the flow after publishing. Do not jump ahead of approval, and do not silently drop the critique pass.
|
|
38
38
|
|
|
39
39
|
1. **Start brainstorm tracking (fresh epoch)** - as the first action on authorized fresh entry, before reading code, the worktree, or answering the user, reset both trackers and start the phase. A new brainstorm owns a clean slate, so stale phases and tasks from earlier work are cleared; re-entering mid-brainstorm is safe (nothing to lose, same clean slate):
|
|
40
40
|
|
|
@@ -55,7 +55,7 @@ Work through the items below **in order**. After a user answer or completed side
|
|
|
55
55
|
10. **Re-run placeholder scan** - follow [Spec Self-Review](#spec-self-review-before-user-review-gate).
|
|
56
56
|
11. **Generate spec summary** - follow [User Review Gate](#user-review-gate).
|
|
57
57
|
12. **User review gate** - follow [User Review Gate](#user-review-gate).
|
|
58
|
-
13. **Transition** - after approval, invoke `/skill:writing-plans` on 1
|
|
58
|
+
13. **Transition** - after approval, invoke `/skill:writing-plans` on 1 or `/skill:loop-implementation` on 2 per [User Review Gate](#user-review-gate); 4 ends the flow after publishing.
|
|
59
59
|
|
|
60
60
|
## Project Routing
|
|
61
61
|
|
|
@@ -168,7 +168,7 @@ Follow [Spec Council](reference/spec-finalization.md#spec-council) for the manda
|
|
|
168
168
|
|
|
169
169
|
## User Review Gate
|
|
170
170
|
|
|
171
|
-
Follow [User Review Gate](reference/spec-finalization.md#user-review-gate) for summary, commit, approval, and selected-engine transition or
|
|
171
|
+
Follow [User Review Gate](reference/spec-finalization.md#user-review-gate) for summary, commit, approval, and selected-engine transition or row-4 publication.
|
|
172
172
|
|
|
173
173
|
## Amending an approved spec
|
|
174
174
|
|
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
## Standing grants
|
|
6
6
|
|
|
7
|
-
Honor a user sentence in this flow that waives per-diff review for later amends (`auto-apply amends`, `approve, auto-apply amends` or
|
|
7
|
+
Honor a user sentence in this flow that waives per-diff review for later amends (`auto-apply amends`, `approve, auto-apply amends`, a `1` or `2` approval without `--amends-stop` at the spec gate, `auto-apply amends, stop only for redraws`, `apply spec fixes without asking`, or the same intent in other words). The gate grants on a `1` or `2` approval without `--amends-stop`, and a prose grant after an `--amends-stop` approval still counts. Apply every later amend-class change without review, scope changes included; redraws always stop and the grant never satisfies the spec gate.
|
|
8
8
|
|
|
9
9
|
A grant is the spec's `**Amend-grant:**` line read through the shared predicate; `none` or a missing line means no grant. A new brainstorm writes `none`; a resume honors the line as written. Never take a grant from commit history, a handoff brief, or the transcript; the one read of a prior commit is the post-revert restore, which reads the pre-revert HEAD's spec line.
|
|
10
10
|
|
|
11
|
-
**The line.** `**Amend-grant:** none` or `**Amend-grant:** <granting sentence verbatim, one physical line>`, in the header block (the span between the H1 and the first `##`). Writers place it directly below `**Goal:**` when that line exists, otherwise on the first line after the H1, its blank line, and any `> **Superseded by:**` banner lines; readers never depend on the position.
|
|
11
|
+
**The line.** `**Amend-grant:** none` or `**Amend-grant:** <granting sentence verbatim, one physical line>`, in the header block (the span between the H1 and the first `##`). Writers place it directly below `**Goal:**` when that line exists, otherwise on the first line after the H1, its blank line, and any `> **Superseded by:**` banner lines; readers never depend on the position. Take a gate approval's granting sentence from the gate's default grant line in `spec-finalization.md`, never the digit. Collapse a prose grant to one physical line before the write: newlines and runs of whitespace become single spaces, wording preserved. The same substitution applies wherever this file quotes the granting sentence in a commit body.
|
|
12
12
|
|
|
13
13
|
**The predicate.** Every reader (gauntlet-resume at entry, this file at each batch boundary) applies it verbatim over the header block; occurrences below the first `##` never count.
|
|
14
14
|
|
|
@@ -169,7 +169,7 @@ reread rule; amend the block before using a changed contract. Legacy specs
|
|
|
169
169
|
without that section retain finish-time rereading. A one-member run has no
|
|
170
170
|
companion artifact or companion aftermath.
|
|
171
171
|
|
|
172
|
-
Aftermath, once per batch, only when at least one item applied (nothing applied -> skip to the commit below). Ledger exists (line 1 `# Ledger - loop engine` in the resolved plan dir) -> skip `plan-writer` and `plan_check`. Reconcile the ledger against the approved spec dispositions: `deviates:`, `deferred:`, or `elsewhere:` -> `cut`, evidence = the disposition; factual or requirement-preserving amendment -> preserve rows; re-bounded `done` row -> `open`, evidence = `reopened by amendment`. Preserve every row's attempts and the ledger's iterations and allowance. Apply evidenced drafted-row text corrections as amend items while preserving row identity; retain the cut/reopen rules above. Ticket text and row add/remove changes remain redraws. Commit spec + ledger together with subject `loop: cut row <n>` for a batch containing only one cut, otherwise `loop: amend` (including mixed batches), carrying the amendment audit body below (including each `granted` record and granting sentence); after the commit, use the driver's next ledger-path refresh to project the new statuses and continue without task-plan aftermath. Keep task-plan `add`/`update`/`init` out of this route. Project `done -> cut` as `complete -> skipped` and a re-bound `done -> open` as `complete -> pending`; count neither as a reopen. During verify without amend permission, stop on a re-bound row with `Stopped: row <n> reopened by amendment during verify`; keep verify active and offer authorization to return that row to ledger implementation or stop. Under amend permission, continue without a second authorization. For the granted continuation or the
|
|
172
|
+
Aftermath, once per batch, only when at least one item applied (nothing applied -> skip to the commit below). Ledger exists (line 1 `# Ledger - loop engine` in the resolved plan dir) -> skip `plan-writer` and `plan_check`. Reconcile the ledger against the approved spec dispositions: `deviates:`, `deferred:`, or `elsewhere:` -> `cut`, evidence = the disposition; factual or requirement-preserving amendment -> preserve rows; re-bounded `done` row -> `open`, evidence = `reopened by amendment`. Preserve every row's attempts and the ledger's iterations and allowance. Apply evidenced drafted-row text corrections as amend items while preserving row identity; retain the cut/reopen rules above. Ticket text and row add/remove changes remain redraws. Commit spec + ledger together with subject `loop: cut row <n>` for a batch containing only one cut, otherwise `loop: amend` (including mixed batches), carrying the amendment audit body below (including each `granted` record and granting sentence); after the commit, use the driver's next ledger-path refresh to project the new statuses and continue without task-plan aftermath. Keep task-plan `add`/`update`/`init` out of this route. Project `done -> cut` as `complete -> skipped` and a re-bound `done -> open` as `complete -> pending`; count neither as a reopen. During verify without amend permission, stop on a re-bound row with `Stopped: row <n> reopened by amendment during verify`; keep verify active and offer authorization to return that row to ledger implementation or stop. Under amend permission, continue without a second authorization. For the granted continuation or the human-authorized return, apply the driver's `## Before each dispatch` boundaries, including exhausted-row rule 2, then apply `## Dispatch` through the driver's `## After the loop` step 3 one-task `tasks` continuation and `## Validate the return` (tuple, refresh, admission, refresh), keeping verify active with no phase reset; close the row on disk, then rerun the step 1 gate before verify continues. Never close it with `plan_tracker update`. No plan yet -> commit the spec; continue. Plan exists -> read `git -C "<abs worktree path>" status --porcelain` (plain jj: `jj -R "<abs worktree path>" diff --summary`); collect the parent's in-flight workflow edits as worktree-relative paths, including the amended spec and staged in-place wave-repair deliverables. Dispatch `plan-writer` per `writing-plans` `## Author the plan` step 3 with an `Amend:` block naming the amended spec sections, an `In-flight:` list of those paths (the parent supplies the set; the child never infers it), and the rule "preserve every task title and wave position the amendment does not touch; edit only affected anchors and tasks", then run that section's steps 5-6 (the parent `plan_check` and its branches).
|
|
173
173
|
|
|
174
174
|
At that return point, classify human-facing outcomes with this table; let writing-plans' first `Findings:` repair run as written.
|
|
175
175
|
|
|
@@ -32,7 +32,7 @@ Immediately after ordered admission and before binding, classify N=1 read-only.
|
|
|
32
32
|
| Observation | Route |
|
|
33
33
|
|---|---|
|
|
34
34
|
| Shape fails | Pass the selected SYNC to provisioning. Continue unchanged through bind, gather, scout, and Rework record. |
|
|
35
|
-
| Shape passes, marker absent | Force `SYNC=merge` for provisioning. Print `spec-only PR without the gate marker - running lint and council`. Provision the one-element admitted PR array through pr-head's checkout, base merge, and Step 4 report with no thread fetch (bypass its `## Fetch unresolved review threads` as on the marked route). Skip ticket binding, context-builder, the PR scout block, and gather; never write a `## Rework record`. Resume at checklist step 4 with the carried spec file at `<worktree>/<path>` as the draft, as a redraw does (recon falls to the questionary); spec-writing overwrites that file at its carried path. Run lint, council, and the gate as for any spec, with
|
|
35
|
+
| Shape passes, marker absent | Force `SYNC=merge` for provisioning. Print `spec-only PR without the gate marker - running lint and council`. Provision the one-element admitted PR array through pr-head's checkout, base merge, and Step 4 report with no thread fetch (bypass its `## Fetch unresolved review threads` as on the marked route). Skip ticket binding, context-builder, the PR scout block, and gather; never write a `## Rework record`. Resume at checklist step 4 with the carried spec file at `<worktree>/<path>` as the draft, as a redraw does (recon falls to the questionary); spec-writing overwrites that file at its carried path. Run lint, council, and the gate as for any spec, with 4 withheld (`Withheld: draft PR - #N already exists`). On approval 1/2 persist `**Engine:**`, `**Amend-grant:**`, and `**PR:** <owner/repo#N>` as a new commit per spec-pr.md's re-gate persistence. |
|
|
36
36
|
| Shape and marker pass | Count carried `### Leg:` blocks under `## Legs` from the same `git show <headRefOid>:<path>` used for the marker, before home provisioning. Force `SYNC=merge`. Zero/one block keeps home-only pr-head checkout/base merge/Step 4. For observed N>1 blocks pass that coordinated marked context to pr-head's home base-sync recovery; malformed blocks missing repo, branch or contract stop naming the block and preserve home. Provision only the one-element admitted PR array, then follow spec-pr.md's re-gate and its coordinated settlement after home's Step 4. Skip binding and all before-gather thread queries. Treat draft and ready PRs equally. |
|
|
37
37
|
|
|
38
38
|
## Relatedness before provisioning
|
|
@@ -137,7 +137,7 @@ If the council path ran, the body is its audit (`Coverage:` when present, then `
|
|
|
137
137
|
|
|
138
138
|
Evaluate the summary in two stages (the **Degrade path** referenced in each is defined just below):
|
|
139
139
|
|
|
140
|
-
Before the summary `Read` below, resolve `gauntlet_setting({ key: "loopEngine" })` once for this gate. Retain `maxIterationsPerRow` (default 4) as `<n>` for
|
|
140
|
+
Before the summary `Read` below, resolve `gauntlet_setting({ key: "loopEngine" })` once for this gate. Retain `maxIterationsPerRow` (default 4) as `<n>` for the loop row's `--allowance=N` default. Render any settings warning as one adjacent line. Stop on an unavailable settings tool; never guess the allowance. Beside this lookup, call `phase_tracker({ action: "status" })` once before the summary `Read`. Retain the numeric percentage from its `Context:` line; treat a missing `Context:` line, `Context: unknown`, or a failed call as unknown and never stop for a missing reading.
|
|
141
141
|
|
|
142
142
|
1. **From the dispatch tool result, before the `Read`.** If the result is **not** an `"Output saved to: <path> (<N> KB, <M> lines)"` reference (an exit-0 save error returns the save error plus a `Full reply preserved at` / `not preserved` pointer, no inline output), or the reference reports under ~500 bytes, or over ~45 KB (the `Read` truncates at 50KB / 2000 lines, so a larger file cannot render whole) - skip the `Read` and take the degrade path. Use the reference's reported figures; do not re-derive them.
|
|
143
143
|
2. **The `Read` itself, as the last content-producing tool call before composing the gate.** `Read` `$SUMMARY_PATH` and paste its contents verbatim immediately after the gate marker. If the `Read` fails, returns 0 bytes, or reports truncation - take the degrade path. The `Read` must be last: pi-condense does not protect a `/tmp` read, so any turn boundary between the `Read` and the render lets the read result be pruned, reproducing the bug.
|
|
@@ -148,8 +148,16 @@ Either way - summary rendered or degraded - then `rm "$SUMMARY_PATH"` (unconditi
|
|
|
148
148
|
|
|
149
149
|
Follow the [first-line rule](menu-layout.md). Paste the summary verbatim, unedited in the template below; use adjacent lines for the `Council:` counts, unresolved ambiguities, and every `Missing from the spec` entry; render the `Scope cuts:` line yourself from the spec's `## Acceptance criteria` section - every `deferred:`, `deviates:`, and `venue:` row, `none` when there is none - never from the summary; the audit itself is shown only on row 3:
|
|
150
150
|
|
|
151
|
+
Choose exactly one rendered row from 1, 2, or 4 as the recommendation. Append `[recommended]` at the end of that row's sentence, never to a flag line or row 3. Set `<recommended-row>` in the first-line marker and the `Recommended:` line to that same number; give a concrete reason after the dash.
|
|
152
|
+
|
|
153
|
+
Decide the recommendation before rendering, without printing the deliberation. For a numeric context reading strictly above 25, when row 4 is rendered, recommend row 4 before assessing acceptance rows. Compare the reading as a number; never floor it: 25.0 does not trigger this rule; 25.1 and 26.0 do. Use this reason line, substituting the observed percentage for `<P>` and keeping the literal `<N>` until publication: ``Recommended: 4 - context is at <P>% of the window; start a fresh session and run `/skill:brainstorming #<N>` on the draft PR there, which is less prone to hallucination.`` Outside the create-only retry view, restrict the recommendation to rendered row 1 or 2 for `Context: unknown`, a numeric reading of 25 or lower, or a withheld row 4.
|
|
154
|
+
|
|
155
|
+
When row 4 is not recommended and the committed spec has zero acceptance rows, recommend row 1 with this reason: `Recommended: 1 - the spec has no acceptance rows, so the loop engine has nothing to iterate.`
|
|
156
|
+
|
|
157
|
+
When row 4 is not recommended and acceptance rows exist, assess the committed spec's `## Acceptance criteria` in the main loop, without a tool or subagent. Assess only `in-scope` and `venue:` rows; skip `deviates:`, `deferred:`, and `elsewhere:` rows. Treat two or more separately checkable outcomes in one row as bundled. Treat several facets of one observation (the fields of one rendered line, a value and where it is stored) as one outcome. Recommend row 1 for a bundled row. Use the first bundled row in section order, with its one-based index among all rows, in this reason: `Recommended: 1 - row <k> "<row text, first 60 chars>" commits to <outcome>, <outcome>[, ...]; a plan splits it into tasks.` When none of the assessed rows is bundled, recommend row 2 with this reason: `Recommended: 2 - no row bundles more than one outcome.`
|
|
158
|
+
|
|
151
159
|
```
|
|
152
|
-
gauntlet: gate=brainstorming/user-review-gate
|
|
160
|
+
gauntlet: gate=brainstorming/user-review-gate recommended=<recommended-row>
|
|
153
161
|
<spec-only summary read back from the temp file - pasted verbatim, unedited>
|
|
154
162
|
|
|
155
163
|
Spec written and committed to <project>/doc/specs/<filename>.md (worktree: <path>).
|
|
@@ -166,20 +174,29 @@ Council: <A> applied, <D> deferred, <R> rejected
|
|
|
166
174
|
<unresolved ambiguities; every `Missing from the spec` entry from the summary>
|
|
167
175
|
New predecessor candidates at spec-writing: <path> (<title>), ... - index rows are a hint; code is the source and an absent row proves nothing.
|
|
168
176
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
177
|
+
Pick one:
|
|
178
|
+
1 - plan engine: write a task plan, then implement it in reviewed waves.
|
|
179
|
+
- `--amends-stop`: stop for my review before a blocked task changes the spec's scope, acceptance criteria, or contracts (default: apply it and list it at the finish gate; a redraw always stops).
|
|
180
|
+
- `--fund-rounds=N`: fund up to N extra fix rounds per task after its escalated round (default: stop and ask there).
|
|
181
|
+
|
|
182
|
+
2 - loop engine: skip the plan and iterate a fresh implementer over the acceptance criteria.
|
|
183
|
+
- `--amends-stop`: stop for my review before the loop rewords or cuts a row it is stuck on (default: apply it and list it at the finish gate; a redraw always stops).
|
|
184
|
+
- `--allowance=N`: attempts per row before the loop stops and asks (default: <n>).
|
|
185
|
+
|
|
186
|
+
3 - council explanation: show the council audit, then return to this gate without approving.
|
|
187
|
+
|
|
188
|
+
4 - draft PR: approve the spec's content only and publish it as a draft PR; to continue, start a fresh session and run `/skill:brainstorming #<N>` there.
|
|
189
|
+
|
|
190
|
+
Recommended: <recommended-row> - <reason>
|
|
176
191
|
|
|
177
192
|
Or tell me what to change in the spec, or say "revert applied council edit <X>" to undo a specific applied edit.
|
|
178
193
|
```
|
|
179
194
|
|
|
180
|
-
For zero `- [ ]` rows under `## Acceptance criteria`,
|
|
195
|
+
For zero `- [ ]` rows under `## Acceptance criteria`, omit row 2 and all its flag lines, including `--allowance=N`; render rows 1, 3, 4 (PR subject: 1, 3) and explain: "Loop engine unavailable: this spec has no acceptance-criteria rows." The only legal zero-row body is `none - ticket not fetched (<reason>)`; retain its paste-rows affordance.
|
|
181
196
|
|
|
182
|
-
|
|
197
|
+
Apply the withholding rules independently: on the worker path or when the council aborted before an audit existed, omit row 3 and the `Council:` line; combine this with the zero-row and PR-subject omissions and never renumber the remaining rows. Do not invent a council audit.
|
|
198
|
+
|
|
199
|
+
On every PR subject omit row 4 and print `Withheld: draft PR - #N already exists` under the list, reusing finishing's withheld-row layout; a hidden 4 gets the clarifying question naming rendered choices. Read [spec-pr.md](spec-pr.md) for row-4 reply decoding, publication, and marked-PR re-gating; its published-branch persistence replaces the local amend recipe below on the marked re-gate and the unmarked spec-only route only; a rework PR subject keeps the amend recipe.
|
|
183
200
|
|
|
184
201
|
Render the drafted-only block in the template from the applied spec section, never from the summarizer: copy every row and disposition verbatim. Include it for a fetched ticket without ACs; omit it for ticket-row provenance. Approval ratifies these rows at this gate, with no pre-gate acceptance stop. On reply `3`, keep the block reused verbatim with the briefing; on a row-touching change request, render from the recommitted section; on redraw, render from the re-drafted section.
|
|
185
202
|
|
|
@@ -187,30 +204,45 @@ If you believe the summary needs correcting, do **not** silently rewrite it - re
|
|
|
187
204
|
|
|
188
205
|
**Revert valve.** "Revert applied council edit X" is a normal change request: revise the spec to undo edit X, re-dispatch the summarizer with a **fresh** temp path (per the re-dispatch rule below), and re-present the gate. This is cheap here - the spec is not yet plan- or code-bearing.
|
|
189
206
|
|
|
190
|
-
Wait for the user.
|
|
207
|
+
Wait for the user. Resolve a rendered row from its digit or label; use the recommended row for `approve` and plain approval prose as defined below. Parse whitespace-separated flags after a digit, label, or `approve` in any order, each at most once.
|
|
208
|
+
|
|
209
|
+
**Rejected replies.** Apply every check below before plain approval and before change requests. For a rejected reply, make no file or commit changes, state that the gate is waiting, and end with exactly one clarifying question containing the listed content and a question mark; a second invalid reply leaves the gate waiting too. Do not infer a grant or turn worded amendment or budget intent into a spec edit.
|
|
210
|
+
|
|
211
|
+
| Rejected reply | Question content |
|
|
212
|
+
|---|---|
|
|
213
|
+
| `--fund-rounds=N` on row 2, `--allowance=N` on row 1, or any flag on row 3 or 4; apply equally after a digit, label, or `approve` | Quote the flag and name the engine row that accepts it (`--amends-stop` belongs to rows 1 and 2). |
|
|
214
|
+
| amendment, grant, or budget intent in words beside a digit, label, or approval prose (`approve, stop on amends`) | Quote the words and name the matching flag: `--amends-stop`, `--fund-rounds=N`, or `--allowance=N`; for granting words, say auto-apply is the default and name `--amends-stop` as the opt-out. |
|
|
215
|
+
| N not matching `[1-9][0-9]*` or not a positive safe integer, a value flag missing `=N`, a repeated flag, or an unknown `--` token | Quote the offending token. |
|
|
216
|
+
| Old suffix forms `; allowance N`, `, allowance N`, `; fund N fix rounds`, `, fund N fix rounds`, or `N more fix rounds`, beside a digit, label, or `approve` | Quote the suffix and name the matching flag, `--allowance=N` or `--fund-rounds=N`. |
|
|
217
|
+
| A flag with no row digit, row label, or `approve`; a budget token alone | Ask for a rendered row. |
|
|
218
|
+
| `5`, `6`, another out-of-range digit, or a withheld row's digit or label | Name the rendered rows; never remap the selection. |
|
|
219
|
+
|
|
220
|
+
For bare `approve`, resolve the recommended rendered row (1, 2, or 4) from the just-rendered gate; never recompute it from newer context or acceptance rows. Print `Taking "approve" as option <n> - <label>` with that row's number and label before applying its action, exactly as for its bare digit. Apply this same mapping and literal echo to approval prose that names no row and carries no amendment, grant, or budget wording (for example, `approved, go ahead`).
|
|
221
|
+
|
|
222
|
+
After these checks, use the accepted mapping below. Accept `--fund-rounds=N` on row 1 with N matching `[1-9][0-9]*`; without `--amends-stop`, append `; fund N fix rounds` to `G` without removing the default amend permission. Keep `G` verbatim, including its final period (`approval.; fund N fix rounds`). On row 2, accept one `--allowance=N` flag with N matching `[1-9][0-9]*` and a positive safe integer. Carry the accepted value to loop entry and persist it only in the ledger, not in the spec or settings.
|
|
191
223
|
|
|
192
224
|
| Reply | Action / written value |
|
|
193
225
|
|---|---|
|
|
194
|
-
| bare `
|
|
195
|
-
| `
|
|
196
|
-
| `
|
|
197
|
-
|
|
|
198
|
-
| `
|
|
199
|
-
| `
|
|
200
|
-
|
|
|
201
|
-
|
|
202
|
-
|
|
226
|
+
| bare `1` | approve; persist `G`; engine `waves` |
|
|
227
|
+
| `1 --amends-stop` | approve; persist `none`; engine `waves` |
|
|
228
|
+
| bare `2` | approve; persist `G`; engine `loop`; use the settings allowance |
|
|
229
|
+
| `2 --amends-stop` | approve; persist `none`; engine `loop`; use the settings allowance |
|
|
230
|
+
| `1 --fund-rounds=N` | approve; persist `G; fund N fix rounds`; engine `waves` |
|
|
231
|
+
| `1 --amends-stop --fund-rounds=N` | approve; persist `fund N fix rounds`; engine `waves` |
|
|
232
|
+
| `2 --allowance=N` | approve; persist `G`; engine `loop`; carry `run allowance: N` to ledger seeding |
|
|
233
|
+
|
|
234
|
+
Default grant (`G`): `every later spec amendment in this flow (corrected facts, paths, verification lines, and scope, acceptance-criteria, or public-contract edits alike) applies without asking; only a redraw (changed problem statement, component added, removed, or re-bounded) still stops for you, and the grant never stands in for a spec approval.`
|
|
203
235
|
|
|
204
|
-
For every value to persist, read [Standing grants](amendment-surface.md#standing-grants) and run Value decoding. Decode before `edit` or `--amend`; never persist a malformed token. Use the decoded table value in the approval persistence below, including waves budget-only approvals. Strip only an accepted
|
|
236
|
+
For every value to persist, read [Standing grants](amendment-surface.md#standing-grants) and run Value decoding. Decode before `edit` or `--amend`; never persist a malformed token. Use the decoded table value in the approval persistence below, including waves budget-only approvals. Apply this opt-out rule only without funding: For `--amends-stop` approvals, persist `none` rather than the default grant and keep the selected row's engine. With both `--amends-stop` and `--fund-rounds=N` on row 1, persist only `fund N fix rounds`, without amend permission, and keep engine `waves`. Strip only an accepted `--allowance=N` flag before decoding the grant; keep the run allowance separate from `**Amend-grant:**`. In persistence narration, quote the exact resulting `**Amend-grant:**` value in full, including any funding suffix; never substitute an option name or "option-2 description plus suffix" for the persisted text.
|
|
205
237
|
|
|
206
|
-
On a change request (including a revert), revise the spec and re-present - mint a **fresh** temp path for the re-dispatched summarizer (never reuse a prior round's path, so stale content can never be mistaken for the new summary). On `3` or its label alone: print the audit verbatim from `git -C <abs worktree path> show -s --format=%b HEAD` (never from a held tool result; the body survives the grant's `--amend --no-edit`), then re-present the same gate - the briefing text of the gate message just rendered, reused verbatim (no summarizer re-dispatch, no read of the removed `$SUMMARY_PATH`; if that text is no longer in context, the one-line degrade note takes its place), the `Council:` line, the adjacent lines, the rendered option rows; nothing in the spec or the commit changes. `3` plus a change request is a change request. `3` plus `1`/`2`/`4
|
|
238
|
+
On a change request (including a revert), revise the spec and re-present - mint a **fresh** temp path for the re-dispatched summarizer (never reuse a prior round's path, so stale content can never be mistaken for the new summary). On `3` or its label alone: print the audit verbatim from `git -C <abs worktree path> show -s --format=%b HEAD` (never from a held tool result; the body survives the grant's `--amend --no-edit`), then re-present the same gate - the briefing text of the gate message just rendered, reused verbatim (no summarizer re-dispatch, no read of the removed `$SUMMARY_PATH`; if that text is no longer in context, the one-line degrade note takes its place), the `Council:` line, the adjacent lines, the rendered option rows, flag lines, tag, marker, and `Recommended:` line verbatim; make no new status or settings call and do not recompute the recommendation. Record no approval; nothing in the spec or the commit changes. `3` plus a change request is a change request. `3` plus `1`/`2`/`4` prints and re-presents, and the approval is read only from a clean `1`/`2`/`4` on the re-presented gate - a reply carrying `3` never grants. A gate-round recommit (change request or revert) re-runs the same heredoc commit with the audit as its body, so HEAD always carries it; on a revert of edit X, move X's `Applied:` line to `Rejected:` with `-> reverted at gate` and recompute the `Council:` counts from the revised audit. On a validated implementation approval, first read [Standing grants](amendment-surface.md#standing-grants) (stop if unreadable). On every implementation approval (1/2), `edit` the spec's `**Amend-grant:**` value to the decoded table value for every reply. Write exactly one `**Engine:** loop` for 2 or `**Engine:** waves` for 1 directly below `**Amend-grant:**` in the header block (readers: absent -> `waves`). Then `git -C <abs worktree path> add -- <spec path>` and `git -C <abs worktree path> commit --amend --no-edit -q`, keeping the council-audit body; confirm `git -C <abs worktree path> show HEAD:<spec path>` contains both fields with the selected values and satisfies the grant predicate and Value decoding. A reply that mixes approval with a change request ("2 but rename the section") is a change request: revise, re-present, and read the grant only from the reply to the re-presented gate. If the amend or the HEAD check fails, stop and report; never proceed as granted. The plan and execution mode are mechanical derivatives, so the only human gate here is spec approval itself. Don't land the spec on `main`; it stays in the worktree and ships in the same squash commit as the implementation.
|
|
207
239
|
|
|
208
240
|
Post-approval changes follow [Amending an approved spec](../SKILL.md#amending-an-approved-spec).
|
|
209
241
|
|
|
210
|
-
After implementation approval (1/2
|
|
242
|
+
After implementation approval (1/2), mark the brainstorm phase complete:
|
|
211
243
|
|
|
212
244
|
```
|
|
213
245
|
phase_tracker({ action: "complete", phase: "brainstorm" })
|
|
214
246
|
```
|
|
215
247
|
|
|
216
|
-
Then invoke `/skill:writing-plans` on 1
|
|
248
|
+
Then invoke `/skill:writing-plans` on 1 or `/skill:loop-implementation` on 2 immediately, with no further prompt. For a bare loop approval, state that the driver uses the settings allowance without writing it to the spec or settings, and skips plan with reason `loop engine` instead of invoking writing-plans. For an accepted `--allowance=N` flag on row 2, print exactly one line `run allowance: <n>` immediately before invoking `/skill:loop-implementation`; omit that line on a bare approval. Render the carrier as a standalone plain-text line, even when narrating the handoff; keep it in the approving turn only, never in the spec or settings.
|
|
@@ -6,11 +6,11 @@ Resolve home `gauntlet_setting({ key: "flowGuards" })` and use its `specDirs`. F
|
|
|
6
6
|
|
|
7
7
|
Keep shape separate from approval. Read the added spec with `git show <head>:<spec path>`; match `^\*\*Engine:\*\*[ \t]+deferred[ \t]*$` only in the header before the first `## `. Use that marker plus shape for re-gating. Use shape alone for publication. Ignore draft status, labels, PR body, telemetry, and audit presence as classification proof. Route a list of N>1 PRs through rework; count carried Legs separately.
|
|
8
8
|
|
|
9
|
-
## Publish
|
|
9
|
+
## Publish row 4
|
|
10
10
|
|
|
11
|
-
Decode the reply before writes. A hidden `
|
|
11
|
+
Decode the reply before writes using [User Review Gate](spec-finalization.md#user-review-gate)'s rejected-reply checks. A hidden `4` gets the clarifying question naming rendered choices. Any flag on `4` is malformed: re-present, write nothing. `3` plus `4` prints the audit and re-presents without approval; `4` plus a change request revises and re-presents.
|
|
12
12
|
|
|
13
|
-
On clean `
|
|
13
|
+
On clean `4`, edit home only: `**Amend-grant:** none` and exactly one `**Engine:** deferred` directly below it. Row 4 never grants. Stage the spec with `git -C <worktree> add -- <spec path>`, then `git -C <worktree> commit --amend --no-edit -q`; verify both lines through `git -C <worktree> show HEAD:<spec path>`. Stop on failure.
|
|
14
14
|
|
|
15
15
|
Read the committed home spec's `## Legs` in [legs.md](legs.md) order. Carry Worktree First paths; treat recorded repo, branch, contract, spec-dir, home and create as authoritative. Keep the one-block and legacy recipe below verbatim (one push/PR/cleanup, no companion prefixes). For N>1 run the coordinated passes below instead of executing the home recipe immediately: they invoke its preflight last, then its push/create after companion publication, and replace its output/cleanup ordering. Keep companion files unchanged.
|
|
16
16
|
|
|
@@ -22,7 +22,7 @@ git -C <worktree> fetch origin "$DEFAULT"
|
|
|
22
22
|
git -C <worktree> diff --name-status origin/$DEFAULT...HEAD
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
Prove the shared predicate against `origin/$DEFAULT` before pushing. Stop on command errors. On invalid shape print the offending name-status lines and `origin/$DEFAULT`, retain the amended spec and checkout, and redraw with `Withheld: draft PR - diff against origin/$DEFAULT is not spec-only (<paths>)` replacing
|
|
25
|
+
Prove the shared predicate against `origin/$DEFAULT` before pushing. Stop on command errors. On invalid shape print the offending name-status lines and `origin/$DEFAULT`, retain the amended spec and checkout, and redraw with `Withheld: draft PR - diff against origin/$DEFAULT is not spec-only (<paths>)` replacing 4. Keep implementation approvals available.
|
|
26
26
|
|
|
27
27
|
Push, then create with explicit head/base and the spec H1 as title. Pass the summary verbatim through the quoted heredoc shown below, including its literal delimiter in narrated commands. Run gh against the worktree repository:
|
|
28
28
|
|
|
@@ -35,12 +35,23 @@ EOF
|
|
|
35
35
|
|
|
36
36
|
| Observation | Action |
|
|
37
37
|
|---|---|
|
|
38
|
-
| Push rejected | Print git output; retain amended spec and checkout; re-present with
|
|
39
|
-
| Create fails after push | Print error and pushed branch. Keep brainstorm incomplete and checkout intact.
|
|
40
|
-
| Retry
|
|
41
|
-
| Create succeeds | Print URL before completing brainstorm; then perform ownership-based cleanup below. |
|
|
38
|
+
| Push rejected | Print git output; retain amended spec and checkout; re-present with 4 retryable. |
|
|
39
|
+
| Create fails after push | Print error and pushed branch. Keep brainstorm incomplete and checkout intact. Render the create-only retry view below. |
|
|
40
|
+
| Retry 4 after published handoff | Refresh origin's branch head; require `origin/<branch>` == HEAD. On mismatch print both full SHAs and stop. On equality rerun create only, no push, no amend. |
|
|
41
|
+
| Create succeeds | Print URL, then ``Continue: start a fresh session, then run `/skill:brainstorming #<N>`.`` with the returned PR number before completing brainstorm; then perform ownership-based cleanup below. |
|
|
42
|
+
|
|
43
|
+
Render the create-only retry view per [menu-layout.md](menu-layout.md) at every context reading, including 25% or lower and `Context: unknown`:
|
|
44
|
+
|
|
45
|
+
```text
|
|
46
|
+
gauntlet: gate=brainstorming/user-review-gate recommended=4
|
|
47
|
+
4 - retry opening the draft PR [recommended]
|
|
48
|
+
Withheld: implementation approvals - the handoff commit is published; an approval would amend it
|
|
49
|
+
Recommended: 4 - the handoff commit is published; retrying the draft PR is the only action left.
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Accept `4` or its label as the create-only retry. For bare `approve`, first print `Taking "approve" as option 4 - retry opening the draft PR`, then take the same retry with no amend and no push. Reject every other reply with one clarifying question naming rendered row 4 and write nothing; engine replies `1` and `2` remain unavailable.
|
|
42
53
|
|
|
43
|
-
After URL output call `phase_tracker({ action: "complete", phase: "brainstorm" })`, then run [Draft-PR cleanup](#draft-pr-cleanup) once for home. Start no plan or loop, produce no handoff brief, and leave telemetry unchanged.
|
|
54
|
+
After URL and Continue output call `phase_tracker({ action: "complete", phase: "brainstorm" })`, then run [Draft-PR cleanup](#draft-pr-cleanup) once for home. Start no plan or loop, produce no handoff brief, and leave telemetry unchanged.
|
|
44
55
|
|
|
45
56
|
### Draft-PR cleanup
|
|
46
57
|
|
|
@@ -69,7 +80,7 @@ Finish preflight for every companion in declared order, then home, before any pu
|
|
|
69
80
|
|
|
70
81
|
1. Resolve each companion's default with `DEFAULT=$(gh repo view <owner/name> --json defaultBranchRef -q .defaultBranchRef.name)` (positional repo, not `-R`); require nonempty. Run `git -C <companion worktree> fetch origin "$DEFAULT"` and `git -C <companion worktree> diff --name-status origin/$DEFAULT...HEAD`. Apply the shared predicate with that member's own dirs and recorded added file.
|
|
71
82
|
2. Discover remote publication with `git -C <companion worktree> ls-remote --exit-code --heads origin <branch>`. Exit 2 means absent: attempt no branch fetch. Exit 0 means present: fetch `origin <branch>`, then read full `origin/<branch>` and HEAD SHAs for publication. Any other exit is a command failure, never absence; ignore stale tracking refs as discovery proof.
|
|
72
|
-
3. Run home's default/fetch/shape recipe last. On any shape failure print the member, offending name-status lines and `origin/<default>`, retain every amended spec and checkout, and redraw with `Withheld: draft PR - <repo> diff against origin/<default> is not spec-only (<paths>)` replacing
|
|
83
|
+
3. Run home's default/fetch/shape recipe last. On any shape failure print the member, offending name-status lines and `origin/<default>`, retain every amended spec and checkout, and redraw with `Withheld: draft PR - <repo> diff against origin/<default> is not spec-only (<paths>)` replacing 4; keep implementation approvals. On gh/default/fetch/ls-remote failure stop naming member and command output. Nothing has been pushed on either preflight failure.
|
|
73
84
|
|
|
74
85
|
Publish companions in declared order from the preflight observations:
|
|
75
86
|
|
|
@@ -77,8 +88,8 @@ Publish companions in declared order from the preflight observations:
|
|
|
77
88
|
|---|---|
|
|
78
89
|
| Absent | `git -C <companion worktree> push -u origin <branch>`; record published member. |
|
|
79
90
|
| Present, full remote SHA equals HEAD | Skip with `<repo>: already published`; include it in the published inventory. |
|
|
80
|
-
| Present, different full SHA | Print repo, both full SHAs and already-published members; retain every checkout and list paths; re-present
|
|
81
|
-
| Push rejected | Print member and git output, already-published members and retained paths; re-present
|
|
91
|
+
| Present, different full SHA | Print repo, both full SHAs and already-published members; retain every checkout and list paths; re-present 4 retryable after by-hand resolution. Never force or reconcile. |
|
|
92
|
+
| Push rejected | Print member and git output, already-published members and retained paths; re-present 4 retryable. Retry both passes; equality skips completed companions. |
|
|
82
93
|
|
|
83
94
|
Then run home's existing push/create recipe. Home push/create failures keep its failure rows and also list published companions; never roll back. After home create failure freeze the published handoff commit: the create-only retry above does not amend or push any member or rerun publication passes. On success print `pushed: <repo> origin/<branch>` for each companion before the single home URL, then complete brainstorm.
|
|
84
95
|
|
|
@@ -105,7 +116,7 @@ Compare the recorded contract before provisioning:
|
|
|
105
116
|
|
|
106
117
|
For a script-placed leg with an unwanted recorded `home:`, require a user-approved amendment dropping that line from both the home block and companion file through their existing reconciliation path. Rewrite nothing automatically.
|
|
107
118
|
|
|
108
|
-
At gate readiness render each observed Step 4 report in full, home first then companions in recorded order: `Worktree ready at <path>`, `Branch: <branch>`, Base and Base SHA, and the observed `merge:` outcome. Include each returned `create: override skipped (contains -b)` and `Base sync recovered:` line; preserve home's PR and Pre-rework head lines only on home. Inside the rendered gate block, explicitly print `Worktrees: <home repo> <home path>, <companion repo> <companion path>, ...` naming every Worktree First path, home first then each companion in recorded order, never home alone. Render these values, not a promise to include them. Offer the ordinary AC-dependent 1/2
|
|
119
|
+
At gate readiness render each observed Step 4 report in full, home first then companions in recorded order: `Worktree ready at <path>`, `Branch: <branch>`, Base and Base SHA, and the observed `merge:` outcome. Include each returned `create: override skipped (contains -b)` and `Base sync recovered:` line; preserve home's PR and Pre-rework head lines only on home. Inside the rendered gate block, explicitly print `Worktrees: <home repo> <home path>, <companion repo> <companion path>, ...` naming every Worktree First path, home first then each companion in recorded order, never home alone. Render these values, not a promise to include them. Offer the ordinary AC-dependent 1/2 choices and optional pinned audit 3 below, and `Withheld: draft PR - #N already exists`. Keep ordinary pinned-audit and approval persistence below; no companion approval record or second council.
|
|
109
120
|
|
|
110
121
|
## Re-gate a marked spec PR
|
|
111
122
|
|
|
@@ -124,8 +135,8 @@ git -C <worktree> show -s --format=%b "$AUDIT_SHA"
|
|
|
124
135
|
|
|
125
136
|
Recognize an audit only with all `Applied:`, `Deferred:`, and `Rejected:` labels. A drafted-AC repair line alone is not an audit. Count Council from the pinned body; offer row 3 only with that audit and read that same body on 3, never HEAD. Audit absence does not block re-gating.
|
|
126
137
|
|
|
127
|
-
Reuse [User Review Gate](spec-finalization.md#user-review-gate)'s summarizer dispatch, fresh temp path, last content-producing Read, verbatim render, degraded path, and unconditional temp cleanup, but skip its unconditional initial spec commit. Render Scope cuts and drafted rows from the carried spec. Offer 1/2
|
|
138
|
+
Reuse [User Review Gate](spec-finalization.md#user-review-gate)'s summarizer dispatch, fresh temp path, settings/context lookup, recommendation, last content-producing Read, verbatim render, degraded path, and unconditional temp cleanup, but skip its unconditional initial spec commit. Render Scope cuts and drafted rows from the carried spec. Offer 1/2 and optional 3; with zero AC rows omit 2 and its flags and explain `Loop engine unavailable: this spec has no acceptance-criteria rows.` Withhold 4 with `Withheld: draft PR - #N already exists`; clarify a 4 reply by naming rendered choices.
|
|
128
139
|
|
|
129
140
|
For a change request, revise and stage the spec and reconciled banners; make a new commit without the old audit body (no new council ran). For coordinated changes touching Problem, shared Design, Errors and edge cases, Out of scope, companion-binding clauses or a Leg block, rewrite and commit affected companion files in their live worktrees per [legs.md](legs.md) before re-dispatching the summarizer with a fresh temp path and re-presenting. Complete the amendment only when carried parts agree; infer no second council or approval.
|
|
130
141
|
|
|
131
|
-
For approval 1/2
|
|
142
|
+
For approval 1/2 with their accepted flags, persist on home only; leave companion files untouched. Apply the ordinary gate's rejected-reply checks and accepted mapping before any write. Replace deferred with `waves` for 1 or `loop` for 2, write the decoded `**Amend-grant:**`, and write exactly one `**PR:** <owner/repo#N>` directly below Engine, lowercasing owner/repo parsed from the admitted PR URL. Stage and make a new commit `spec: select engine and grant for PR #N`; never amend a published commit. Verify all three fields through `git show HEAD:<spec path>` before brainstorm completion and the selected writing-plans/loop-implementation chain. For an accepted `--allowance=N`, print `run allowance: N` on its own line immediately before invoking loop-implementation, even in a narrated approval trace; do not put the carrier in a table or replace it with a promise to print it. Keep the allowance out of the spec and settings. Stop on persistence or verification failure. Apply this same new-commit persistence to the unmarked route's gate approval (1/2 with their accepted flags), never `--amend`.
|
|
@@ -84,7 +84,7 @@ Apply the first-line grammar in [menu-layout](../brainstorming/reference/menu-la
|
|
|
84
84
|
- No phase `in_progress` -> append nothing; say the brief is a plain handoff.
|
|
85
85
|
- A phase `in_progress` (verify or ship included - resume stops at verify on its own)
|
|
86
86
|
-> append the process-state section exactly as `## Producers` in
|
|
87
|
-
`reference/brief-contract.md` lays it out:
|
|
87
|
+
`reference/brief-contract.md` lays it out: drop exactly the last line of the phase status when it starts with `Context: `, then copy the rest and the full plan status verbatim
|
|
88
88
|
(`No plan active.` verbatim when there is no plan), the contract's artifact-specific fields, and the gate-history line. Recognize the loop alternative by ledger line 1; read the ledger from the run worktree for its durable last decision. Read the run worktree's spec; when it carries `## Rework record`, copy every top-level PR identity (without the title) and its full pre-rework head, home first in record order, into the optional fields in the contract's producer layout; copy the optional top-level rework base after the pairs as the contract specifies. Without that record, use the ordinary layout. For multiple members, read `reference/brief-contract.md` "Coordinated brief grammar" and append its ordered member snapshot, including missing trees and existing receipt paths, in that layout. Keep the core snapshot home-bound. Use only the contract's grammar; write no second state file. Append with a single
|
|
89
89
|
`cat >> "<brief path>" <<'EOF' ... EOF` whose body is that block.
|
|
90
90
|
- Re-read the file tail and confirm it ends with the gate-history line from the
|
|
@@ -48,9 +48,11 @@ inline. `## Repo state` is matched by prefix: `## Repo state` or
|
|
|
48
48
|
## Producers
|
|
49
49
|
|
|
50
50
|
`gauntlet-handoff` is the only writer of `## Process state`; it appends to the file
|
|
51
|
-
cohort's `handoff` skill wrote, which ends at `## Skills loaded`.
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
cohort's `handoff` skill wrote, which ends at `## Skills loaded`. Drop exactly the last
|
|
52
|
+
line of the `phase_tracker status` output when it starts with `Context: `; copy the
|
|
53
|
+
rest verbatim. Layout, byte-exact: one blank line, the heading on its own line, a
|
|
54
|
+
blank line, that phase status, a blank line, the `plan_tracker status` output
|
|
55
|
+
verbatim, a blank line,
|
|
54
56
|
`Active task: <name|none>`, then, only for a PR subject, one or more consecutive
|
|
55
57
|
`PR: <owner/repo#N>` / `Pre-rework head: <40-char sha>` pairs, one per record group,
|
|
56
58
|
home first, in record order, then optional single `Rework base: <40-char sha>` after all PR pairs, then the optional coordinated block below, then the gate-history line after the last pair, rework-base line, or block -
|
|
@@ -188,7 +190,7 @@ a plan added after base pairs with it by basename. Zero specs -> stop; more than
|
|
|
188
190
|
human picks. The consumer carries this path to its entry check 6 and its post-restore
|
|
189
191
|
announcement without re-resolving it.
|
|
190
192
|
|
|
191
|
-
Honor SKILL.md entry check 6's deferred stop before any process-state arming call below; carry the resolved spec path without re-discovery. For brainstorm-stage briefs, resolve any existing spec through these candidate rules and run entry check 6's deferred-header admission before `start brainstorm`; with zero specs, restore brainstorm without a spec. Keep grant decoding exempt for this stage. A handoff after
|
|
193
|
+
Honor SKILL.md entry check 6's deferred stop before any process-state arming call below; carry the resolved spec path without re-discovery. For brainstorm-stage briefs, resolve any existing spec through these candidate rules and run entry check 6's deferred-header admission before `start brainstorm`; with zero specs, restore brainstorm without a spec. Keep grant decoding exempt for this stage. A handoff after row 4's push succeeded but PR creation failed still has brainstorm in_progress; its deferred header stops restoration, not the ordinary gate.
|
|
192
194
|
|
|
193
195
|
| Active | Calls, in order |
|
|
194
196
|
|---|---|
|
|
@@ -23,7 +23,7 @@ At seed and at an authorized restore, before entering the dispatch loop, read th
|
|
|
23
23
|
At seed and at an authorized restore, when the held membership has more than one leg, read `reference/coordinated-legs.md` IN FULL now with read at its absolute path; stop on an unreadable reference naming its path, never reconstruct it. On fresh entry apply its `## Entry` section at step 4 instead of the home-only skeleton below, using step 4's resolved allowance seed value. On a restore apply its `## Resume` section before the dirty-tree stop and before any pending recovery. Keep legacy and single-member ledger bytes unchanged, with no coordinated metadata.
|
|
24
24
|
|
|
25
25
|
3. Call `phase_tracker({ action: "skip", phase: "plan", reason: "loop engine" })`.
|
|
26
|
-
4. Require a clean named-branch implementation worktree. With dirty status and no `pending:` tuple, take ## Human stop before writing the ledger. Read the literal `run allowance: <n>` line from the invoking approval turn: it carries the approved
|
|
26
|
+
4. Require a clean named-branch implementation worktree. With dirty status and no `pending:` tuple, take ## Human stop before writing the ledger. Read the literal `run allowance: <n>` line from the invoking approval turn: it carries the approved `--allowance=N` flag's value. Use that value over step 1's setting; with no carrier use `maxIterationsPerRow`. Print `allowance: <n> (reply)` or `allowance: <n> (setting)` with the seeded header. Ignore the carrier once a ledger exists; resume uses its header only. Write `<resolved plan dir>/<spec stem>-ledger.md`. Use this grammar with literal values, not placeholders:
|
|
27
27
|
|
|
28
28
|
```markdown
|
|
29
29
|
# Ledger - loop engine
|
|
@@ -63,7 +63,7 @@ Read the ledger and require `allowance:` and no `cap:` before the ordered table,
|
|
|
63
63
|
| Order | Observed state | Action |
|
|
64
64
|
|---|---|---|
|
|
65
65
|
| 1 | No `open` or `failed` row | Refresh; require implement complete; continue at ## After the loop step 0. All-cut and baseline-complete ledgers exit here. |
|
|
66
|
-
| 2 | Unresolved row attempts >= effective allowance | Human stop
|
|
66
|
+
| 2 | Unresolved row attempts >= effective allowance | Human stop with or without amend permission. Exempt `done` and `cut`. |
|
|
67
67
|
| 3 | Last two child row commits for the same row changed no file outside the ledger and no row status, or two consecutive validation misses on that row | Set the hint for that row: `the last two attempts changed nothing outside the ledger` for empty-child stagnation, or `two returns broke the contract: <concrete miss from the last repair evidence>` for validation misses; continue to rule 4. |
|
|
68
68
|
| 4 | Dispatch allowed | Select target by the priority below, then apply the escalation threshold check. |
|
|
69
69
|
|
|
@@ -75,7 +75,7 @@ Use the held decoded amendment grant for amendment choices only; ignore its wave
|
|
|
75
75
|
|
|
76
76
|
Select `seed` until a validated `loop: seed evidence` commit with its `row 0 done` decision survives on the branch, independently of `iterations`; before any seed dispatch apply ## Validate the return's seed count instead of rule 3's row windows. Otherwise select the still-unresolved human retry target, then the still-failed row named by the previous decision, then first failed row, then first open row. Read seed survival from the ledger at HEAD and the matching validated commit, not from evidence completeness. Never re-seed a validated partial seed to fill empty evidence cells. Use the latest admitted return's target decision for targeting and the child's `previous decision:` input, never an extra's line; skip allowance-grant and legacy grant history while retaining the entire Decisions section. Durable status beats a decision's suggestion. Keep the retry hint only for its target.
|
|
77
77
|
|
|
78
|
-
For a numbered target with no durable `row <n> escalated` decision, compute `threshold = min(escalateAfter, effective allowance - 1)` from the held `escalateAfter` and the row's effective allowance. When the row's pre-dispatch attempts >= threshold, make this dispatch the escalated round: resolve `gauntlet_setting({ key: "escalationLoop" })`
|
|
78
|
+
For a numbered target with no durable `row <n> escalated` decision, compute `threshold = min(escalateAfter, effective allowance - 1)` from the held `escalateAfter` and the row's effective allowance. When the row's pre-dispatch attempts >= threshold, make this dispatch the escalated round: resolve `gauntlet_setting({ key: "escalationLoop" })` with or without amend permission. Use the returned non-empty `implModel` string, including the resolver's main-loop model fallback when the setting is unset or malformed. With the settings tool unavailable or `implModel` undefined (neither a configured model nor a main-loop model), stop before dispatch with `Problem: escalationLoop.implModel unavailable`; write no escalation decision and leave attempts unchanged. Never substitute a default-model attempt for that stop.
|
|
79
79
|
|
|
80
80
|
With the resolved model, append `row <n> escalated | implModel round | allowed attempts <effective allowance>`, commit parent `loop: escalate row <n>`, print `escalated round for row <n>`, and dispatch that attempt with `model: <implModel>` through the normal loop-implementer target, bump and validation path. Exclude this parent commit from child-only stagnation; it starts no new empty-child or validation-miss window. With defaults (allowance 4, `escalateAfter` 3), escalate attempt 4; clamp larger thresholds to the last allowed attempt. At allowance 1, escalate the first and only allowed attempt. A row found past the threshold unspent escalates on its next dispatch. Treat the escalated decision as exactly one round within the effective allowance, never an extra attempt. Recover the row's escalation identity from `## Decisions` on every dispatch and resume; unrecoverable means spent. Preserve `row <n> escalated` for the whole flow across retry, `rows +N`, amendments and resume. Once spent, omit the model override on every later authorized attempt, including every attempt up to a raised effective allowance; never resolve another row escalation or append a second marker. With no marker and recoverable history, apply the threshold predicate after retry or `rows +N`; a previously missing model or migrated row has not spent escalation. Dispatch errors, non-DONE and validation failures consume it before any recommendation decision.
|
|
81
81
|
|
|
@@ -146,7 +146,7 @@ Recover interrupted returns through ## Interrupted recovery before dispatch, wit
|
|
|
146
146
|
|
|
147
147
|
Outside the dispatch loop, perform authorized amendment actions under the amendment surface's own reads. After the amendment commit, re-decode the grant and refresh the held row dispositions, membership, checkout paths and Rules from the updated spec before returning to the loop; apply this to funding and standing-grant amendments too. Leave the `**Amend-grant:**` header grammar unchanged.
|
|
148
148
|
|
|
149
|
-
Retry, cut, amend, raise-allowance and escalate commits never clear the tuple. For ledger amendments use its line-1 discriminant: no plan writer or plan_check; refresh after the amendment commit. Approved deviates/deferred/elsewhere becomes `cut` with disposition evidence; requirement-preserving amendments leave rows unchanged; a re-bounded done row becomes `open` with `reopened by amendment`. Preserve attempts, iterations and allowance. Commit spec + ledger as `loop: cut row <n>` or `loop: amend`.
|
|
149
|
+
Retry, cut, amend, raise-allowance and escalate commits never clear the tuple. For ledger amendments use its line-1 discriminant: no plan writer or plan_check; refresh after the amendment commit. Approved deviates/deferred/elsewhere becomes `cut` with disposition evidence; requirement-preserving amendments leave rows unchanged; a re-bounded done row becomes `open` with `reopened by amendment`. Preserve attempts, iterations and allowance. Commit spec + ledger as `loop: cut row <n>` or `loop: amend`. Without amend permission, stop for amendments; with amend permission, auto-apply amends. Redraw always stops and deletes the ledger with the plan. Cut only through the amendment surface, including its standing-grant section 5.
|
|
150
150
|
|
|
151
151
|
End every stop with `Recommendation: <option> - <why>` or `Recommendation: none - <why>`. An unnamed repair is none. Under amend permission take only a named authorized amend: print `took recommendation: amend for row <n>`, apply amendment-surface section 5 (including its audit), commit `loop: amend` / `loop: cut row <n>`, then return to the ordered table. Whitespace-normalize the row evidence cell and compare with evidence already auto-resolved on that row; repetition renders `Recommendation: none - evidence repeats row <n>`. Recover this evidence from amendment/ledger history; missing history never authorizes a repeated action. A cut leaves the stop; an unresolved row at allowance stops again, not a free retry. Retry, `rows +N` and redraw wait for the human. Fix-first enters `/skill:shape-ticket`'s own gate, never an automatic separate repair. Hard boundaries never auto-take recommendations.
|
|
152
152
|
|
|
@@ -171,13 +171,13 @@ For coordinated runs, route each verification and review below to every leg with
|
|
|
171
171
|
0. Call `phase_tracker({ action: "start", phase: "verify" })`. Mint `LOG_DIR=$(mktemp -d)` once for this verify session; a resumed session mints a new one at its first gate-set site.
|
|
172
172
|
1. Run the gate set per ## Gate set. Require every pair to pass. Commit verification-produced tracked changes, including gate-produced changes. Any repair invalidates that run: apply the rerun scope below before the next gate. No task reopen/update is awaited.
|
|
173
173
|
Count `repairs` as home `loop: repair verification` commits since ledger base, plus one for a `pending: verify` tuple with no admitted repair commit. Use the shared ledger allowance, with no per-row retry increments. Recover this count from branch history and disk on every resume; match marker bodies to pending tuples to avoid counting one dispatch twice. Recover an outstanding tuple before any new gate run or dispatch, including the last reserved repair at allowance.
|
|
174
|
-
On failure automatically repair while `repairs < allowance`
|
|
174
|
+
On failure automatically repair while `repairs < allowance` with or without amend permission; never consult amend permission or gate on iterations. Keep verify active and implement complete. Resolve `gauntlet_setting({ key: "escalationLoop" })`; require its non-empty `implModel`, including the resolver's main-loop fallback. Missing settings/model stops with `Problem: escalationLoop.implModel unavailable`, without a bump or marker. Save the home ledger and home/failing-leg HEADs, then bump iterations once and write `pending: verify | <repo> | <HEAD>` on disk before dispatch, using the failing leg's identity (single-leg `home`) and HEAD. Treat only that bump/tuple as expected home dirt. Dispatch exactly one `implementer` with `model: <implModel>`, `context: "fresh"`, `async: false`, failing checkout cwd and Rules, absolute spec path, failing command, checkout, exit code and log path, never pasted output. Pass the exact pending tuple and consumed `iteration:` for the first two commit-body lines, plus the failing leg's base and pre-bump iteration for jobs-file identity. Inject the persona's step-5 action authorization without its row mutation protocol. Include this blocking-call contract in the repair task: bound every blocking command with `timeout -k 30 <n>`, n <= 600; background and poll longer work. Read [loop-implementer's Evidence command](../../agents/loop-implementer.md#evidence-command) and copy its first three paragraphs verbatim into that task, omitting its row/seed ledger protocol. The repair child reads the log to derive the files to touch; for a stale selector restore the test or its name, never ledger evidence.
|
|
175
175
|
Require DONE, a clean failing checkout and exactly one commit after HEAD_BEFORE, matching the task's tuple/iteration attribution. Require all ledger rows unchanged, preserving attempts, mapping, allowance and prior decisions. The home child's sole commit includes the already-bumped ledger with pending retained; a companion child commits its leg only, leaving home HEAD and expected dirt unchanged. Remove `pending:` only in the parent repair marker: commit `loop: repair verification` in home with the consumed iteration and exact tuple in its body, recording the admitted child SHA. Refresh after admission. On killed, error, non-DONE, dirty, zero/multiple-commit, wrong-attribution or invalid repair returns, read `${TMPDIR:-/tmp}/loop-<failing leg's base SHA>-<pre-bump iteration>.jobs` using the repair task's identity, not home's base, and apply ## Interrupted recovery steps 1-2 to the failing checkout at its saved HEAD. For a companion also reset home to the saved home HEAD with `reset --hard` and `clean -fd`. Write exactly one empty `loop: repair verification` marker in home (no repair code): stage only the ledger with saved row cells, the already-consumed iteration and no `pending:`, and put tuple, iteration and interruption reason in the body, with no second bump. A non-empty `status --porcelain` after reset blocks neither the marker nor the rerun. Apply interrupted recovery's failure pass with the verification repair count to a failed reset of either checkout or an unwritten marker; require the marker's parent to be the saved home HEAD. On resume, admit a matching clean single repair commit or recover the interrupted return by this same path without another bump; an already admitted matching marker needs no second marker.
|
|
176
176
|
Rerun the failing checkout's gate pairs once using ## Gate set's log redirection and fail-fast rule after each admitted or recovered repair. After that rerun passes, run the original fail-fast run's still-unexecuted pairs from other checkouts in ledger order before recording verified HEAD. On resume run the complete gate set in a fresh session LOG_DIR. A new failure in any leg returns to the repair-count check; do not reopen rows or reset the count. Never spend verify-phase credits. On failure at `repairs >= allowance`, render `Stopped: verification failed with every row closed` with `repairs: <k> of <allowance>` and `Problem:` naming `gate <i> exit <code> <log path>` and quoting at most the last 20 lines with `tail -n 20`; this human-stop excerpt is the driver's only log read. Keep verify active and implement complete; offer amend or stop only, no `Retry with hint` or `rows +N`. Use the same restricted menu for missing capabilities. On success record verified HEAD and clean status for every leg.
|
|
177
177
|
2. Dispatch foreground whole-diff `wave-reviewer` per `/skill:requesting-code-review`, from ledger base through committed HEAD, with `SCOPED_TEST_COMMANDS: none`. Apply its fix rounds. Rerun the complete gate set after every fix round before re-review/next gate. Carry final SHIP Minor lines verbatim as `whole-diff minors:`, or `whole-diff minors: none`.
|
|
178
178
|
3. Run happy path per the fully read reference when overrides has `## Happy path` or the diff selects a row; use the diff-derived row, not a plan header. Pass summary and outcome to the separate fresh `conformance-reviewer`, along with spec path, verbatim original prompt and full diff. Use spec AC rows against the ledger as the checklist. Follow the reference's partition, concern decomposition, fix rounds and Convergence with the gate set replacing plan Verification at every test site per the reference's ledger-subject override. Use normal conformance Gn tasks on the same tracker and keep durable Gn identities in reports. Rerun the complete gate set after repairs. Resolve closureReview settings and reviewer dispatch per the reference. Reviews happen only after complete implement; none inside the iteration loop.
|
|
179
179
|
When the conformance fix-round cap blocks (`<used> fix round(s) used against a cap of <cap>`) or the reference's step 6 asks at its cap, read `<used>` from that text. Under amend permission with `<used>` below the ledger allowance: when the block is live, call `phase_tracker({ action: "grant_fix_rounds", rounds: <allowance - used>, reason: "<Amend-grant sentence verbatim>" })`, print `funded <allowance - used> conformance rounds under the grant`, and continue the fix loop; when `closureReview.enforce` is false, continue without a call. With `<used>` at or above the allowance, an error reply, or no amend permission, take the reference's step-6 stop. Never call the tool as a probe or store a grant counter; never count rounds yourself. The next block's `<used>` includes granted rounds, so a second block at the allowance stops; a resumed run with unspent credits continues without a block or another grant. Leave the cap and settings unchanged.
|
|
180
|
-
On an approved re-bound (`reopened by amendment`), use the held grant. Without amend permission, refresh and stop with `Stopped: row <n> reopened by amendment during verify`; offer authorize the row's return to ledger implementation or stop. Under amend permission, continue without a second authorization. For the granted continuation or the
|
|
180
|
+
On an approved re-bound (`reopened by amendment`), use the held grant. Without amend permission, refresh and stop with `Stopped: row <n> reopened by amendment during verify`; offer authorize the row's return to ledger implementation or stop. Under amend permission, continue without a second authorization. For the granted continuation or the human-approved return, apply the normal Before each dispatch boundaries, including exhausted-row rule 2, then Dispatch, Validate the return and refresh with verify still active and no phase reset; close on disk and rerun step 1 before continuing verify. During verify, dispatch the reopened row as a one-task `tasks` call carrying the same `## Dispatch` fields (agent, context fresh, async false, cwd, output, outputMode, acceptance, task text, and `model` only on an escalated round), with no `worktree:`; the closure guard counts it as one fix round against the conformance cap funded above. Keep the tuple write, iteration bump, `## Validate the return` and interrupted recovery exactly as for any dispatch. Keep completion blocked until closure; never substitute a tracker write for the ledger return.
|
|
181
181
|
4. Complete verify only on current CONFORMS or valid carried-open deferred inventory per the reference. A started positive-cap fix loop blocking/failing/exhausting with an open fix gap stops, never completes verify. Summarize rows closed, iterations consumed, files changed, test counts and review verdict. Emit exact `## Closure / conformance` schema from the reference: `status: CONFORMS (0 open)` or `status: GAPS (N open)`, then `audited-base: <full HEAD SHA>`, happy-path exactly when run, Deferred/deviates per spec exactly when applicable, all gap/concern fields unchanged, auto-applied fix commits index and whole-diff minors. Read its whole-diff-minors companion when directed. Never rename fields.
|
|
182
182
|
5. Immediately invoke `/skill:finishing-a-development-branch <abs worktree path>`. Its menu is the human gate; do not add a ready-to-finish prompt.
|
|
183
183
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Interrupted recovery
|
|
2
2
|
|
|
3
|
-
Treat dispatch error, non-DONE, silence kill, dirty tree, zero/multiple commits and wrong attribution as interrupted returns. Use the saved pre-dispatch ledger and checkout `HEAD_BEFORE`; on resume use the tuple's HEAD and its ledger before-image (the saved home HEAD for a companion). Recover without a human turn
|
|
3
|
+
Treat dispatch error, non-DONE, silence kill, dirty tree, zero/multiple commits and wrong attribution as interrupted returns. Use the saved pre-dispatch ledger and checkout `HEAD_BEFORE`; on resume use the tuple's HEAD and its ledger before-image (the saved home HEAD for a companion). Recover without a human turn with or without amend permission. Recovery itself is unconditional; check the numbered target's effective allowance or seed repair count only after committing the repair.
|
|
4
4
|
|
|
5
5
|
1. Read `${TMPDIR:-/tmp}/loop-<base SHA>-<iteration i>.jobs`; process lines are `<pid> <process-start-identity> <command>`. An absent or empty jobs file means no jobs to terminate. For each listed live job require matching start identity and command plus PGID equal to the pid; recheck identity, command and group leader before each signal. Send `kill -TERM -- -<pid>`, wait at most 10 s, then send `kill -KILL -- -<pid>` to a surviving matching group. When any identity, command or group-leader check fails, identity is unavailable, or the job is already gone, skip that job and continue recovery. A job still alive after KILL and missing launch history do not block recovery. Signal neither the driver's shells nor unrecorded processes. Print `terminated <k> child jobs` when k > 0, counting observed exits, then delete the jobs file.
|
|
6
6
|
2. Use the driver's shell: `git -C "<worktree>" reset --hard HEAD_BEFORE`, then `git -C "<worktree>" clean -fd` (leave ignored files alone). Continue even when files remain after reset; the next return is validated as usual.
|