pincer-workflow 0.4.1 → 0.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.
Files changed (63) hide show
  1. package/README.md +9 -7
  2. package/bin/pincer.js +58 -5
  3. package/package.json +3 -3
  4. package/template/.agents/skills/pincer-code/SKILL.md +117 -12
  5. package/template/.agents/skills/pincer-evaluate/SKILL.md +57 -10
  6. package/template/.agents/skills/pincer-narrow/SKILL.md +48 -8
  7. package/template/.agents/skills/pincer-plan/SKILL.md +12 -4
  8. package/template/.agents/skills/pincer-release/SKILL.md +32 -3
  9. package/template/.agents/skills/pincer-status/SKILL.md +25 -2
  10. package/template/.claude/commands/pincer-code.md +117 -12
  11. package/template/.claude/commands/pincer-evaluate.md +57 -10
  12. package/template/.claude/commands/pincer-narrow.md +48 -8
  13. package/template/.claude/commands/pincer-plan.md +12 -4
  14. package/template/.claude/commands/pincer-release.md +32 -3
  15. package/template/.claude/commands/pincer-status.md +25 -2
  16. package/template/.claude/hooks/hook-policy.cjs +24 -3
  17. package/template/.claude/references/prd-template.md +11 -4
  18. package/template/.claude/references/ticket-template.md +4 -0
  19. package/template/.codex/README.md +3 -2
  20. package/template/.github/prompts/pincer-code.prompt.md +117 -12
  21. package/template/.github/prompts/pincer-evaluate.prompt.md +57 -10
  22. package/template/.github/prompts/pincer-narrow.prompt.md +48 -8
  23. package/template/.github/prompts/pincer-plan.prompt.md +12 -4
  24. package/template/.github/prompts/pincer-release.prompt.md +32 -3
  25. package/template/.github/prompts/pincer-status.prompt.md +25 -2
  26. package/template/AGENTS.md +22 -0
  27. package/template/docs/dry-run-checklist.md +70 -6
  28. package/template/docs/release-checklist.md +5 -2
  29. package/template/docs/runtime-contracts.md +1683 -0
  30. package/template/scripts/pincer-evidence.cjs +13 -229
  31. package/template/scripts/pincer-runtime/adopt.cjs +132 -0
  32. package/template/scripts/pincer-runtime/agreement.cjs +240 -0
  33. package/template/scripts/pincer-runtime/authorization.cjs +167 -0
  34. package/template/scripts/pincer-runtime/changes.cjs +517 -0
  35. package/template/scripts/pincer-runtime/checks.cjs +48 -0
  36. package/template/scripts/pincer-runtime/coverage.cjs +361 -0
  37. package/template/scripts/pincer-runtime/dispositions.cjs +95 -0
  38. package/template/scripts/pincer-runtime/evidence.cjs +676 -0
  39. package/template/scripts/pincer-runtime/fsutil.cjs +37 -0
  40. package/template/scripts/pincer-runtime/gates.cjs +73 -0
  41. package/template/scripts/pincer-runtime/identity.cjs +163 -0
  42. package/template/scripts/pincer-runtime/impact.cjs +177 -0
  43. package/template/scripts/pincer-runtime/io.cjs +41 -0
  44. package/template/scripts/pincer-runtime/lifecycle.cjs +311 -0
  45. package/template/scripts/pincer-runtime/locator.cjs +158 -0
  46. package/template/scripts/pincer-runtime/migrate.cjs +204 -0
  47. package/template/scripts/pincer-runtime/parse.cjs +316 -0
  48. package/template/scripts/pincer-runtime/phases.cjs +245 -0
  49. package/template/scripts/pincer-runtime/readiness.cjs +97 -0
  50. package/template/scripts/pincer-runtime/requirements.cjs +255 -0
  51. package/template/scripts/pincer-runtime/resume.cjs +205 -0
  52. package/template/scripts/pincer-runtime/routing.cjs +54 -0
  53. package/template/scripts/pincer-runtime/runner.cjs +242 -0
  54. package/template/scripts/pincer-runtime/sanitize.cjs +63 -0
  55. package/template/scripts/pincer-runtime/source.cjs +129 -0
  56. package/template/scripts/pincer-runtime/state.cjs +314 -0
  57. package/template/scripts/pincer-runtime/status.cjs +514 -0
  58. package/template/scripts/pincer-runtime/transaction.cjs +200 -0
  59. package/template/scripts/pincer-runtime/transitions.cjs +134 -0
  60. package/template/scripts/pincer-runtime.cjs +661 -0
  61. package/template/scripts/pincer-status.sh +11 -162
  62. package/template/scripts/pincer-ticket.sh +19 -139
  63. package/template/scripts/pincer-ticket-lib.sh +0 -321
@@ -28,9 +28,13 @@ durable runtime-owned release record is later work.
28
28
  3. Check every applicable item mechanically where possible:
29
29
  - File existence and frontmatter: read the files.
30
30
  - Commit format and story: `git log --oneline`.
31
- - Receipts: every done ticket carries current `last_check` and `verified` evidence;
32
- any status warning fails the audit. Do not call `pincer-ticket.sh` from Release:
33
- it writes receipts and would invalidate the evaluated candidate.
31
+ - Receipts: every done ticket is ready — on a legacy project current `last_check`
32
+ and `verified` receipts, on a migrated project a current passing attempt
33
+ (`node scripts/pincer-runtime.cjs ready` exits 0); any status warning fails the
34
+ audit. Do not call `pincer-ticket.sh` from Release:
35
+ it writes receipts and would invalidate the evaluated candidate. Release never
36
+ runs `verify`, `check` or `done`; `status`, `ready` and the project gate are its
37
+ only commands.
34
38
  - Evidence: `scripts/pincer-status.sh` runs the shared validator
35
39
  (`scripts/pincer-evidence.cjs`) against the manifest `NOTES.md` names. The `Notes`
36
40
  line must read `current` and the `Evidence` line `ok`; any other text fails the
@@ -38,6 +42,31 @@ durable runtime-owned release record is later work.
38
42
  screenshots described in chat: read the manifest's `checks`, requirement
