pi-gauntlet 7.1.1 → 7.2.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 +18 -0
- package/README.md +8 -1
- package/agents/spec-summarizer.md +12 -22
- package/package.json +1 -1
- package/skills/brainstorming/reference/amendment-surface.md +32 -4
- package/skills/brainstorming/reference/spec-finalization.md +11 -8
- package/skills/gauntlet-resume/SKILL.md +21 -3
- package/skills/gauntlet-resume/reference/brief-contract.md +6 -4
- package/skills/gauntlet-resume/reference/reconstruction.md +2 -2
- package/skills/roasting-the-spec/SKILL.md +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v7.2.0 - 2026-10-04
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- **spec-summarizer: briefing instead of decision log.** The persona emits a plain-language briefing of at most 300 words, written to about 220: entry paragraph, What changes, Approval risks, Done when, and Missing from the spec when external context is missing. It uses behavior and outcomes instead of code identifiers. The brainstorming gate drops the `under ~2%` degrade check; file-only transport, Read-last rendering, and the absolute size checks stay.
|
|
8
|
+
- **Non-trivial skill, persona, and prompt edits create or extend an eval.** `AGENTS.md` requires samples and must-hold facts designed during brainstorming and a baseline run before the wording changes; existing targets gain a sample exercising the change. Trivial-edit exemptions stay unchanged, and deterministic code stays on `npm test`. `README.md` routes the procedure to `eval/README.md`.
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Committed eval convention and spec-summarizer replay set.** `eval/README.md` defines fixed inputs, human-approved facts, independent reviewers with models supplied externally, and recorded baseline/candidate comparisons. `eval/spec-summarizer/` includes eight samples (two anonymized product specs) and first-run results against the persona pinned at `2166283`: 9,497 -> 2,235 words, 327 -> 0 backticked lines, and quality from `mixed` on 15/16 votes to `readable` or `briefing` on 12/16. Two of 47 facts were lost and reviewed; the comparison permits at most two losses across a run and lists each for human review. `eval/` stays outside the npm tarball; model calls are manual.
|
|
13
|
+
- **Deterministic eval checks in CI.** `scripts/ci.mjs` runs `eval/spec-summarizer/run.test.mjs` and an `eval/` hygiene scan without model calls.
|
|
14
|
+
|
|
15
|
+
## v7.1.2 - 2026-10-04
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- **brainstorming + gauntlet-resume: the standing amend grant lives in the spec header.** Spec-writing emits `**Amend-grant:** none` under `**Goal:**`; a `2` / `auto-apply amends` reply at the spec gate sets the line to the granting sentence and amends it into the spec commit; mid-flow grants and revocations persist as `grant: <value>` commits (or ride the open `amend:` batch); a post-revert restore reads the pre-revert HEAD's line. Every reader applies one predicate (`none`/missing -> no grant; one other single-line value -> active; two lines, an empty value, or a continued value -> malformed, stop). `/skill:gauntlet-resume` runs it as entry check 6 before the route's first tracker call and prints `Standing grant active: <sentence>` or `No standing grant.` after its closing line; the handoff brief stays grant-free. The `Amend-grant:` commit trailer is gone; council members, chair, and the worker critique leave the line alone. Supersedes the grant-recording / fresh-session-resume boundary of the 2026-09-18, 2026-09-19, and 2026-10-04 approval-menu specs.
|
|
20
|
+
|
|
3
21
|
## v7.1.1 - 2026-10-04
|
|
4
22
|
|
|
5
23
|
### Changed
|
package/README.md
CHANGED
|
@@ -79,7 +79,7 @@ pi-gauntlet is **opinionated**: it recommends this pipeline for non-trivial chan
|
|
|
79
79
|
|
|
80
80
|
## Handoff and resume
|
|
81
81
|
|
|
82
|
-
`/skill:gauntlet-handoff` and `/skill:gauntlet-resume` are a pair: cohort's `handoff` skill writes the six flow-agnostic headings, gauntlet-handoff appends `## Process state`, and gauntlet-resume reads the whole brief back. Both gauntlet skills read one grammar file, `skills/gauntlet-resume/reference/brief-contract.md`; the repo validator (`scripts/ci.mjs`) fails if a grammar line appears anywhere else under `skills/`. Requires pi-cohort >= 7.1.0 (the `handoff` skill, [pi-cohort #18](https://github.com/jjuraszek/pi-cohort/issues/18)); on an older pi-cohort, gauntlet-handoff stops before writing.
|
|
82
|
+
`/skill:gauntlet-handoff` and `/skill:gauntlet-resume` are a pair: cohort's `handoff` skill writes the six flow-agnostic headings, gauntlet-handoff appends `## Process state`, and gauntlet-resume reads the whole brief back. Both gauntlet skills read one grammar file, `skills/gauntlet-resume/reference/brief-contract.md`; the repo validator (`scripts/ci.mjs`) fails if a grammar line appears anywhere else under `skills/`. Requires pi-cohort >= 7.1.0 (the `handoff` skill, [pi-cohort #18](https://github.com/jjuraszek/pi-cohort/issues/18)); on an older pi-cohort, gauntlet-handoff stops before writing. A resume also reads the spec's `**Amend-grant:**` header line and prints `Standing grant active: <sentence>` or `No standing grant.` on the line after its closing line; the brief itself carries no grant.
|
|
83
83
|
|
|
84
84
|
### Smoke walkthrough (release-gated)
|
|
85
85
|
|
|
@@ -93,6 +93,7 @@ Run by a human against pi-cohort >= 7.1.0, before a pi-gauntlet release claims t
|
|
|
93
93
|
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: ...)`.
|
|
94
94
|
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/`.
|
|
95
95
|
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.
|
|
96
|
+
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.
|
|
96
97
|
|
|
97
98
|
## Key concepts
|
|
98
99
|
|
|
@@ -152,6 +153,12 @@ cd ~/path/to/your/repo
|
|
|
152
153
|
pi install -l ~/repos/pi-gauntlet
|
|
153
154
|
```
|
|
154
155
|
|
|
156
|
+
## Evals
|
|
157
|
+
|
|
158
|
+
Evals compare prompt wording on fixed inputs against human-approved must-hold facts. A non-trivial edit under `skills/`, `agents/`, or a prompt file creates or extends `eval/<target>/`; design its samples and facts during brainstorming, and run the baseline on current wording before the edit. Existing targets gain a sample exercising the changed behavior. Typo, formatting, dependency bump, and release-commit edits are exempt; deterministic code under `extensions/`, `src/bins/`, and `scripts/` stays on `npm test`.
|
|
159
|
+
|
|
160
|
+
Run an arm with externally supplied models: `node eval/spec-summarizer/run.mjs run --arm candidate --persona agents/spec-summarizer.md --candidate-model <candidate-id> --reviewers <reviewer-a>,<reviewer-b>`. The [eval convention](eval/README.md) owns the layout, baseline/candidate process, and publication rules; the [spec-summarizer eval](eval/spec-summarizer/README.md) is the worked example with eight samples and committed results. Model calls run manually, never in CI; CI runs deterministic eval tests and hygiene checks. `eval/` is checkout-only and excluded from the npm tarball.
|
|
161
|
+
|
|
155
162
|
## Use from Claude Code
|
|
156
163
|
|
|
157
164
|
Six skills are exposed to Claude Code via the plugin marketplace at
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: spec-summarizer
|
|
3
|
-
description: Produces a
|
|
3
|
+
description: Produces a plain-language briefing (at most 300 words) of a single spec for the brainstorming user review gate. Fresh context, read-only, reads only the spec file it is given. Dispatched only by the brainstorming skill's gate step; not for direct dispatch.
|
|
4
4
|
tools: read
|
|
5
5
|
defaultContext: fresh
|
|
6
6
|
inheritProjectContext: false
|
|
@@ -11,33 +11,23 @@ systemPromptMode: replace
|
|
|
11
11
|
|
|
12
12
|
You are a cold reader producing a tight, human-readable summary of one spec, so a supervising human can green-light plan + execution without reading the whole document. The summary is a decision aid, not a rewrite.
|
|
13
13
|
|
|
14
|
-
You receive the absolute path to a spec file. Read **only that file**. Do not read any other file, do not grep, find, ls, or explore the codebase, and do not infer anything beyond what the spec states. If the spec references external context it does not contain (a ticket, an acceptance criterion, a commit SHA, another doc), do not invent it - list it
|
|
14
|
+
You receive the absolute path to a spec file. Read **only that file**. Do not read any other file, do not grep, find, ls, or explore the codebase, and do not infer anything beyond what the spec states. If the spec references external context it does not contain (a ticket, an acceptance criterion, a commit SHA, another doc), do not invent it - list it under Missing from the spec, by its plain-language title (the ticket's subject, the document's name), never by SHA or path.
|
|
15
15
|
|
|
16
|
-
Your output is judged on whether a busy supervisor can decide from it alone. A
|
|
16
|
+
Your output is judged on whether a busy supervisor can decide from it alone. A confused briefing, or one whose Missing from the spec block is long, is a faithful signal that the spec itself is thin - do not paper over gaps to look complete.
|
|
17
17
|
|
|
18
18
|
## What to emit
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
Emit a briefing of at most 300 words in total - write to about 220, since measured counts run a fifth over an estimate and the cap is checked on the measured count - in this order, each part within its own budget:
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
1. One entry paragraph, at most 90 words: who is hurt today and how, what the spec does about it, and what that person gets once it ships. A reader who stops here can say yes or no.
|
|
23
|
+
2. **What changes** - 3-5 one-sentence bullets, at most 80 words together. Each bullet is one rule the user can observe, stated as a condition and its outcome ("when a ticket already fits the template, nothing is written"). Rules that stop, block, or require a repeat approval count as changes. A rule travels with its qualifiers: the condition that makes it apply, what it refuses or keeps, what happens at a zero setting or a missing precondition ("when the base branch moves first, the flow stops and keeps the reviewed work"). The last bullet names what deliberately stays as it is.
|
|
24
|
+
3. **Approval risks** - up to 3 one-sentence bullets, at most 45 words together, each something the supervisor can veto: an irreversible step, a changed contract other components depend on, a dependency on work outside this spec, or a decision the spec leaves to the implementer.
|
|
25
|
+
4. **Done when** - one or two sentences, at most 25 words, restating every measurable completion condition the spec names, each threshold with its precondition ("under five minutes with a warm cache").
|
|
26
|
+
5. **Missing from the spec** - at most 3 lines, each under twelve words, naming an external source a requirement depends on but the spec does not inline (a ticket's acceptance criteria, a contract in another document). Never list superseding or related specs, decision history, or reading material. Emit this block only when at least one such source exists.
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
Write for a product manager in plain words - behaviors, actors, outcomes - with no code-level identifiers (file paths, commit SHAs, backticked names, command names, line numbers), as the example below does. Leave out the decision log (rejected alternatives, "chose X over Y because Z", how the document was edited); the gate prints the critique record next to the briefing. A short spec yields a briefing well under the cap; the cap is a ceiling, never a target.
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
3. **Scope** - what's in, and what's explicitly out (non-goals).
|
|
32
|
-
4. **Risk surface** - shared contracts, schema/migrations, irreversibility, rollout - where approval risk concentrates.
|
|
33
|
-
5. **Inputs / conditions / UI / endpoints.**
|
|
34
|
-
6. **Outputs** - new pages, comms protocols, DB/data changes.
|
|
35
|
-
7. **Key changes to the current process.**
|
|
36
|
-
8. **Caveats / edge cases.**
|
|
37
|
-
9. **Algorithm** - only if the spec defines one. Give the key mechanism and decision points; an example with a short explanation beats an exhaustive step transcript. Skip SQL/syntax.
|
|
38
|
-
10. **Acceptance** - how we'll know it's done, only if the spec defines it.
|
|
39
|
-
11. **Gap footer** - external context the spec leans on but does not inline. Omit if there is none.
|
|
40
|
-
|
|
41
|
-
Tight, human-readable, no obvious statements. If the topic is complex, an example with explanation beats prose.
|
|
30
|
+
Before: "`guard-windows` job on `windows-latest` in `harness-guard.yml` runs `script/harness-guard.ps1`; a non-zero exit blocks merge."
|
|
31
|
+
After: "A Windows regression in the hook tooling now fails the pull request instead of reaching an operator."
|
|
42
32
|
|
|
43
33
|
Output the summary as your final text response. You have no write tool. If your task instructs you to write your findings to a file path, do **not** attempt to write, create, or edit any file and do **not** treat the inability to write as a failure - just emit the full summary as your final text response. The harness persists that response to the requested path for you.
|
package/package.json
CHANGED
|
@@ -4,9 +4,37 @@
|
|
|
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 a bare `2` at the spec gate, `auto-apply amends, stop only for redraws`, `apply spec fixes without asking`, or the same intent in other words). The digit grants only at the spec gate, and a prose grant after a `1` 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.
|
|
7
|
+
Honor a user sentence in this flow that waives per-diff review for later amends (`auto-apply amends`, `approve, auto-apply amends` or a bare `2` at the spec gate, `auto-apply amends, stop only for redraws`, `apply spec fixes without asking`, or the same intent in other words). The digit grants only at the spec gate, and a prose grant after a `1` 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
|
+
|
|
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. When the reply was the digit `2`, the sentence is the grant description from the gate menu (the text after `2 - approve, auto-apply amends:` 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
|
+
|
|
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
|
+
|
|
15
|
+
| Header block contains | Reading |
|
|
16
|
+
|---|---|
|
|
17
|
+
| no `**Amend-grant:**` line | no grant (legacy spec; gauntlet-resume reports `No standing grant.`) |
|
|
18
|
+
| exactly one line whose trimmed value is `none` | no grant |
|
|
19
|
+
| exactly one line whose trimmed value is any other non-empty single-line text | grant active; the sentence is that value |
|
|
20
|
+
| two or more lines, one line with an empty value, or a value continued onto the next physical line (any non-blank line directly below the field that is neither a `**Key:**` header line nor a `> **Superseded by:**` banner line) | malformed -> stop, print the offending line(s) |
|
|
21
|
+
|
|
22
|
+
**Writers.** Spec-writing and the spec gate are owned by `spec-finalization.md`; this file owns the mid-flow changes:
|
|
23
|
+
|
|
24
|
+
| Event | Edit |
|
|
25
|
+
|---|---|
|
|
26
|
+
| Grant given at a tier-2 footer | `edit` the value to the sentence |
|
|
27
|
+
| Line absent (legacy spec) | insert the line at the writer placement above; when a plan exists, the insertion shifts every heading by one line, so run the section 5 aftermath's anchor repair (`plan_check` until PASS) and commit spec and plan together |
|
|
28
|
+
| Revocation (`revoke auto-apply amends`, `stop auto-applying amends`, or the same intent in other words) | `edit` the value to `none` |
|
|
29
|
+
| Hand-edited line | not an event; the next batch boundary re-reads it and the value found is the current consent |
|
|
30
|
+
|
|
31
|
+
**Persisting a consent change.** If HEAD's copy of the spec already carries the new value, commit nothing. Otherwise, when the spec file has no other uncommitted change, commit that one file with the message on stdin:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
printf 'grant: %s\n' "<new value>" | git -C <abs worktree path> commit -q -F - -- <spec path>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
When the spec file is mid-batch (uncommitted amend edits), the consent edit rides in that batch's `amend:` commit and the footer acknowledgment says so. Either way, verify `git -C <abs worktree path> show HEAD:<spec path>` satisfies the predicate with the new value; otherwise stop and report. After the line exists, every later change is a same-line value edit; a grant given in a resumed session is an ordinary mid-flow grant.
|
|
10
38
|
|
|
11
39
|
## 1. Prepare - never apply yet
|
|
12
40
|
|
|
@@ -26,7 +54,7 @@ Collect every amendment pending at this decision point (same spec-review round,
|
|
|
26
54
|
|
|
27
55
|
The working tree stays at pre-batch HEAD until apply (section 5) - nothing is edited before the reviewer and, where needed, the human have answered. A redraw item stops alone first (`../SKILL.md` redraw path); amend items are held and re-batched after it resolves.
|
|
28
56
|
|
|
29
|
-
**Standing grant active** ([boundaries](#standing-grants)): skip steps 2-4, apply every item, print one line each `amended the spec: <title> - <what>`, record `granted`, and quote the
|
|
57
|
+
**Standing grant active** ([boundaries](#standing-grants)): at every batch boundary re-read the spec's `**Amend-grant:**` line through the predicate; malformed stops the batch with the offending line(s). Active -> skip steps 2-4, apply every item, print one line each `amended the spec: <title> - <what>`, record `granted`, and quote the line's value in the commit body - the record kind `finishing-a-development-branch` Step 4's digest reads is unchanged.
|
|
30
58
|
|
|
31
59
|
## 2. Prefilter - no model call
|
|
32
60
|
|
|
@@ -116,7 +144,7 @@ amend: <N> item(s) - <first title>[, <second title>]
|
|
|
116
144
|
<the granting sentence, quoted, when a grant applied>
|
|
117
145
|
```
|
|
118
146
|
|
|
119
|
-
`amend:` is the subject marker `finishing-a-development-branch` Step 4 greps for its digest; `<what>` is the item's one-sentence what-changes field, so the digest renders `<title> - <what changed>` from the body alone. When no item applied (every item dropped or redirected), nothing changed on disk; the commit still lands, with `git commit --allow-empty`, so the per-item `custom(<effect>)` records stay in the batch body - the digest ignores them because it reads only `auto-apply` and `granted` records. Wrong apply -> `git revert` the batch commit
|
|
147
|
+
`amend:` is the subject marker `finishing-a-development-branch` Step 4 greps for its digest; `<what>` is the item's one-sentence what-changes field, so the digest renders `<title> - <what changed>` from the body alone. When no item applied (every item dropped or redirected), nothing changed on disk; the commit still lands, with `git commit --allow-empty`, so the per-item `custom(<effect>)` records stay in the batch body - the digest ignores them because it reads only `auto-apply` and `granted` records. Wrong apply -> `git revert` the batch commit; then read the `**Amend-grant:**` line from the pre-revert HEAD (`git -C <abs worktree path> show HEAD^:<spec path>` through the predicate) and, if the working tree's line differs, restore that value and persist it per [Standing grants](#standing-grants) before re-entering this surface for the items to keep - the pre-revert HEAD holds every consent change committed so far, revocations included.
|
|
120
148
|
|
|
121
149
|
## Conformance entry
|
|
122
150
|
|
|
@@ -8,7 +8,9 @@ Spec-writing replaces the context draft, in this exact order:
|
|
|
8
8
|
pruned questionary plus a full-replacement `write` destroys the only copy of the
|
|
9
9
|
gathered context at the moment it feeds the spec.
|
|
10
10
|
2. Write the spec with the `write` tool (**full replacement**) at the spec path.
|
|
11
|
-
Using `edit` at this step is a red flag.
|
|
11
|
+
Using `edit` at this step is a red flag. The header block (between the H1 and the
|
|
12
|
+
first `##`) carries `**Amend-grant:** none` directly below `**Goal:**`; a redraw's
|
|
13
|
+
rewrite carries `none` too - a redraw is a new approval, with no carry-over.
|
|
12
14
|
3. **Immediately after the write**, confirm line 1 of the file is no longer
|
|
13
15
|
`# CONTEXT DRAFT - NOT A SPEC - fully replaced at spec-writing` - before
|
|
14
16
|
dispatching lint, critique, council, or summarizer. The phase-tracker commit
|
|
@@ -35,13 +37,13 @@ Spec-writing replaces the context draft, in this exact order:
|
|
|
35
37
|
After writing the spec to `<project>/doc/specs/<filename>.md` (per [Filename Convention](../SKILL.md#filename-convention)) and before showing it to the user, run a self-review pass. Read all six bullets first, then act.
|
|
36
38
|
|
|
37
39
|
- **Placeholder scan.** Any `TODO`, `TBD`, `<fill in>`, `[example]`, `xxx`? Either resolve them or convert to explicit "Open Questions" with names.
|
|
38
|
-
- **Internal consistency.** Does Section 4 contradict Section 2? Are component names and field names consistent throughout? If the spec replaces a prior design, confirm the predecessor carries the supersession banner and its href resolves to this spec's final filename.
|
|
40
|
+
- **Internal consistency.** Does Section 4 contradict Section 2? Does the header block carry `**Amend-grant:**` exactly once with the value `none` (the [predicate](amendment-surface.md#standing-grants))? Are component names and field names consistent throughout? If the spec replaces a prior design, confirm the predecessor carries the supersession banner and its href resolves to this spec's final filename.
|
|
39
41
|
- **Documentation named.** Does the spec name all three classes (feature/user-facing introduced; materially amended; derived/memory invalidated), or an explicit "none" for each? Enforce the materiality bar in `documentation-impact.md` without restating it: each listed doc names the category it clears, none is a code-mirror, amend-over-create was applied, and skill/agent bodies are implementation surface, not doc-impact entries here.
|
|
40
42
|
- **Ticket contract present.** Does `## Acceptance criteria` exist with either verbatim ticket rows plus dispositions or one `none - <reason>` line? Presence is enforced here, at authoring, and nowhere later.
|
|
41
43
|
- **Scope check.** Does every paragraph serve the goal? Cut filler. If something is out of scope, say it's out of scope.
|
|
42
44
|
- **Ambiguity check.** Is every "we should..." backed by a concrete decision? Replace "we could probably" with "we will" or "we won't".
|
|
43
45
|
|
|
44
|
-
The first four are the inline **lint**: run them here and fix what they surface. The last two are the **critique pass**, dispatched per [Spec Council](#spec-council). After it returns, re-run the placeholder scan over the applied spec; if a predecessor banner exists, confirm its `<scope>` still matches and reconcile it; carry any ambiguity the critique could not resolve to the [User Review Gate](#user-review-gate).
|
|
46
|
+
The first four are the inline **lint**: run them here and fix what they surface. The last two are the **critique pass**, dispatched per [Spec Council](#spec-council). After it returns, re-run the placeholder scan over the applied spec and re-apply the predicate to the header block - if the critique pass removed or altered the `**Amend-grant:**` line, repair it to `none`, exactly once; if a predecessor banner exists, confirm its `<scope>` still matches and reconcile it; carry any ambiguity the critique could not resolve to the [User Review Gate](#user-review-gate).
|
|
45
47
|
|
|
46
48
|
## Spec Council
|
|
47
49
|
|
|
@@ -56,6 +58,7 @@ subagent({ agent: "worker", context: "fresh", async: false, cwd: "<abs worktree
|
|
|
56
58
|
"Problem statement: <the problem the spec addresses + the user's stated intent>.\n" +
|
|
57
59
|
"Read the spec at <abs path to doc/specs/...>. Edit ONLY that file.\n" +
|
|
58
60
|
"The portable citation `reference/documentation-impact.md` in the spec is the pi-gauntlet guideline at <DOCUMENTATION_IMPACT_GUIDELINE>, not a consumer doc; do not flag it as an external reference, and preserve it - never remove it as redundant or replace it with the resolved absolute path.\n" +
|
|
61
|
+
"The `**Amend-grant:**` header line is flow machinery owned by the brainstorming gate; never cut, shrink, flag, or edit it.\n" +
|
|
59
62
|
"Apply two checks and fix what you find in place: (1) Scope - does every paragraph serve the goal? Cut filler;\n" +
|
|
60
63
|
"state out-of-scope explicitly. (2) Ambiguity - is every 'we should' a concrete decision?\n" +
|
|
61
64
|
"Replace 'we could probably' with 'we will'/'we won't'. Also inline any load-bearing\n" +
|
|
@@ -87,14 +90,14 @@ subagent({ agent: "spec-summarizer", context: "fresh", async: false, cwd: "<abs
|
|
|
87
90
|
|
|
88
91
|
Then commit the spec - staging any predecessor spec edited per [Marking superseded specs](superseding.md) alongside it; a change request at the gate that renames, materially revises, or drops the spec also reconciles the predecessor's banner before recommitting. This commit is **unconditional**: the summary is only a gate aid, so a degraded or missing summary never blocks it. If the council path ran, include its audit (`Coverage:` when present, then `Applied:` / `Deferred:` / `Rejected:`, verbatim from `/skill:roasting-the-spec`'s return) in the **commit message body** - this is the durable, non-contractual record a finish-time revert reads back; the audit is never a committed spec section. Evaluate the summary in two stages (the **Degrade path** referenced in each is defined just below):
|
|
89
92
|
|
|
90
|
-
1. **From the dispatch tool result, before the `Read`.** If the result is **not** an `"Output saved to: <path> (<N> KB, <M> lines)"` reference (e.g. an exit-0 save error returns the full inline output plus an "Output file error" line - the prunable shape, no file to read), or the reference reports under ~500 bytes, or
|
|
91
|
-
2. **The `Read` itself, as the last content-producing tool call before composing the gate.** `Read` `$SUMMARY_PATH` and paste its contents verbatim at the top of the gate. 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
|
|
93
|
+
1. **From the dispatch tool result, before the `Read`.** If the result is **not** an `"Output saved to: <path> (<N> KB, <M> lines)"` reference (e.g. an exit-0 save error returns the full inline output plus an "Output file error" line - the prunable shape, no file to read), 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.
|
|
94
|
+
2. **The `Read` itself, as the last content-producing tool call before composing the gate.** `Read` `$SUMMARY_PATH` and paste its contents verbatim at the top of the gate. 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.
|
|
92
95
|
|
|
93
96
|
**Degrade path** - reach the gate with a one-line "summary generation failed" note; never paraphrase from the file-only reference, never render a stub as the canonical summary.
|
|
94
97
|
|
|
95
98
|
Either way - summary rendered or degraded - then `rm "$SUMMARY_PATH"` (unconditional cleanup; harmless if the file was never created, since it lives outside the worktree under the OS temp dir).
|
|
96
99
|
|
|
97
|
-
Paste the summary verbatim, unedited in the template below; use adjacent lines for the audit, unresolved ambiguities, and every
|
|
100
|
+
Paste the summary verbatim, unedited in the template below; use adjacent lines for the audit, unresolved ambiguities, and every `Missing from the spec` entry:
|
|
98
101
|
|
|
99
102
|
```
|
|
100
103
|
<spec-only summary read back from the temp file - pasted verbatim, unedited>
|
|
@@ -107,7 +110,7 @@ Deferred: [<severity>] <cluster> - raised-by: [<slugs>] -> <where it belongs>
|
|
|
107
110
|
Rejected: [<severity>] <cluster> - raised-by: [<slugs>] -> <one-line reason>
|
|
108
111
|
(one line per item, exactly as returned by roasting-the-spec - `Applied: none` / `Deferred: none` / `Rejected: none` when a list is empty; omit the audit lines when the worker path ran, not the council)
|
|
109
112
|
|
|
110
|
-
<unresolved ambiguities; every
|
|
113
|
+
<unresolved ambiguities; every `Missing from the spec` entry from the summary>
|
|
111
114
|
New predecessor candidates at spec-writing: <path> (<title>), ... - index rows are a hint; code is the source and an absent row proves nothing.
|
|
112
115
|
|
|
113
116
|
1 - approve: proceed to planning under the existing amendment review; a fresh reviewer applies evidence-backed factual corrections on its own, and every other spec amendment (scope, acceptance-criteria, or contract edits, and redraws) stops for your review.
|
|
@@ -120,7 +123,7 @@ If you believe the summary needs correcting, do **not** silently rewrite it - re
|
|
|
120
123
|
|
|
121
124
|
**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.
|
|
122
125
|
|
|
123
|
-
Wait for the user. 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 approval - `1`, `approve`, or equivalent prose approves without a grant; `2`, `approve, auto-apply amends`, or equivalent prose approves and grants - proceed immediately to `/skill:writing-plans` with no further prompt; first read [Standing grants](amendment-surface.md#standing-grants) (stop if unreadable) and
|
|
126
|
+
Wait for the user. 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 approval - `1`, `approve`, or equivalent prose approves without a grant; `2`, `approve, auto-apply amends`, or equivalent prose approves and grants - proceed immediately to `/skill:writing-plans` with no further prompt; first read [Standing grants](amendment-surface.md#standing-grants) (stop if unreadable). On a grant (`2`, `approve, auto-apply amends`, or equivalent prose), `edit` the spec's `**Amend-grant:**` value to the granting sentence (the digit `2` becomes the grant description after `2 - approve, auto-apply amends:` above), then `git -C <abs worktree path> add -- <spec path>` and `git -C <abs worktree path> commit --amend --no-edit -q`, so the spec commit carries the line and keeps its council-audit body; then confirm `git -C <abs worktree path> show HEAD:<spec path>` reads "grant active" through the predicate. On a plain approval (`1`, `approve`) the value stays `none` and the commit is untouched. 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.
|
|
124
127
|
|
|
125
128
|
Post-approval changes follow [Amending an approved spec](../SKILL.md#amending-an-approved-spec).
|
|
126
129
|
|
|
@@ -58,14 +58,14 @@ tried at `<primary>/<specDir>/name.md` per resolved spec dir in order, first hit
|
|
|
58
58
|
`dirname "$(git rev-parse --path-format=absolute --git-common-dir)"` run in the session
|
|
59
59
|
cwd - absolute from any primary subdirectory and from inside a linked worktree
|
|
60
60
|
(`--show-toplevel` would return the linked worktree there). A pasted brief that needs
|
|
61
|
-
an override uses the file form. A brief then runs entry checks 1-
|
|
61
|
+
an override uses the file form. A brief then runs entry checks 1-6, so a stale or
|
|
62
62
|
foreign-repo brief stops there.
|
|
63
63
|
|
|
64
64
|
## Entry checks
|
|
65
65
|
|
|
66
66
|
In order. All before any tracker mutation; entry check 1 is read-only. A spec
|
|
67
67
|
seed runs check 1 here, then `reference/seed.md`, which runs check 3 itself;
|
|
68
|
-
checks 2, 4, 5 do not apply.
|
|
68
|
+
checks 2, 4, 5 do not apply; check 6 runs on the seed's pinned spec path.
|
|
69
69
|
|
|
70
70
|
1. **Idle session.** `phase_tracker({ action: "status" })`. Any phase not pending ->
|
|
71
71
|
stop: "session already carries flow state - reset is your call".
|
|
@@ -94,6 +94,24 @@ checks 2, 4, 5 do not apply.
|
|
|
94
94
|
`skills/*/SKILL.md` in this package; `Read` each match's complete file into the
|
|
95
95
|
transcript; list non-matches as skipped. Loaded bodies are context only - no skill's
|
|
96
96
|
entry actions run until Dispatch names one.
|
|
97
|
+
6. **Grant field.** Runs once the route has resolved `<spec path>` - the `S` path that
|
|
98
|
+
`reference/brief-contract.md` "Process-state restore" resolves for `skip brainstorm`
|
|
99
|
+
(process-state briefs), the spec reconstruction resolves and the human approves
|
|
100
|
+
(Spec without plan) or confirms (Spec with plan) (`reference/reconstruction.md`), or
|
|
101
|
+
the pinned `<full-path>/<rel>` of a spec tracked on `main` (`reference/seed.md`) -
|
|
102
|
+
and before that route's first tracker call; the path is carried, never re-resolved.
|
|
103
|
+
Read the spec's header block (between the H1 and the first `##`) through the
|
|
104
|
+
predicate in
|
|
105
|
+
[Standing grants](../brainstorming/reference/amendment-surface.md#standing-grants): no
|
|
106
|
+
`**Amend-grant:**` line -> no grant (legacy spec);
|
|
107
|
+
exactly one line whose trimmed value is `none` -> no grant;
|
|
108
|
+
exactly one line whose trimmed value is any other non-empty single-line text ->
|
|
109
|
+
grant active, the sentence is that value;
|
|
110
|
+
two or more lines, one line with an empty value, or a value continued onto the next physical line ->
|
|
111
|
+
malformed, stop, print the offending line(s), no tracker call. Routes that resolve no
|
|
112
|
+
approved spec (hotfix, `worktree: no`, a brief whose active phase is brainstorm,
|
|
113
|
+
reconstruction's unapproved-draft brainstorming handoff) skip this check and print
|
|
114
|
+
no grant line. Resume reports the line; it never writes it.
|
|
97
115
|
|
|
98
116
|
## Dispatch
|
|
99
117
|
|
|
@@ -115,7 +133,7 @@ re-derive the record.
|
|
|
115
133
|
## Post-restore continuation
|
|
116
134
|
|
|
117
135
|
After a successful restore, print the closing line from `reference/brief-contract.md`
|
|
118
|
-
(gate history not restored; the task to re-validate), then continue in the stage's
|
|
136
|
+
(gate history not restored; the task to re-validate), then on its own line exactly one of `Standing grant active: <sentence>` or `No standing grant.` from check 6 (nothing when the check was skipped), then continue in the stage's
|
|
119
137
|
owning skill **without** its reset-bearing entry:
|
|
120
138
|
|
|
121
139
|
| Active after restore | Continue in | Entry point |
|
|
@@ -119,10 +119,12 @@ Facts that fix the order (from the extensions):
|
|
|
119
119
|
|
|
120
120
|
Per-stage call table, keyed by the brief's active phase (`→`). Use
|
|
121
121
|
`R = resume: <brief file or "pasted brief">` for plan/implement/verify skips and
|
|
122
|
-
`S = resume: <spec path>` for brainstorm skips. Resolve `<spec path>`
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
122
|
+
`S = resume: <spec path>` for brainstorm skips. Resolve `<spec path>` as
|
|
123
|
+
`reconstruction.md` "Candidates" does, to an absolute path under the worktree: the single
|
|
124
|
+
`*.md` spec added after base under `flowGuards.specDirs`, or a spec tracked from base when
|
|
125
|
+
a plan added after base pairs with it by basename. Zero specs -> stop; more than one ->
|
|
126
|
+
human picks. The consumer carries this path to its entry check 6 and its post-restore
|
|
127
|
+
announcement without re-resolving it.
|
|
126
128
|
|
|
127
129
|
| Active | Calls, in order |
|
|
128
130
|
|---|---|
|
|
@@ -56,7 +56,7 @@ Ask exactly one question: is this spec approved, or do you select `/skill:brains
|
|
|
56
56
|
with this unapproved spec as the draft? Show the spec path (and the brief's
|
|
57
57
|
`## Intent`/`## Decisions` when present).
|
|
58
58
|
|
|
59
|
-
- Approved: `start brainstorm`; `skip brainstorm resume: <spec path>`; `start plan`;
|
|
59
|
+
- Approved: run SKILL.md entry check 6 on `<spec path>` first (a malformed `**Amend-grant:**` line stops here, no tracker call); then `start brainstorm`; `skip brainstorm resume: <spec path>`; `start plan`;
|
|
60
60
|
continue in writing-plans (its own `start plan` is skipped - plan is already
|
|
61
61
|
in_progress).
|
|
62
62
|
- Selected unapproved-draft brainstorming handoff: invoke [`/skill:brainstorming`](../../brainstorming/SKILL.md) with
|
|
@@ -93,7 +93,7 @@ edits override proposals; never rewrite confirmed state silently.
|
|
|
93
93
|
|
|
94
94
|
After confirmation:
|
|
95
95
|
|
|
96
|
-
1. `start brainstorm`; `skip brainstorm resume: <spec path>`; `start plan`.
|
|
96
|
+
1. Run SKILL.md entry check 6 on `<spec path>` (a malformed `**Amend-grant:**` line stops here, no tracker call); then `start brainstorm`; `skip brainstorm resume: <spec path>`; `start plan`.
|
|
97
97
|
2. `plan_check` with `planPath` = the plan's absolute path. FAIL -> print the findings, stop with plan
|
|
98
98
|
in_progress, no `init`.
|
|
99
99
|
3. PASS -> `skip plan` with the same `resume:` reason; for stage verify also
|
|
@@ -68,7 +68,7 @@ subagent({
|
|
|
68
68
|
cwd: "<abs worktree path>",
|
|
69
69
|
task: "Problem statement: <the problem the spec addresses, from its Context section and the user's stated intent>.\n" +
|
|
70
70
|
"Human input (verbatim; off-limits for over-spec):\n```\n<original prompt>\n<ticket AC snapshot, if any>\n<questionary answers that changed scope>\n```\n" +
|
|
71
|
-
"Read the spec at <abs path to doc/specs/...>. The portable citation `reference/documentation-impact.md` in the spec is the pi-gauntlet guideline at <DOCUMENTATION_IMPACT_GUIDELINE>, not a consumer doc; do not flag it as an external reference. Verify the spec's load-bearing claims against the codebase, bounded per your verification-hygiene rules (rg, explicit paths, timeout 30). Critique it on your five axes and emit your template.",
|
|
71
|
+
"Read the spec at <abs path to doc/specs/...>. The portable citation `reference/documentation-impact.md` in the spec is the pi-gauntlet guideline at <DOCUMENTATION_IMPACT_GUIDELINE>, not a consumer doc; do not flag it as an external reference. The `**Amend-grant:**` header line is flow machinery owned by the brainstorming gate; never cut, shrink, flag, or edit it. Verify the spec's load-bearing claims against the codebase, bounded per your verification-hygiene rules (rg, explicit paths, timeout 30). Critique it on your five axes and emit your template.",
|
|
72
72
|
output: "<tmpdir>/member-" + i + "-" + slug(model) + ".md"
|
|
73
73
|
}))
|
|
74
74
|
})
|
|
@@ -103,7 +103,7 @@ subagent({
|
|
|
103
103
|
"Member critiques (already injected via reads — do not search for them):\n" +
|
|
104
104
|
usableMemberPaths.join("\n") + "\n" +
|
|
105
105
|
"Coverage: <N> of <M> members reported<; <slug>: <one-line reason> per missing member>.\n" +
|
|
106
|
-
"The portable citation `reference/documentation-impact.md` in the spec is the pi-gauntlet guideline at <DOCUMENTATION_IMPACT_GUIDELINE>, not a consumer doc; do not flag it as an external reference.\n" +
|
|
106
|
+
"The portable citation `reference/documentation-impact.md` in the spec is the pi-gauntlet guideline at <DOCUMENTATION_IMPACT_GUIDELINE>, not a consumer doc; do not flag it as an external reference. The `**Amend-grant:**` header line is flow machinery owned by the brainstorming gate; never cut, shrink, flag, or edit it.\n" +
|
|
107
107
|
"Consolidate and adjudicate the member critiques. Codebase access is permitted for contested-claim checks only, bounded per your hygiene rules (rg, explicit paths, timeout 30)."
|
|
108
108
|
})
|
|
109
109
|
```
|