39
43
  dispositions and `visual_review`. Validation establishes that the record is
40
44
  consistent, not that the commands ran — say so if asked.
45
+ - Provenance: status prints a `Provenance` line for the evaluated candidate:
46
+ `runtime (schema 2)` with local attempts consistent, or `legacy (schema 1, authored
47
+ command results)`. A newer local attempt that failed, timed out, was interrupted or
48
+ is still running for the same check and source inputs fails the audit (`ready`
49
+ exits 1 and names the check). A fresh clone reports `local verification history
50
+ unavailable; saved candidate evidence validated only`: state that limit in the
51
+ verdict rather than claiming local verification.
52
+ - Change records (the `Runtime` line reads `changes`): the selected change is
53
+ `completed`, its authorization is `current` for the current agreement, and its
54
+ evaluation locator `.prd/evidence/changes/<id>.json` names the evaluated
55
+ candidate; `node scripts/pincer-runtime.cjs ready` reports `SELECTION_REQUIRED`,
56
+ `LIFECYCLE_BLOCKED`, `DECISION_REQUIRED`, `AUTHORIZATION_REQUIRED` or
57
+ `AGREEMENT_CHANGED` as failures. Release selects, activates and completes nothing;
58
+ historical evidence of a cancelled or superseded change is inspectable but never
59
+ release-ready.
60
+ - Strict coverage (the status line reads `Coverage strict …`): read
61
+ `node scripts/pincer-runtime.cjs coverage` — structure complete, every in-scope
62
+ scenario `delivered` on the evaluated candidate, deferrals and removals backed by
63
+ their decision and user authorization, `delivery` reported as original versus
64
+ agreed scope (never conflate them), adequacy `adequate`; the manifest is schema 3
65
+ and the `Provenance` line reads `runtime (schema 3)`. `ready` names
66
+ `COVERAGE_INCOMPLETE`, `SCOPE_UNAUTHORIZED`, `OBLIGATION_MISSING`,
67
+ `REVIEW_MISSING` and `ADEQUACY_REQUIRED` as failures. A change labeled
68
+ `Coverage unverified` did not adopt strict coverage: audit it under the rules
69
+ above and say so; never imply strict coverage was established.
41
70
  - Every file the manifest lists is tracked, and `git status --short` is empty before
42
71
  and after the audit.
43
72
  - Run the repository's candidate-wide release gate directly (`npm test`, or the
@@ -15,13 +15,36 @@ start of a session. Read-only: change nothing.
15
15
  1. Run `scripts/pincer-status.sh`. It reads the artifacts on disk (`.prd/`, `tickets/`,
16
16
  `NOTES.md`) and prints the PRD state and profile, every ticket with its state and
17
17
  clock-based elapsed time, what is blocked, wall-clock build time while a ticket is in
18
- progress or against an explicit user budget, the evidence verdict for the evaluated
18
+ progress or against an explicit user budget, the `Runtime` line (legacy receipts or
19
+ the registered change), the evidence verdict and `Provenance` line for the evaluated
19
20
  candidate, any warnings (each readiness problem once), and the next command to run.
21
+ `scripts/pincer-status.sh --json` prints one status object with reason codes and the
22
+ next action for tooling; `node scripts/pincer-runtime.cjs ready [T-NN]` is the
23
+ read-only gate. On a project with change records (`Runtime changes …`) run
24
+ `node scripts/pincer-runtime.cjs resume` as well: it reports the selected change, its
25
+ lifecycle, agreement and authorization, decisions, references, tickets, attempts,
26
+ candidate, the authored handoff note and the next command, and never writes;
27
+ `change list` shows every retained change, `status --change <id>` and
28
+ `resume --change <id>` inspect another one without selecting it. `resume` is the
29
+ report; `change resume <id>` is the lifecycle operation. The `Coverage` line says
30
+ `strict` or `unverified`; on a strict change `node scripts/pincer-runtime.cjs coverage`
31
+ (and `impact` after an edit) name the exact scenario, ticket, check or decision
32
+ that is next — quote them rather than inferring coverage from the ticket list.
20
33
  2. Report in three lines: where the workflow is, what is in progress or blocked, and the
21
- next command. Quote the `Next` line as-is.
34
+ next command. Quote the `Next` line as-is. When the `Runtime` line says `legacy`,
35
+ add the register or migrate command it names as the step that precedes the next
36
+ ticket (fresh project → `register`, legacy receipts → `migrate --preview`, a v0.5.0
37
+ binding → `migrate --preview`, no selection → `change select <id>`).
22
38
  3. If a ticket is `in_progress`, read it and `git status`, then offer to resume it with
23
39
  `$pincer-code T-{NN}`. If the script printed a warning, surface it — a done ticket
24
40
  without a receipt was marked by hand and needs `scripts/pincer-ticket.sh verify T-{NN}`.
25
41
  Never restore a ticket file from git to clear a warning; a failed attempt is a record.
26
42
  The one exception is the tree-back-at-candidate case in the recovery section of
27
43
  `$pincer-code`: the user restores the ticket file, and nothing is verified or committed.
44
+ It applies only when the recorded failure is explained by a since-reverted source
45
+ change and the block passes in the same execution context as `verify`; an
46
+ unexplained failure (a service down, a missing dependency) stays a failure until the
47
+ environment is repaired and `verify` passes again. After migration never restore a
48
+ ticket file or delete `.pincer/runtime` to clear a warning: repair the cause and run
49
+ `verify` again; a dead session's `running` attempt is finalized by
50
+ `node scripts/pincer-runtime.cjs recover`.
@@ -16,6 +16,17 @@ Ticket state lives in the ticket file's frontmatter and is written **only** by
16
16
  Verification block and stamps a receipt only on a green exit; `done` refuses without a
17
17
  receipt that matches the current check, or with unticked acceptance criteria. Never edit
18
18
  `status`, `started`, `last_check`, `verified`, or `finished` by hand — on Claude Code a hook blocks it.
19
+ On a migrated project (a change binding under `.prd/changes/`; the `Runtime` line of
20
+ `scripts/pincer-status.sh` names it) `verify` records an attempt under `.pincer/runtime/`
21
+ and writes no receipt into the ticket, and `done` consumes the current passing attempt
22
+ against the current source without re-running the check. `.pincer/`, `.prd/changes/` and `.prd/evidence/changes/`
23
+ are written only by the runtime; never edit or delete them by hand. On a project with
24
+ change records (`Runtime changes …`) every `start`, `verify` and `done` first passes
25
+ the change gate: the ticket's change must be selected in this worktree, `active`
26
+ (`verify` also runs on a `completed` change), on a compatible branch, and authorized
27
+ for the current agreement — otherwise the command refuses with `SELECTION_REQUIRED`,
28
+ `WRONG_CHANGE`, `LIFECYCLE_BLOCKED`, `BASE_MISMATCH`, `DECISION_REQUIRED`,
29
+ `AUTHORIZATION_REQUIRED` or `AGREEMENT_CHANGED` before anything runs or is written.
19
30
 
20
31
  ## Before the loop
21
32
 
@@ -23,7 +34,34 @@ Run `scripts/pincer-status.sh`. It lists every ticket's state, what is blocked,
23
34
  build time from the clock, and the next action. If a ticket is `in_progress`, you are
24
35
  resuming: read it, check `git status` / `git diff` for uncommitted work, and continue
25
36
  from wherever the receipt says you are. Do not ask the user to reconfirm unchanged,
26
- previously authorized work.
37
+ previously authorized work. Read the `Runtime` line before the first ticket. `changes` (change records under
38
+ `.prd/changes/`) → run `node scripts/pincer-runtime.cjs resume` and follow its `Next`
39
+ line: it names the selected change, its lifecycle state, the agreement and the
40
+ authorization verdict, the blockers in order and the exact next command, all from the
41
+ files on disk. Select the change to work on (`node scripts/pincer-runtime.cjs change
42
+ select <id>`; selection is local metadata and touches no source), activate it
43
+ (`change activate <id>`; refused until the user's authorization is recorded with
44
+ `change authorize` and no consequential decision is open) and resume a paused change
45
+ with `change resume <id>`. On a change with strict coverage (`Coverage strict …` in status) also read
46
+ `node scripts/pincer-runtime.cjs coverage` — it names the scenario, ticket, check or
47
+ decision that is next and every structural gap (`COVERAGE_INCOMPLETE`,
48
+ `SCOPE_UNAUTHORIZED`, `OBLIGATION_MISSING`) — and, after any PRD, ticket or map edit,
49
+ `node scripts/pincer-runtime.cjs impact` (`--from G-NN` for another baseline): it
50
+ lists the affected scenarios, tickets and checks with reasons and the dependency
51
+ dependents separately, and reports an unscoped PRD change or unavailable history
52
+ rather than "no impact". `legacy` and no ticket of this PRD carries legacy
53
+ receipts → register now (`node scripts/pincer-runtime.cjs register --prd .prd/prd-vN.md`,
54
+ commit `.prd/changes/` and `.gitignore` as `Register PRD vN`), then record the user's
55
+ approval (`change authorize …`, as `/pincer-narrow` describes), select and activate.
56
+ `legacy` with legacy receipts, or a v0.5.0 binding (`Runtime change <id> · revision …`)
57
+ → run `node scripts/pincer-runtime.cjs migrate --preview --prd .prd/prd-vN.md`, show
58
+ the plan (backups, receipts imported as history, the converted binding, the
59
+ `.gitignore` line, the local selection) and ask once whether to apply. Apply only on
60
+ a yes, then commit the rewritten tickets, `.gitignore` and the record as `Migrate PRD
61
+ vN to the runtime`. The migrated change is planned with no authorization: record the
62
+ user's actual earlier instruction with `change authorize` (the v0.5.0 free text is
63
+ history only) and activate it. Never migrate silently, and never apply when the
64
+ preview reports a conflict.
27
65
 
28
66
  ## Loop (per ticket, in dependency order)
29
67
 
@@ -38,7 +76,9 @@ previously authorized work.
38
76
  dispatch a subagent with a clean prompt: paste the full ticket body, the relevant
39
77
  conventions, and nothing else.
40
78
  3. **Verify:** `scripts/pincer-ticket.sh verify T-{NN}` — runs the Verification block and
41
- writes the receipt only if it exits 0. Red fix and re-run; report the actual output,
79
+ writes the receipt only if it exits 0 (after migration it records an attempt with the
80
+ captured log under `.pincer/runtime/` and writes no receipt into the ticket; readiness
81
+ derives from the latest attempt and the current source). Red → fix and re-run; report the actual output,
42
82
  not assumptions. Green output is the definition of done, not your confidence. If the
43
83
  check only validated syntax or a build, say so — that is not behavioral proof. A
44
84
  visual judgment is recorded separately in evaluation, not as the receipt, and a tool
@@ -56,7 +96,10 @@ previously authorized work.
56
96
  - No error path leaks internals (stack traces, key names with values) to the client.
57
97
  If the review changed code, run `verify` again — the receipt must match the code you commit.
58
98
  5. **Close the ticket:** tick every verified acceptance-criteria checkbox (`- [ ]` → `- [x]`;
59
- editing the checkboxes is allowed), then `scripts/pincer-ticket.sh done T-{NN}`. A
99
+ editing the checkboxes is allowed), then `scripts/pincer-ticket.sh done T-{NN}`. After
100
+ migration `done` consumes the current passing attempt and does not re-run the check; it
101
+ refuses with a reason code (`SOURCE_CHANGED`, `CHECK_CHANGED`, `CHECK_FAILED`,
102
+ `CRITERIA_UNTICKED`, …) and the next step when the latest attempt is not current. A
60
103
  criterion that was cut is a scope change to record in the PRD, not a box to skip.
61
104
  Inspect `git status --short`, preserve pre-existing staged work, and stage only the
62
105
  explicit paths changed for this ticket plus its ticket file. Review `git diff --cached`
@@ -87,20 +130,78 @@ the script or `scripts/pincer-status.sh` printed, and hand the repair to the use
87
130
  performs it in their own terminal. Then return through the lifecycle — `start`,
88
131
  `verify`, `done` — so the ticket carries fresh verification; a restored receipt is
89
132
  never evidence. Do not recommend restoring source files or unrelated edits as routine
90
- ticket repair. One exception: when the PRD is built with valid candidate evidence,
133
+ ticket repair. One exception: when the PRD is built with valid candidate evidence;
91
134
  tracked files other than the ticket file being restored match the evaluated candidate
92
- (or the candidate plus its evidence-only commit) with nothing untracked, and the
93
- ticket's Verification block passes when run
94
- directly rather than through `verify` (which would write a receipt), then
135
+ (or the candidate plus its evidence-only commit) with nothing untracked; the recorded
136
+ failure is explained by a working-tree change that has since been reverted (the failed
137
+ `last_check` was stamped while source differed from the candidate, and that difference
138
+ is gone); and the ticket's Verification block passes when run
139
+ directly rather than through `verify` (which would write a receipt), in the
140
+ same execution context as `verify` — the same shell, working directory, `PATH`
141
+ and environment, with no substituted binary and no repair made first — then
95
142
  the committed evaluation still describes the tree. Say so, name the exact command
96
143
  for the user to restore the ticket file in their own terminal, and
97
144
  do not run `verify`, refresh the receipt or commit anything — the restored file is
98
145
  what is already committed, not new evidence. If the block fails on that clean tree,
99
146
  the failure is real: keep the failed `last_check` and repair through the lifecycle.
147
+ A changed executable, runner, working directory or environment repair requires a
148
+ new recorded verification through `verify`; the exception does not apply to it.
149
+ An unexplained failure cannot be cleared by restoring a receipt: when no
150
+ since-reverted source change explains it (a service down, a missing dependency, a
151
+ check that reads external data), keep the failure, name the cause you observed, and
152
+ ask for the environment to be repaired before `verify` runs again.
100
153
  If source still differs from the candidate, name the differing paths and let the
101
154
  user decide rather than asking which way to fix them; permission to restore a ticket
102
- does not authorize discarding source changes. Automated recovery that preserves
103
- attempt history is later work (M1).
155
+ does not authorize discarding source changes.
156
+ After migration (a change binding exists) recovery is the lifecycle itself: retain the
157
+ failure, repair the cause, run `verify` again; readiness derives from the latest attempt,
158
+ both attempts stay in `.pincer/runtime/` and no tracked file changes. Never restore a
159
+ ticket file or delete `.pincer/runtime` to obtain a green status; the legacy exception
160
+ above applies only before migration. A session that died mid-`verify` leaves a `running`
161
+ attempt: run `node scripts/pincer-runtime.cjs recover`, which finalizes it as
162
+ `interrupted` once the owner process is gone, then `verify` again.
163
+
164
+ ## Changes: pausing, decisions and completion
165
+
166
+ - Stopping before the change is complete (end of session, switching to another
167
+ change): `node scripts/pincer-runtime.cjs change pause <id> --reason "<why>" --note "<handoff for the next session>"`
168
+ and commit the record. Pausing keeps every ticket state, attempt and authorization;
169
+ it refuses while a check is running (`recover` first if its owner died). A fresh
170
+ session runs `resume`, then `change resume <id>` under the existing authorization —
171
+ do not ask the user to re-approve unchanged scope. Another change's work in the
172
+ meantime makes this change's passing attempts `SOURCE_CHANGED`; verify again, do
173
+ not ask for approval again.
174
+ - A newly discovered consequential choice: `node scripts/pincer-runtime.cjs change decide <id> --summary "<the question>"`
175
+ blocks execution (`DECISION_REQUIRED`) until the user answers; record the answer with
176
+ `change decide <id> --resolve D-NN --reference "<where>" --excerpt "<the user's words>"`,
177
+ then `change authorize <id> --agreement <digest> --reference … --excerpt … --decision D-NN`.
178
+ A revision within the user's delegation (for example an added regression check for
179
+ approved behavior) records `change authorize <id> --agreement <digest> --delegated --basis A-NN --explanation "<why it stays within the delegation>"`
180
+ without asking again, and the changed check still needs fresh verification.
181
+ - Editing the PRD under its filename, or a ticket's acceptance text, dependencies,
182
+ size, timeout, association or check — and, with strict coverage, a scenario's text,
183
+ a map link, a declared command or timeout, or a scope entry — changes the agreement:
184
+ execution refuses with `AGREEMENT_CHANGED` (status shows the structural difference;
185
+ `impact` explains it) until its disposition is recorded as above. Ticking criteria, starting or closing tickets and recording
186
+ attempts never change it. An `AGREEMENT_CHANGED` caused by an edit this session
187
+ did not make — a revised PRD, an added or changed ticket found on resume — is a
188
+ consequential decision: raise it with `change decide <id> --summary "<what changed>"`,
189
+ report the structural difference (and the `impact` report) and stop. A general instruction to continue,
190
+ resume or not re-ask never authorizes new scope; record a `user` authorization for
191
+ the revised agreement only for an instruction that names the revised content. With strict coverage a scenario that will not be delivered is
192
+ never dropped from the map or the PRD: it is deferred or removed through a decision
193
+ the user resolves naming it, a `scope` entry (a removal keeps a tombstone naming the
194
+ prior agreement) and an authorization naming that decision; `coverage` reports
195
+ `OBLIGATION_MISSING` or `SCOPE_UNAUTHORIZED` until then, and `change complete`
196
+ refuses. A revised check declaration (a stricter command, an added check) within the
197
+ user's delegation is a `--delegated` authorization and needs fresh verification.
198
+ - When every ticket is done and ready: `node scripts/pincer-runtime.cjs change complete <id>`
199
+ (it refuses unfinished tickets, unticked criteria, stale or failed verification and
200
+ open decisions; with strict coverage also an incomplete map, an unauthorized
201
+ disposition or a missing obligation, before the ticket gate) and commit the record
202
+ as `Complete PRD vN`. Completion never asks for candidate evidence. Completed means ready
203
+ for evaluation, not evaluated or released; a later finding is `change reopen <id> --reason …`
204
+ plus a fix ticket.
104
205
 
105
206
  ## Budget rules
106
207
 
@@ -113,7 +214,8 @@ attempt history is later work (M1).
113
214
 
114
215
  ## When all tickets are done
115
216
 
116
- Update the PRD to `status: built` and commit that change on its own (`PRD vN: built`).
217
+ On a project with change records, complete the change first (`change complete <id>`,
218
+ committed as `Complete PRD vN`). Then update the PRD to `status: built` and commit that change on its own (`PRD vN: built`).
117
219
  The built transition is part of the candidate that `/pincer-evaluate` reviews; it is
118
220
  never moved into a later evidence-only commit. Then finish with:
119
221
  "All tickets built. Run `/pincer-evaluate` for a final quality pass."
@@ -125,6 +227,9 @@ material choice not already authorized, and prepare the concrete proposal before
125
227
  asking. A decision the user delegated (for example "pick the architecture") does not
126
228
  need another approval when you exercise it, but a newly discovered consequential
127
229
  choice is surfaced before implementation. Record the authorization basis and the
128
- scope it covers in the PRD or the handover. An agent-written record or a status
230
+ scope it covers in the PRD or the handover, and on a project with change records as
231
+ a `change authorize` record (the user's words as the excerpt, or a `--delegated`
232
+ disposition with its basis). An agent-written record or a status
129
233
  field is not authenticated human approval. When resuming without the context that
130
- granted authorization, do not invent it — ask.
234
+ granted authorization, do not invent it — read the `resume` report; an authorization
235
+ it reports as `current` needs no repeat approval, and any other verdict is asked.
@@ -19,8 +19,10 @@ run the pipeline, then present results.
19
19
  that uncertainty before claiming a complete review. Record full commit IDs for
20
20
  `base` and `candidate` (`git rev-parse HEAD`), then review `git diff <base>..<candidate>`.
21
21
  The candidate is the clean, committed tree that already includes the implementation,
22
- the ticket closures and the PRD `status: built` commit: `git status --short` must be
23
- empty before review. If anything is uncommitted or the PRD is not yet built, return
22
+ the ticket closures, on a project with change records the `change complete` commit
23
+ (the `Runtime` line reads `… · completed ·`; `check` and `evidence export` refuse an
24
+ active, paused or unauthorized change), and the PRD `status: built` commit:
25
+ `git status --short` must be empty before review. If anything is uncommitted or the PRD is not yet built, return
24
26
  to `/pincer-code`; do not review a dirty tree.
25
27
  2. Dispatch a `code-quality-reviewer` agent with: the diff, the PRD's Success Criteria and
26
28
  Scope sections, and the list of tickets. If the diff is large, split by area and
@@ -28,7 +30,13 @@ run the pipeline, then present results.
28
30
  in a separate pass, applying `.claude/agents/code-quality-reviewer.md` as the rubric.)
29
31
  Keep the reviewer's report — or its explicit no-findings statement — for step 9,
30
32
  where it is saved as an artifact; a review that left no record cannot be audited.
31
- 3. Yourself, in parallel, check spec compliance. For every requirement `R-NN` in the
33
+ 3. Yourself, in parallel, check spec compliance. On a change with strict coverage
34
+ (`Coverage strict …` in status) start from `node scripts/pincer-runtime.cjs coverage`:
35
+ its structure must be complete, and its scenario rows are the obligations — the
36
+ export derives every disposition from the map and the outcomes, so you do not
37
+ author `requirements`; your judgment is recorded as `adequacy` (whether the
38
+ declared checks and reviews really establish their scenarios) and in
39
+ `coverage_review`. Otherwise, for every requirement `R-NN` in the
32
40
  PRD record one disposition: `delivered` (evidence on this candidate), `blocked`
33
41
  (required behavior failed or was left unverified — this blocks PASS; do not relabel
34
42
  it a known limitation to pass), or `deferred` (only with explicit user authorization;
@@ -62,7 +70,41 @@ run the pipeline, then present results.
62
70
  material decision; never make an ad-hoc `review: fixes` commit. Every fix commit
63
71
  produces a new candidate: re-record `candidate`, re-run the checks against it, and
64
72
  write fresh evidence in step 9 — never reuse a manifest from a previous candidate.
65
- 9. Persist evidence for the candidate under `.prd/evidence/prd-vN/<candidate>/`:
73
+ 9. Persist evidence for the candidate under `.prd/evidence/prd-vN/<candidate>/`.
74
+ Strict coverage: run every declared command check as
75
+ `node scripts/pincer-runtime.cjs check C-NN --candidate <sha>` (no command, no
76
+ timeout: the map's declaration is the only source, and a supplied command is
77
+ `CHECK_UNDECLARED`); record each declared review or visual obligation in the
78
+ draft with its `result` and an artifact saved under the candidate's evidence
79
+ directory (a required one that is not passed with an artifact is
80
+ `REVIEW_MISSING`); write `adequacy: { verdict: "adequate" | "inadequate", note }`;
81
+ list every declared check once and no `requirements` (they are derived). The
82
+ export writes the inventory and map snapshots under `coverage/`, derives the
83
+ scenario and requirement rows and `delivery` (original versus agreed scope) and
84
+ validates them against the committed candidate; an `inadequate` judgment or a
85
+ failed required check is recorded honestly and blocks readiness. Migrated
86
+ project without strict coverage (the `Runtime` status line names a change): run
87
+ each executable check through the runtime on the clean candidate view —
88
+ `node scripts/pincer-runtime.cjs check C-NN --candidate <sha> -- <command>` (one
89
+ command per check, the command line as run; `npm test` stays one aggregate check) —
90
+ then write the authored fields to a draft outside the evidence directory, for
91
+ example `.pincer/drafts/<sha>.json`: `environment.tools` and `environment.limitations`,
92
+ `coverage_review`, `requirements`, review and visual checks with their saved
93
+ artifacts, `visual_review`, and a stub `{"id": "C-NN", "kind": "command",
94
+ "required": true|false}` for each executable check. Then run
95
+ `node scripts/pincer-runtime.cjs evidence export --candidate <sha> --base <base> --prd .prd/prd-vN.md --draft <file>`.
96
+ The export writes `checks/C-NN.log` from the captured logs, fills `command`,
97
+ `result`, `provenance: runtime` and `attempt` from the attempts, labels review and
98
+ visual checks `provenance: authored`, computes the digests and writes an evidence
99
+ schema 2 manifest; it refuses a dirty tree, a HEAD that is not the candidate, a stub
100
+ without an attempt, and a `passed` or `failed` command result written by hand. On a
101
+ project with change records the export also appends the evaluation to the change's
102
+ locator `.prd/evidence/changes/<id>.json` (the identity of this change's
103
+ evaluation; root `NOTES.md` stays the human summary and may be overwritten by a
104
+ later change's evaluation without losing this one) — commit the locator with the
105
+ evidence. A tool that cannot run is recorded as an authored command check with
106
+ `result: unverified` and a note, as before. Legacy project (no change binding):
107
+ author the schema 1 manifest as follows.
66
108
  - `checks/C-NN.log` — the command and a redacted summary or safe log of each
67
109
  executable check. Never secrets, never an environment dump. Record
68
110
  one check per command: `command` holds the command line as run, never prose
@@ -102,11 +144,13 @@ run the pipeline, then present results.
102
144
  evidence: .prd/evidence/prd-vN/<candidate>/manifest.json
103
145
  ---
104
146
  ```
105
- Then commit NOTES.md, the manifest and its listed artifacts and nothing else
147
+ Then commit NOTES.md, the manifest, its listed artifacts and (change records) the
148
+ evaluation locator — and nothing else —
106
149
  as `evaluate: PRD vN candidate <short sha>`. Status accepts this later commit only
107
- when its diff from the candidate is limited to `NOTES.md` and the evidence files
108
- the manifest lists; changes to source, tests, configuration, tickets, the PRD or
109
- other evaluations require reevaluation. Legacy notes without these references
150
+ when its diff from the candidate is limited to `NOTES.md`, the candidate's evidence
151
+ directories and evaluation locators; changes to source, tests, configuration,
152
+ tickets, the PRD or the change record (a lifecycle transition after the
153
+ candidate) require reevaluation. Legacy notes without these references
110
154
  do not establish readiness. Then describe what was built, what was cut
111
155
  and why, known issues, and what you'd do next with more time. Then a **Handover**
112
156
  section, written for the stranger who inherits this repo in six months: how to get
@@ -124,6 +168,9 @@ material choice not already authorized, and prepare the concrete proposal before
124
168
  asking. A decision the user delegated (for example "pick the architecture") does not
125
169
  need another approval when you exercise it, but a newly discovered consequential
126
170
  choice is surfaced before implementation. Record the authorization basis and the
127
- scope it covers in the PRD or the handover. An agent-written record or a status
171
+ scope it covers in the PRD or the handover, and on a project with change records as
172
+ a `change authorize` record (the user's words as the excerpt, or a `--delegated`
173
+ disposition with its basis). An agent-written record or a status
128
174
  field is not authenticated human approval. When resuming without the context that
129
- granted authorization, do not invent it — ask.
175
+ granted authorization, do not invent it — read the `resume` report; an authorization
176
+ it reports as `current` needs no repeat approval, and any other verdict is asked.
@@ -32,14 +32,25 @@ discovered consequential choice is surfaced before implementation.
32
32
  - Build the requirement map: for every `R-NN` in the PRD and each of its
33
33
  scenarios, name the ticket that owns the implementation and the executable
34
34
  check that exercises it, or an explicit review method when no executable check
35
- exists. Record the IDs in each ticket's Context as `Implements: R-NN, R-MM`.
36
- Enabling work that implements no requirement states its purpose in the ticket
37
- Objective. Resolve missing coverage and conflicting criteria with the user
38
- before implementation; do not start with an unmapped required scenario.
35
+ exists. Record the IDs in each ticket's Context as `Implements: R-NN, R-MM`
36
+ (a navigation aid). Enabling work that implements no requirement states its purpose
37
+ in the ticket Objective. Resolve missing coverage and conflicting criteria with
38
+ the user before implementation; do not start with an unmapped required scenario. On a change with change records, author the map once as
39
+ `.prd/coverage/<change id>.json` (coverage map schema 1, "Coverage map" in
40
+ `docs/runtime-contracts.md`): one `scenarios` row per `S-NN` naming its
41
+ implementing tickets and declared checks, every ticket of the change in
42
+ `tickets` as `implements` or `enables` (with a rationale), each check declared
43
+ once in `checks` with its kind, `required` flag and, for a command, the exact
44
+ command line and timeout, and a `scope` entry (`deferred` or `removed`) for a
45
+ scenario this change will not deliver, naming the decision that records the
46
+ user's choice. The map is authored work you edit by hand; the runtime never
47
+ rewrites it, and it validates it against the PRD's definitions.
39
48
  - Every ticket gets a runnable command in its Verification block — a fenced `bash`
40
49
  block that exits 0 only when the ticket is done. `scripts/pincer-ticket.sh verify`
41
50
  runs it verbatim and stamps the receipt that `done` requires, so it must be
42
- non-interactive and self-contained (no "check by hand").
51
+ non-interactive and self-contained (no "check by hand"). An optional
52
+ `timeout: <seconds>` frontmatter field (default 600) bounds the run; it is part of
53
+ the check identity, so changing it invalidates earlier passes.
43
54
  - Each Verification section opens with `Proves:` — what the check establishes and
44
55
  which regression it detects. A check for an executable change must exercise
45
56
  observable behavior (including relevant rejection paths and, in brownfield work,
@@ -81,7 +92,33 @@ existing authorization for the same scope and order.
81
92
  inspect existing staged changes, stage that PRD and the explicit new ticket paths,
82
93
  review `git diff --cached`, and commit only those paths. Ask first — and finalize
83
94
  once it is resolved — only when step 4 surfaced a newly discovered consequential
84
- choice or a scope change the PRD does not cover. Finish with:
95
+ choice or a scope change the PRD does not cover. Then register the change when the
96
+ `Runtime` status line says `legacy` and no ticket of this PRD carries legacy
97
+ receipts, or `changes` (the project already keeps change records):
98
+ `node scripts/pincer-runtime.cjs register --prd .prd/prd-vN.md` writes the change
99
+ record `.prd/changes/prd-vN.json` (retaining every earlier change); stage
100
+ `.prd/changes/` and `.gitignore` (registration adds `.pincer/` to it) and commit them
101
+ as `Register PRD vN`. Then record the user's actual approval against the agreement
102
+ the record binds — `node scripts/pincer-runtime.cjs change show prd-vN --json`
103
+ prints the agreement digest — with
104
+ `node scripts/pincer-runtime.cjs change authorize prd-vN --agreement <digest> --reference "<where the user said it>" --excerpt "<the user's approval, quoted>"`,
105
+ select it for this worktree (`node scripts/pincer-runtime.cjs change select prd-vN`)
106
+ and commit `.prd/changes/` as `Authorize PRD vN`. When the map was authored, adopt
107
+ strict coverage explicitly: `node scripts/pincer-runtime.cjs coverage adopt --preview --change prd-vN`
108
+ shows the inventory, the map digest and the agreement it records (it refuses an
109
+ incomplete map, naming the scenario or ticket); `--apply` writes the schema 3
110
+ record with a backup and grants nothing — record the user's approval of that
111
+ agreement with `change authorize` (the same instruction, if it named this
112
+ breakdown; a delegated disposition needs its basis) and commit `.prd/coverage/`
113
+ and `.prd/changes/` as `Adopt strict coverage for PRD vN`. A scenario the user
114
+ deferred or removed is a decision: `change decide --summary "<the choice>"`,
115
+ `--resolve D-NN` with the user's words naming the scenario, the `scope` entry in
116
+ the map, then `change authorize … --decision D-NN`. Never record a disposition
117
+ the user did not state; `coverage` reports `SCOPE_UNAUTHORIZED` until it is. The excerpt records the user's own
118
+ words; running the command proves nothing by itself, and a registration, a PRD
119
+ status or a passing check never becomes an authorization. A project whose tickets
120
+ carry legacy receipts, or that still holds a v0.5.0 binding (`Runtime change <id> ·
121
+ revision …`), is migrated from `/pincer-code` after a preview, never here. Finish with:
85
122
  "Tickets ready in `tickets/`. Run `/pincer-code` to start implementing."
86
123
 
87
124
  ## Authorization rule (shared by plan, narrow, code and evaluate)
@@ -91,6 +128,9 @@ material choice not already authorized, and prepare the concrete proposal before
91
128
  asking. A decision the user delegated (for example "pick the architecture") does not
92
129
  need another approval when you exercise it, but a newly discovered consequential
93
130
  choice is surfaced before implementation. Record the authorization basis and the
94
- scope it covers in the PRD or the handover. An agent-written record or a status
131
+ scope it covers in the PRD or the handover, and on a project with change records as
132
+ a `change authorize` record (the user's words as the excerpt, or a `--delegated`
133
+ disposition with its basis). An agent-written record or a status
95
134
  field is not authenticated human approval. When resuming without the context that
96
- granted authorization, do not invent it — ask.
135
+ granted authorization, do not invent it — read the `resume` report; an authorization
136
+ it reports as `current` needs no repeat approval, and any other verdict is asked.
@@ -91,8 +91,13 @@ concrete scope and architecture; do not repeat an approval already given for the
91
91
  In Requirements, assign stable `R-NN` IDs within the selected PRD: a revision
92
92
  keeps existing IDs and adds new ones, never renumbers. Every requirement has
93
93
  observable acceptance scenarios, the relevant failure paths, and the existing
94
- behavior it must preserve `/pincer-narrow` maps each scenario to a ticket and
95
- a check, and `/pincer-evaluate` dispositions every ID.
94
+ behavior it must preserve, each written as a bold `- **S-NN:** …` item under its
95
+ requirement heading (the template's grammar; the runtime parses exactly these
96
+ definitions into the inventory that strict coverage tracks, and a requirement
97
+ without a scenario is invalid there) — `/pincer-narrow` maps each scenario to a
98
+ ticket and a check in the coverage map, and `/pincer-evaluate` dispositions every
99
+ ID. A supplied PRD keeps its own uppercase IDs (`REQ-1`, `AC-3`); only its
100
+ definition syntax is adapted, and the mapping table records what changed.
96
101
  2. Include optional sections when risk or the product context warrants them.
97
102
  3. Save to the next unused `.prd/prd-v{N}.md` (create `.prd/` if needed), with `N`
98
103
  matching the filename and frontmatter:
@@ -119,6 +124,9 @@ material choice not already authorized, and prepare the concrete proposal before
119
124
  asking. A decision the user delegated (for example "pick the architecture") does not
120
125
  need another approval when you exercise it, but a newly discovered consequential
121
126
  choice is surfaced before implementation. Record the authorization basis and the
122
- scope it covers in the PRD or the handover. An agent-written record or a status
127
+ scope it covers in the PRD or the handover, and on a project with change records as
128
+ a `change authorize` record (the user's words as the excerpt, or a `--delegated`
129
+ disposition with its basis). An agent-written record or a status
123
130
  field is not authenticated human approval. When resuming without the context that
124
- granted authorization, do not invent it — ask.
131
+ granted authorization, do not invent it — read the `resume` report; an authorization
132
+ it reports as `current` needs no repeat approval, and any other verdict is asked.
@@ -26,9 +26,13 @@ durable runtime-owned release record is later work.
26
26
  3. Check every applicable item mechanically where possible:
27
27
  - File existence and frontmatter: read the files.
28
28
  - Commit format and story: `git log --oneline`.
29
- - Receipts: every done ticket carries current `last_check` and `verified` evidence;
30
- any status warning fails the audit. Do not call `pincer-ticket.sh` from Release:
31
- it writes receipts and would invalidate the evaluated candidate.
29
+ - Receipts: every done ticket is ready — on a legacy project current `last_check`
30
+ and `verified` receipts, on a migrated project a current passing attempt
31
+ (`node scripts/pincer-runtime.cjs ready` exits 0); any status warning fails the
32
+ audit. Do not call `pincer-ticket.sh` from Release:
33
+ it writes receipts and would invalidate the evaluated candidate. Release never
34
+ runs `verify`, `check` or `done`; `status`, `ready` and the project gate are its
35
+ only commands.
32
36
  - Evidence: `scripts/pincer-status.sh` runs the shared validator
33
37
  (`scripts/pincer-evidence.cjs`) against the manifest `NOTES.md` names. The `Notes`
34
38
  line must read `current` and the `Evidence` line `ok`; any other text fails the
@@ -36,6 +40,31 @@ durable runtime-owned release record is later work.
36
40
  screenshots described in chat: read the manifest's `checks`, requirement
37
41
  dispositions and `visual_review`. Validation establishes that the record is
38
42
  consistent, not that the commands ran — say so if asked.
43
+ - Provenance: status prints a `Provenance` line for the evaluated candidate:
44
+ `runtime (schema 2)` with local attempts consistent, or `legacy (schema 1, authored
45
+ command results)`. A newer local attempt that failed, timed out, was interrupted or
46
+ is still running for the same check and source inputs fails the audit (`ready`
47
+ exits 1 and names the check). A fresh clone reports `local verification history
48
+ unavailable; saved candidate evidence validated only`: state that limit in the
49
+ verdict rather than claiming local verification.
50
+ - Change records (the `Runtime` line reads `changes`): the selected change is
51
+ `completed`, its authorization is `current` for the current agreement, and its
52
+ evaluation locator `.prd/evidence/changes/<id>.json` names the evaluated
53
+ candidate; `node scripts/pincer-runtime.cjs ready` reports `SELECTION_REQUIRED`,
54
+ `LIFECYCLE_BLOCKED`, `DECISION_REQUIRED`, `AUTHORIZATION_REQUIRED` or
55
+ `AGREEMENT_CHANGED` as failures. Release selects, activates and completes nothing;
56
+ historical evidence of a cancelled or superseded change is inspectable but never
57
+ release-ready.
58
+ - Strict coverage (the status line reads `Coverage strict …`): read
59
+ `node scripts/pincer-runtime.cjs coverage` — structure complete, every in-scope
60
+ scenario `delivered` on the evaluated candidate, deferrals and removals backed by
61
+ their decision and user authorization, `delivery` reported as original versus
62
+ agreed scope (never conflate them), adequacy `adequate`; the manifest is schema 3
63
+ and the `Provenance` line reads `runtime (schema 3)`. `ready` names
64
+ `COVERAGE_INCOMPLETE`, `SCOPE_UNAUTHORIZED`, `OBLIGATION_MISSING`,
65
+ `REVIEW_MISSING` and `ADEQUACY_REQUIRED` as failures. A change labeled
66
+ `Coverage unverified` did not adopt strict coverage: audit it under the rules
67
+ above and say so; never imply strict coverage was established.
39
68
  - Every file the manifest lists is tracked, and `git status --short` is empty before
40
69
  and after the audit.
41
70
  - Run the repository's candidate-wide release gate directly (`npm test`, or the
@@ -13,13 +13,36 @@ start of a session. Read-only: change nothing.
13
13
  1. Run `scripts/pincer-status.sh`. It reads the artifacts on disk (`.prd/`, `tickets/`,
14
14
  `NOTES.md`) and prints the PRD state and profile, every ticket with its state and
15
15
  clock-based elapsed time, what is blocked, wall-clock build time while a ticket is in
16
- progress or against an explicit user budget, the evidence verdict for the evaluated
16
+ progress or against an explicit user budget, the `Runtime` line (legacy receipts or
17
+ the registered change), the evidence verdict and `Provenance` line for the evaluated
17
18
  candidate, any warnings (each readiness problem once), and the next command to run.
19
+ `scripts/pincer-status.sh --json` prints one status object with reason codes and the
20
+ next action for tooling; `node scripts/pincer-runtime.cjs ready [T-NN]` is the
21
+ read-only gate. On a project with change records (`Runtime changes …`) run
22
+ `node scripts/pincer-runtime.cjs resume` as well: it reports the selected change, its
23
+ lifecycle, agreement and authorization, decisions, references, tickets, attempts,
24
+ candidate, the authored handoff note and the next command, and never writes;
25
+ `change list` shows every retained change, `status --change <id>` and
26
+ `resume --change <id>` inspect another one without selecting it. `resume` is the
27
+ report; `change resume <id>` is the lifecycle operation. The `Coverage` line says
28
+ `strict` or `unverified`; on a strict change `node scripts/pincer-runtime.cjs coverage`
29
+ (and `impact` after an edit) name the exact scenario, ticket, check or decision
30
+ that is next — quote them rather than inferring coverage from the ticket list.
18
31
  2. Report in three lines: where the workflow is, what is in progress or blocked, and the
19
- next command. Quote the `Next` line as-is.
32
+ next command. Quote the `Next` line as-is. When the `Runtime` line says `legacy`,
33
+ add the register or migrate command it names as the step that precedes the next
34
+ ticket (fresh project → `register`, legacy receipts → `migrate --preview`, a v0.5.0
35
+ binding → `migrate --preview`, no selection → `change select <id>`).
20
36
  3. If a ticket is `in_progress`, read it and `git status`, then offer to resume it with
21
37
  `/pincer-code T-{NN}`. If the script printed a warning, surface it — a done ticket
22
38
  without a receipt was marked by hand and needs `scripts/pincer-ticket.sh verify T-{NN}`.
23
39
  Never restore a ticket file from git to clear a warning; a failed attempt is a record.
24
40
  The one exception is the tree-back-at-candidate case in the recovery section of
25
41
  `/pincer-code`: the user restores the ticket file, and nothing is verified or committed.
42
+ It applies only when the recorded failure is explained by a since-reverted source
43
+ change and the block passes in the same execution context as `verify`; an
44
+ unexplained failure (a service down, a missing dependency) stays a failure until the
45
+ environment is repaired and `verify` passes again. After migration never restore a
46
+ ticket file or delete `.pincer/runtime` to clear a warning: repair the cause and run
47
+ `verify` again; a dead session's `running` attempt is finalized by
48
+ `node scripts/pincer-runtime.cjs recover`.