pincer-workflow 0.4.1 → 0.5.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/README.md +7 -5
- package/bin/pincer.js +42 -5
- package/package.json +2 -2
- package/template/.agents/skills/pincer-code/SKILL.md +43 -9
- package/template/.agents/skills/pincer-evaluate/SKILL.md +19 -1
- package/template/.agents/skills/pincer-narrow/SKILL.md +11 -2
- package/template/.agents/skills/pincer-release/SKILL.md +14 -3
- package/template/.agents/skills/pincer-status/SKILL.md +15 -2
- package/template/.claude/commands/pincer-code.md +43 -9
- package/template/.claude/commands/pincer-evaluate.md +19 -1
- package/template/.claude/commands/pincer-narrow.md +11 -2
- package/template/.claude/commands/pincer-release.md +14 -3
- package/template/.claude/commands/pincer-status.md +15 -2
- package/template/.claude/hooks/hook-policy.cjs +17 -3
- package/template/.claude/references/ticket-template.md +4 -0
- package/template/.codex/README.md +3 -2
- package/template/.github/prompts/pincer-code.prompt.md +43 -9
- package/template/.github/prompts/pincer-evaluate.prompt.md +19 -1
- package/template/.github/prompts/pincer-narrow.prompt.md +11 -2
- package/template/.github/prompts/pincer-release.prompt.md +14 -3
- package/template/.github/prompts/pincer-status.prompt.md +15 -2
- package/template/AGENTS.md +6 -0
- package/template/docs/dry-run-checklist.md +43 -6
- package/template/docs/release-checklist.md +2 -1
- package/template/docs/runtime-contracts.md +437 -0
- package/template/scripts/pincer-evidence.cjs +5 -223
- package/template/scripts/pincer-runtime/evidence.cjs +391 -0
- package/template/scripts/pincer-runtime/fsutil.cjs +37 -0
- package/template/scripts/pincer-runtime/identity.cjs +146 -0
- package/template/scripts/pincer-runtime/lifecycle.cjs +289 -0
- package/template/scripts/pincer-runtime/migrate.cjs +127 -0
- package/template/scripts/pincer-runtime/parse.cjs +297 -0
- package/template/scripts/pincer-runtime/readiness.cjs +89 -0
- package/template/scripts/pincer-runtime/runner.cjs +224 -0
- package/template/scripts/pincer-runtime/sanitize.cjs +63 -0
- package/template/scripts/pincer-runtime/source.cjs +129 -0
- package/template/scripts/pincer-runtime/state.cjs +292 -0
- package/template/scripts/pincer-runtime/status.cjs +358 -0
- package/template/scripts/pincer-runtime.cjs +350 -0
- package/template/scripts/pincer-status.sh +11 -162
- package/template/scripts/pincer-ticket.sh +19 -139
- package/template/scripts/pincer-ticket-lib.sh +0 -321
package/README.md
CHANGED
|
@@ -86,7 +86,7 @@ want the repo-side rules too can copy `AGENTS.md` from the
|
|
|
86
86
|
npx pincer-workflow@latest update
|
|
87
87
|
```
|
|
88
88
|
|
|
89
|
-
Files you never touched are refreshed in place. (Installs older than v0.2.0 gain the ticket state machine, the status report and the ticket-guard hook on update; `.claude/settings.json` conflicts if you edited it — merge the new hook entry from the `.new` file. v0.2.2 replaces the Codex adapter: the commands are now skills in `.agents/skills/` invoked as `$pincer-*`, since Codex no longer loads `~/.codex/prompts/` — you can delete the copies there. v0.2.3 ships the playbooks, rubrics and templates under `.claude/` on every platform, which Codex- and Copilot-only installs were missing. v0.3.0 makes trust revocable: every verification attempt is recorded, `done` re-runs the check, tickets carry `prd:`, the release audit is read-only, and `.pincer.json` moves to schema 2 — an install from 0.2.x is treated as an untrusted baseline, so on the first update every changed file arrives as a `.new` proposal once; hooks now need Node 18+. v0.4.0 carries requirement IDs and `Proves:` checks from the PRD to evaluation, adds `profile: small|standard`, and saves candidate evidence under `.prd/evidence/`; the update is additive, but an existing `NOTES.md` without an `evidence:` manifest reads as stale until `/pincer-evaluate` is re-run. v0.4.1 is playbook wording only: the code playbook gains one recovery exception (a tree back at the evaluated candidate is restored by the user and nothing is committed), evaluate records one check per command, and plan asks only the open part of a partly answered question.) Files you edited are left
|
|
89
|
+
Files you never touched are refreshed in place. (Installs older than v0.2.0 gain the ticket state machine, the status report and the ticket-guard hook on update; `.claude/settings.json` conflicts if you edited it — merge the new hook entry from the `.new` file. v0.2.2 replaces the Codex adapter: the commands are now skills in `.agents/skills/` invoked as `$pincer-*`, since Codex no longer loads `~/.codex/prompts/` — you can delete the copies there. v0.2.3 ships the playbooks, rubrics and templates under `.claude/` on every platform, which Codex- and Copilot-only installs were missing. v0.3.0 makes trust revocable: every verification attempt is recorded, `done` re-runs the check, tickets carry `prd:`, the release audit is read-only, and `.pincer.json` moves to schema 2 — an install from 0.2.x is treated as an untrusted baseline, so on the first update every changed file arrives as a `.new` proposal once; hooks now need Node 18+. v0.4.0 carries requirement IDs and `Proves:` checks from the PRD to evaluation, adds `profile: small|standard`, and saves candidate evidence under `.prd/evidence/`; the update is additive, but an existing `NOTES.md` without an `evidence:` manifest reads as stale until `/pincer-evaluate` is re-run. v0.4.1 is playbook wording only: the code playbook gains one recovery exception (a tree back at the evaluated candidate is restored by the user and nothing is committed), evaluate records one check per command, and plan asks only the open part of a partly answered question. v0.5.0 adds the runtime: `scripts/pincer-runtime.cjs` with its modules under `scripts/pincer-runtime/` now implements the ticket lifecycle, status, migration and evidence export, and `pincer-ticket.sh` / `pincer-status.sh` delegate to it, so every command needs Node.js 18+; unmigrated projects keep their receipts and behavior. Run `node scripts/pincer-runtime.cjs migrate --preview --prd .prd/prd-vN.md` to see what migration would change; after `--apply`, `verify` records attempts with captured logs under the ignored `.pincer/runtime/` and writes no receipt into the ticket, `done` consumes the current passing attempt against the current source, and `/pincer-evaluate` exports evidence schema 2 from runtime attempts. `docs/runtime-contracts.md` is the contract; `pincer doctor` tells you when a migration is available and never migrates on its own. Updating the kit inside a migrated project changes tracked runtime files, so every done ticket's attempt reads `SOURCE_CHANGED` until it is verified again; update between changes, not mid-ticket. An update from 0.4.x leaves the retired `scripts/pincer-ticket-lib.sh` on disk; `pincer doctor` names it and it is safe to delete.) Files you edited are left
|
|
90
90
|
alone — the new version lands next to them as `<file>.new` for a manual merge.
|
|
91
91
|
`npx pincer-workflow doctor` checks the health of an install (hook executable,
|
|
92
92
|
`.gitignore` covering `.env*`, no unmerged `*.new` files, version current).
|
|
@@ -98,10 +98,12 @@ alone — the new version lands next to them as `<file>.new` for a manual merge.
|
|
|
98
98
|
| `AGENTS.md` | Project rules, single cross-platform source (workflow order, security defaults, secrets, untrusted-content and dependency rules) |
|
|
99
99
|
| `.claude/commands/` | The five playbooks plus `/pincer-status` (canonical — adapters are generated from them; ships on every platform together with `agents/` and `references/`) |
|
|
100
100
|
| `.claude/agents/` | `codebase-explorer` and `code-quality-reviewer` subagents, with inline fallbacks for platforms without subagents |
|
|
101
|
-
| `scripts/pincer-
|
|
102
|
-
| `scripts/pincer-
|
|
103
|
-
| `scripts/pincer-
|
|
104
|
-
|
|
|
101
|
+
| `scripts/pincer-runtime.cjs` + `scripts/pincer-runtime/` | The runtime (Node.js 18+, no dependencies): one implementation of the ticket lifecycle, readiness, status (`--json` too), change registration, source identity, verification attempts with sanitized captured logs, migration with backups, candidate checks and evidence export; `docs/runtime-contracts.md` is its contract. Local attempts live in the ignored `.pincer/runtime/`, change bindings in `.prd/changes/`; both are written only by the runtime |
|
|
102
|
+
| `scripts/pincer-ticket.sh` | Wrapper for the lifecycle: `start` (enforces dependency order) → `verify` (runs the ticket's check; before migration it stamps a receipt only on green, after migration it records an attempt bound to the current source) → `done` (refuses without a current pass or with unticked criteria; after migration it consumes the attempt without re-running the check) |
|
|
103
|
+
| `scripts/pincer-status.sh` | Wrapper for the read-only state report: current PRD and profile, `Runtime` mode, associated tickets, wall-clock elapsed time while work is active or against an explicit budget, evidence verdict and `Provenance`, warnings with reason codes, and next command |
|
|
104
|
+
| `scripts/pincer-evidence.cjs` | Read-only validator for candidate evidence (schema 1 authored, schema 2 exported from runtime attempts): `/pincer-evaluate` writes `.prd/evidence/prd-vN/<candidate>/manifest.json` plus logs and screenshots; status and release validate schema, references, candidate association, required results, provenance, file containment and SHA-256 digests. Legacy `NOTES.md` without a manifest is readable but never release-ready; an older runtime does not enforce this contract |
|
|
105
|
+
| `docs/runtime-contracts.md` | The runtime contract: modes, commands and exit codes, supported grammar, identities, source manifest, attempts, capture limits, reason codes, evidence schema 2, migration and rollback |
|
|
106
|
+
| `.claude/hooks/` + `settings.json` | Claude guardrails for documented destructive command forms and for writes to ticket state, `.pincer/` and `.prd/changes/`; Node.js 18+ parses hook payloads structurally |
|
|
105
107
|
| `.agents/skills/` · `.codex/` · `.github/` | Generated Codex skills and Copilot prompt files + platform wiring (`.codex/README.md` covers the Codex posture) |
|
|
106
108
|
| `scripts/sync-prompts.sh` | Regenerates the adapters after you edit a playbook |
|
|
107
109
|
| `scripts/build-plugin.sh` | Regenerates the Claude Code plugin (`plugin/`) from the template |
|
package/bin/pincer.js
CHANGED
|
@@ -26,13 +26,15 @@ const MANIFEST_SCHEMA = 2;
|
|
|
26
26
|
// and Copilot prompts point at them), so they ship everywhere; only Claude
|
|
27
27
|
// Code's own wiring (CLAUDE.md, settings.json, hooks) is platform-specific.
|
|
28
28
|
const PLATFORM_ROOTS = {
|
|
29
|
-
common: ['AGENTS.md', 'docs/release-checklist.md', 'docs/dry-run-checklist.md', 'scripts/sync-prompts.sh', 'scripts/pincer-ticket.sh', 'scripts/pincer-
|
|
29
|
+
common: ['AGENTS.md', 'docs/release-checklist.md', 'docs/dry-run-checklist.md', 'docs/runtime-contracts.md', 'scripts/sync-prompts.sh', 'scripts/pincer-ticket.sh', 'scripts/pincer-status.sh', 'scripts/pincer-evidence.cjs', 'scripts/pincer-runtime.cjs', 'scripts/pincer-runtime', '.claude/commands', '.claude/agents', '.claude/references'],
|
|
30
30
|
claude: ['CLAUDE.md', '.claude/settings.json', '.claude/hooks'],
|
|
31
31
|
codex: ['.codex', '.agents'],
|
|
32
32
|
copilot: ['.github'],
|
|
33
33
|
};
|
|
34
34
|
const EXECUTABLES = ['scripts/sync-prompts.sh', 'scripts/pincer-ticket.sh', 'scripts/pincer-status.sh', '.claude/hooks/block-dangerous.sh', '.claude/hooks/ticket-guard.sh'];
|
|
35
35
|
const GITIGNORE_LINES = ['.env', '.env.*', '!.env.example'];
|
|
36
|
+
// The runtime's local state (attempts, locks, backups) is never tracked.
|
|
37
|
+
const RUNTIME_IGNORE = '.pincer/';
|
|
36
38
|
|
|
37
39
|
const sha = (buf) => crypto.createHash('sha256').update(buf).digest('hex');
|
|
38
40
|
|
|
@@ -134,12 +136,18 @@ function install(dir, platforms, baseline) {
|
|
|
134
136
|
|
|
135
137
|
function ensureGitignore(dir) {
|
|
136
138
|
const p = path.join(dir, '.gitignore');
|
|
137
|
-
|
|
139
|
+
let existing = fs.existsSync(p) ? fs.readFileSync(p, 'utf8') : '';
|
|
138
140
|
const have = new Set(existing.split('\n').map((l) => l.trim()));
|
|
139
141
|
const missing = GITIGNORE_LINES.filter((l) => !have.has(l));
|
|
140
|
-
if (missing.length
|
|
141
|
-
|
|
142
|
-
|
|
142
|
+
if (missing.length) {
|
|
143
|
+
const lead = existing && !existing.endsWith('\n') ? '\n' : '';
|
|
144
|
+
fs.appendFileSync(p, `${lead}${existing ? '\n' : ''}# secrets (added by pincer init)\n${missing.join('\n')}\n`);
|
|
145
|
+
existing = fs.readFileSync(p, 'utf8');
|
|
146
|
+
}
|
|
147
|
+
if (![RUNTIME_IGNORE, '/.pincer/', '.pincer'].some((l) => have.has(l))) {
|
|
148
|
+
const lead = existing && !existing.endsWith('\n') ? '\n' : '';
|
|
149
|
+
fs.appendFileSync(p, `${lead}${existing ? '\n' : ''}# pincer runtime state (added by pincer init)\n${RUNTIME_IGNORE}\n`);
|
|
150
|
+
}
|
|
143
151
|
}
|
|
144
152
|
|
|
145
153
|
function report({ written, skipped, conflicted }) {
|
|
@@ -240,10 +248,39 @@ function cmdDoctor() {
|
|
|
240
248
|
const gi = fs.existsSync(path.join(dir, '.gitignore')) ? fs.readFileSync(path.join(dir, '.gitignore'), 'utf8') : '';
|
|
241
249
|
check(GITIGNORE_LINES.every((l) => gi.split('\n').map((s) => s.trim()).includes(l)),
|
|
242
250
|
'.gitignore covers .env files', 'add: .env / .env.* / !.env.example');
|
|
251
|
+
if (![RUNTIME_IGNORE, '/.pincer/', '.pincer'].some((l) => gi.split('\n').map((s) => s.trim()).includes(l))) {
|
|
252
|
+
console.log(` note .gitignore does not list ${RUNTIME_IGNORE} (runtime state); \`pincer update\`, \`register\` or \`migrate --apply\` adds it`);
|
|
253
|
+
}
|
|
243
254
|
|
|
244
255
|
const stale = fs.existsSync(TEMPLATE) && manifest.version !== VERSION;
|
|
245
256
|
check(!stale, `install is current (v${manifest.version})`, 'run: pincer update');
|
|
246
257
|
|
|
258
|
+
// The runtime ships with every layout; a project with legacy receipts and no
|
|
259
|
+
// change binding can migrate explicitly (never silently here).
|
|
260
|
+
const runtimeFiles = Object.keys(manifest.files).filter((rel) => rel === 'scripts/pincer-runtime.cjs' || rel.startsWith('scripts/pincer-runtime/'));
|
|
261
|
+
if (runtimeFiles.length) {
|
|
262
|
+
const missingRuntime = runtimeFiles.filter((rel) => !fs.existsSync(path.join(dir, rel)));
|
|
263
|
+
check(missingRuntime.length === 0, 'runtime files present', `missing: ${missingRuntime.join(', ')} — run: pincer update`);
|
|
264
|
+
}
|
|
265
|
+
// Files an earlier kit installed that this version no longer ships stay on disk
|
|
266
|
+
// (the installer never deletes); name them so they can be removed by hand.
|
|
267
|
+
const OBSOLETE = ['scripts/pincer-ticket-lib.sh'];
|
|
268
|
+
const obsolete = OBSOLETE.filter((rel) => fs.existsSync(path.join(dir, rel)) && !(rel in manifest.files));
|
|
269
|
+
if (obsolete.length) console.log(` note obsolete kit file(s) from an earlier version, safe to delete: ${obsolete.join(', ')}`);
|
|
270
|
+
|
|
271
|
+
const ticketsDir = path.join(dir, 'tickets');
|
|
272
|
+
const legacyReceipts = fs.existsSync(ticketsDir)
|
|
273
|
+
? fs.readdirSync(ticketsDir).filter((n) => /^T-\d+.*\.md$/.test(n)).filter((n) => /^(verified|last_check):/m.test(fs.readFileSync(path.join(ticketsDir, n), 'utf8')))
|
|
274
|
+
: [];
|
|
275
|
+
const bindingsDir = path.join(dir, '.prd', 'changes');
|
|
276
|
+
const hasBinding = fs.existsSync(bindingsDir) && fs.readdirSync(bindingsDir).some((n) => n.endsWith('.json'));
|
|
277
|
+
if (legacyReceipts.length && !hasBinding) {
|
|
278
|
+
const prdDir = path.join(dir, '.prd');
|
|
279
|
+
const prds = fs.existsSync(prdDir) ? fs.readdirSync(prdDir).map((n) => n.match(/^prd-v(\d+)\.md$/)).filter(Boolean).map((m) => Number(m[1])) : [];
|
|
280
|
+
const latest = prds.length ? `.prd/prd-v${Math.max(...prds)}.md` : '.prd/prd-vN.md';
|
|
281
|
+
console.log(` note migration available: ${legacyReceipts.length} ticket(s) carry legacy receipts and no change binding exists — preview with: node scripts/pincer-runtime.cjs migrate --preview --prd ${latest}`);
|
|
282
|
+
}
|
|
283
|
+
|
|
247
284
|
const edited = Object.entries(manifest.files)
|
|
248
285
|
.filter(([rel, h]) => fs.existsSync(path.join(dir, rel)) && sha(fs.readFileSync(path.join(dir, rel))) !== h)
|
|
249
286
|
.map(([rel]) => rel);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pincer-workflow",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "PINCER — a PRD-driven agentic delivery workflow for Claude Code, Codex CLI, and GitHub Copilot. Plan · Investigate · Narrow · Code · Evaluate · Release.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"pincer": "bin/pincer.js"
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"node": ">=18"
|
|
15
15
|
},
|
|
16
16
|
"scripts": {
|
|
17
|
-
"test": "node test/smoke.test.js && node test/installer.test.js && node test/ticket.test.js && node test/validation.test.js && node test/verification.test.js && node test/behavioral-verification.test.js && node test/evidence.test.js && node test/candidate.test.js && node test/recovery.test.js && node test/hooks.test.js && node test/workflow.test.js && node test/distribution.test.js"
|
|
17
|
+
"test": "node test/smoke.test.js && node test/installer.test.js && node test/ticket.test.js && node test/validation.test.js && node test/verification.test.js && node test/behavioral-verification.test.js && node test/evidence.test.js && node test/candidate.test.js && node test/recovery.test.js && node test/hooks.test.js && node test/runtime-parse.test.js && node test/runtime-identity.test.js && node test/runtime-state.test.js && node test/runtime-status.test.js && node test/runtime-runner.test.js && node test/runtime-lifecycle.test.js && node test/runtime-migrate.test.js && node test/runtime-evidence.test.js && node test/workflow.test.js && node test/contracts.test.js && node test/distribution.test.js"
|
|
18
18
|
},
|
|
19
19
|
"keywords": [
|
|
20
20
|
"claude-code",
|
|
@@ -18,6 +18,11 @@ Ticket state lives in the ticket file's frontmatter and is written **only** by
|
|
|
18
18
|
Verification block and stamps a receipt only on a green exit; `done` refuses without a
|
|
19
19
|
receipt that matches the current check, or with unticked acceptance criteria. Never edit
|
|
20
20
|
`status`, `started`, `last_check`, `verified`, or `finished` by hand — on Claude Code a hook blocks it.
|
|
21
|
+
On a migrated project (a change binding under `.prd/changes/`; the `Runtime` line of
|
|
22
|
+
`scripts/pincer-status.sh` names it) `verify` records an attempt under `.pincer/runtime/`
|
|
23
|
+
and writes no receipt into the ticket, and `done` consumes the current passing attempt
|
|
24
|
+
against the current source without re-running the check. `.pincer/` and `.prd/changes/`
|
|
25
|
+
are written only by the runtime; never edit or delete them by hand.
|
|
21
26
|
|
|
22
27
|
## Before the loop
|
|
23
28
|
|
|
@@ -25,7 +30,15 @@ Run `scripts/pincer-status.sh`. It lists every ticket's state, what is blocked,
|
|
|
25
30
|
build time from the clock, and the next action. If a ticket is `in_progress`, you are
|
|
26
31
|
resuming: read it, check `git status` / `git diff` for uncommitted work, and continue
|
|
27
32
|
from wherever the receipt says you are. Do not ask the user to reconfirm unchanged,
|
|
28
|
-
previously authorized work.
|
|
33
|
+
previously authorized work. Read the `Runtime` line before the first ticket: a change
|
|
34
|
+
binding present → continue; `legacy` and no ticket of this PRD carries legacy
|
|
35
|
+
receipts → register now (`node scripts/pincer-runtime.cjs register --prd .prd/prd-vN.md --authorization "<the user's approval, quoted>"`,
|
|
36
|
+
commit `.prd/changes/` and `.gitignore` as `Register PRD vN`); `legacy` with legacy receipts → run
|
|
37
|
+
`node scripts/pincer-runtime.cjs migrate --preview --prd .prd/prd-vN.md`, show the plan
|
|
38
|
+
(backups, receipts imported as history, `.gitignore` line) and ask once whether to
|
|
39
|
+
apply. Apply only on a yes, then commit the rewritten tickets, `.gitignore` and the
|
|
40
|
+
binding as `Migrate PRD vN to the runtime`. Never migrate silently, and never apply
|
|
41
|
+
when the preview reports a conflict.
|
|
29
42
|
|
|
30
43
|
## Loop (per ticket, in dependency order)
|
|
31
44
|
|
|
@@ -40,7 +53,9 @@ previously authorized work.
|
|
|
40
53
|
dispatch a subagent with a clean prompt: paste the full ticket body, the relevant
|
|
41
54
|
conventions, and nothing else.
|
|
42
55
|
3. **Verify:** `scripts/pincer-ticket.sh verify T-{NN}` — runs the Verification block and
|
|
43
|
-
writes the receipt only if it exits 0
|
|
56
|
+
writes the receipt only if it exits 0 (after migration it records an attempt with the
|
|
57
|
+
captured log under `.pincer/runtime/` and writes no receipt into the ticket; readiness
|
|
58
|
+
derives from the latest attempt and the current source). Red → fix and re-run; report the actual output,
|
|
44
59
|
not assumptions. Green output is the definition of done, not your confidence. If the
|
|
45
60
|
check only validated syntax or a build, say so — that is not behavioral proof. A
|
|
46
61
|
visual judgment is recorded separately in evaluation, not as the receipt, and a tool
|
|
@@ -58,7 +73,10 @@ previously authorized work.
|
|
|
58
73
|
- No error path leaks internals (stack traces, key names with values) to the client.
|
|
59
74
|
If the review changed code, run `verify` again — the receipt must match the code you commit.
|
|
60
75
|
5. **Close the ticket:** tick every verified acceptance-criteria checkbox (`- [ ]` → `- [x]`;
|
|
61
|
-
editing the checkboxes is allowed), then `scripts/pincer-ticket.sh done T-{NN}`.
|
|
76
|
+
editing the checkboxes is allowed), then `scripts/pincer-ticket.sh done T-{NN}`. After
|
|
77
|
+
migration `done` consumes the current passing attempt and does not re-run the check; it
|
|
78
|
+
refuses with a reason code (`SOURCE_CHANGED`, `CHECK_CHANGED`, `CHECK_FAILED`,
|
|
79
|
+
`CRITERIA_UNTICKED`, …) and the next step when the latest attempt is not current. A
|
|
62
80
|
criterion that was cut is a scope change to record in the PRD, not a box to skip.
|
|
63
81
|
Inspect `git status --short`, preserve pre-existing staged work, and stage only the
|
|
64
82
|
explicit paths changed for this ticket plus its ticket file. Review `git diff --cached`
|
|
@@ -89,20 +107,36 @@ the script or `scripts/pincer-status.sh` printed, and hand the repair to the use
|
|
|
89
107
|
performs it in their own terminal. Then return through the lifecycle — `start`,
|
|
90
108
|
`verify`, `done` — so the ticket carries fresh verification; a restored receipt is
|
|
91
109
|
never evidence. Do not recommend restoring source files or unrelated edits as routine
|
|
92
|
-
ticket repair. One exception: when the PRD is built with valid candidate evidence
|
|
110
|
+
ticket repair. One exception: when the PRD is built with valid candidate evidence;
|
|
93
111
|
tracked files other than the ticket file being restored match the evaluated candidate
|
|
94
|
-
(or the candidate plus its evidence-only commit) with nothing untracked
|
|
95
|
-
|
|
96
|
-
|
|
112
|
+
(or the candidate plus its evidence-only commit) with nothing untracked; the recorded
|
|
113
|
+
failure is explained by a working-tree change that has since been reverted (the failed
|
|
114
|
+
`last_check` was stamped while source differed from the candidate, and that difference
|
|
115
|
+
is gone); and the ticket's Verification block passes when run
|
|
116
|
+
directly rather than through `verify` (which would write a receipt), in the
|
|
117
|
+
same execution context as `verify` — the same shell, working directory, `PATH`
|
|
118
|
+
and environment, with no substituted binary and no repair made first — then
|
|
97
119
|
the committed evaluation still describes the tree. Say so, name the exact command
|
|
98
120
|
for the user to restore the ticket file in their own terminal, and
|
|
99
121
|
do not run `verify`, refresh the receipt or commit anything — the restored file is
|
|
100
122
|
what is already committed, not new evidence. If the block fails on that clean tree,
|
|
101
123
|
the failure is real: keep the failed `last_check` and repair through the lifecycle.
|
|
124
|
+
A changed executable, runner, working directory or environment repair requires a
|
|
125
|
+
new recorded verification through `verify`; the exception does not apply to it.
|
|
126
|
+
An unexplained failure cannot be cleared by restoring a receipt: when no
|
|
127
|
+
since-reverted source change explains it (a service down, a missing dependency, a
|
|
128
|
+
check that reads external data), keep the failure, name the cause you observed, and
|
|
129
|
+
ask for the environment to be repaired before `verify` runs again.
|
|
102
130
|
If source still differs from the candidate, name the differing paths and let the
|
|
103
131
|
user decide rather than asking which way to fix them; permission to restore a ticket
|
|
104
|
-
does not authorize discarding source changes.
|
|
105
|
-
|
|
132
|
+
does not authorize discarding source changes.
|
|
133
|
+
After migration (a change binding exists) recovery is the lifecycle itself: retain the
|
|
134
|
+
failure, repair the cause, run `verify` again; readiness derives from the latest attempt,
|
|
135
|
+
both attempts stay in `.pincer/runtime/` and no tracked file changes. Never restore a
|
|
136
|
+
ticket file or delete `.pincer/runtime` to obtain a green status; the legacy exception
|
|
137
|
+
above applies only before migration. A session that died mid-`verify` leaves a `running`
|
|
138
|
+
attempt: run `node scripts/pincer-runtime.cjs recover`, which finalizes it as
|
|
139
|
+
`interrupted` once the owner process is gone, then `verify` again.
|
|
106
140
|
|
|
107
141
|
## Budget rules
|
|
108
142
|
|
|
@@ -64,7 +64,25 @@ run the pipeline, then present results.
|
|
|
64
64
|
material decision; never make an ad-hoc `review: fixes` commit. Every fix commit
|
|
65
65
|
produces a new candidate: re-record `candidate`, re-run the checks against it, and
|
|
66
66
|
write fresh evidence in step 9 — never reuse a manifest from a previous candidate.
|
|
67
|
-
9. Persist evidence for the candidate under `.prd/evidence/prd-vN/<candidate
|
|
67
|
+
9. Persist evidence for the candidate under `.prd/evidence/prd-vN/<candidate>/`.
|
|
68
|
+
Migrated project (the `Runtime` status line names a change): run each executable
|
|
69
|
+
check through the runtime on the clean candidate view —
|
|
70
|
+
`node scripts/pincer-runtime.cjs check C-NN --candidate <sha> -- <command>` (one
|
|
71
|
+
command per check, the command line as run; `npm test` stays one aggregate check) —
|
|
72
|
+
then write the authored fields to a draft outside the evidence directory, for
|
|
73
|
+
example `.pincer/drafts/<sha>.json`: `environment.tools` and `environment.limitations`,
|
|
74
|
+
`coverage_review`, `requirements`, review and visual checks with their saved
|
|
75
|
+
artifacts, `visual_review`, and a stub `{"id": "C-NN", "kind": "command",
|
|
76
|
+
"required": true|false}` for each executable check. Then run
|
|
77
|
+
`node scripts/pincer-runtime.cjs evidence export --candidate <sha> --base <base> --prd .prd/prd-vN.md --draft <file>`.
|
|
78
|
+
The export writes `checks/C-NN.log` from the captured logs, fills `command`,
|
|
79
|
+
`result`, `provenance: runtime` and `attempt` from the attempts, labels review and
|
|
80
|
+
visual checks `provenance: authored`, computes the digests and writes an evidence
|
|
81
|
+
schema 2 manifest; it refuses a dirty tree, a HEAD that is not the candidate, a stub
|
|
82
|
+
without an attempt, and a `passed` or `failed` command result written by hand. A
|
|
83
|
+
tool that cannot run is recorded as an authored command check with
|
|
84
|
+
`result: unverified` and a note, as before. Legacy project (no change binding):
|
|
85
|
+
author the schema 1 manifest as follows.
|
|
68
86
|
- `checks/C-NN.log` — the command and a redacted summary or safe log of each
|
|
69
87
|
executable check. Never secrets, never an environment dump. Record
|
|
70
88
|
one check per command: `command` holds the command line as run, never prose
|
|
@@ -41,7 +41,9 @@ discovered consequential choice is surfaced before implementation.
|
|
|
41
41
|
- Every ticket gets a runnable command in its Verification block — a fenced `bash`
|
|
42
42
|
block that exits 0 only when the ticket is done. `scripts/pincer-ticket.sh verify`
|
|
43
43
|
runs it verbatim and stamps the receipt that `done` requires, so it must be
|
|
44
|
-
non-interactive and self-contained (no "check by hand").
|
|
44
|
+
non-interactive and self-contained (no "check by hand"). An optional
|
|
45
|
+
`timeout: <seconds>` frontmatter field (default 600) bounds the run; it is part of
|
|
46
|
+
the check identity, so changing it invalidates earlier passes.
|
|
45
47
|
- Each Verification section opens with `Proves:` — what the check establishes and
|
|
46
48
|
which regression it detects. A check for an executable change must exercise
|
|
47
49
|
observable behavior (including relevant rejection paths and, in brownfield work,
|
|
@@ -83,7 +85,14 @@ existing authorization for the same scope and order.
|
|
|
83
85
|
inspect existing staged changes, stage that PRD and the explicit new ticket paths,
|
|
84
86
|
review `git diff --cached`, and commit only those paths. Ask first — and finalize
|
|
85
87
|
once it is resolved — only when step 4 surfaced a newly discovered consequential
|
|
86
|
-
choice or a scope change the PRD does not cover.
|
|
88
|
+
choice or a scope change the PRD does not cover. Then register the change when the
|
|
89
|
+
`Runtime` status line says `legacy` and no ticket of this PRD carries legacy
|
|
90
|
+
receipts: `node scripts/pincer-runtime.cjs register --prd .prd/prd-vN.md --authorization "<the user's approval, quoted>"`,
|
|
91
|
+
then stage `.prd/changes/` and `.gitignore` (registration adds `.pincer/` to it) and
|
|
92
|
+
commit them as `Register PRD vN`. The authorization
|
|
93
|
+
text records the user's own words; running the command proves nothing by itself. A
|
|
94
|
+
project whose tickets carry legacy receipts is migrated from `$pincer-code` after a
|
|
95
|
+
preview, never here. Finish with:
|
|
87
96
|
"Tickets ready in `tickets/`. Run `$pincer-code` to start implementing."
|
|
88
97
|
|
|
89
98
|
## Authorization rule (shared by plan, narrow, code and evaluate)
|
|
@@ -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
|
|
32
|
-
|
|
33
|
-
|
|
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,13 @@ 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.
|
|
41
52
|
- Every file the manifest lists is tracked, and `git status --short` is empty before
|
|
42
53
|
and after the audit.
|
|
43
54
|
- Run the repository's candidate-wide release gate directly (`npm test`, or the
|
|
@@ -15,13 +15,26 @@ 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
|
|
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.
|
|
20
24
|
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.
|
|
25
|
+
next command. Quote the `Next` line as-is. When the `Runtime` line says `legacy`,
|
|
26
|
+
add the register or migrate command it names as the step that precedes the next
|
|
27
|
+
ticket (fresh project → `register`, legacy receipts → `migrate --preview`).
|
|
22
28
|
3. If a ticket is `in_progress`, read it and `git status`, then offer to resume it with
|
|
23
29
|
`$pincer-code T-{NN}`. If the script printed a warning, surface it — a done ticket
|
|
24
30
|
without a receipt was marked by hand and needs `scripts/pincer-ticket.sh verify T-{NN}`.
|
|
25
31
|
Never restore a ticket file from git to clear a warning; a failed attempt is a record.
|
|
26
32
|
The one exception is the tree-back-at-candidate case in the recovery section of
|
|
27
33
|
`$pincer-code`: the user restores the ticket file, and nothing is verified or committed.
|
|
34
|
+
It applies only when the recorded failure is explained by a since-reverted source
|
|
35
|
+
change and the block passes in the same execution context as `verify`; an
|
|
36
|
+
unexplained failure (a service down, a missing dependency) stays a failure until the
|
|
37
|
+
environment is repaired and `verify` passes again. After migration never restore a
|
|
38
|
+
ticket file or delete `.pincer/runtime` to clear a warning: repair the cause and run
|
|
39
|
+
`verify` again; a dead session's `running` attempt is finalized by
|
|
40
|
+
`node scripts/pincer-runtime.cjs recover`.
|
|
@@ -16,6 +16,11 @@ 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/` and `.prd/changes/`
|
|
23
|
+
are written only by the runtime; never edit or delete them by hand.
|
|
19
24
|
|
|
20
25
|
## Before the loop
|
|
21
26
|
|
|
@@ -23,7 +28,15 @@ Run `scripts/pincer-status.sh`. It lists every ticket's state, what is blocked,
|
|
|
23
28
|
build time from the clock, and the next action. If a ticket is `in_progress`, you are
|
|
24
29
|
resuming: read it, check `git status` / `git diff` for uncommitted work, and continue
|
|
25
30
|
from wherever the receipt says you are. Do not ask the user to reconfirm unchanged,
|
|
26
|
-
previously authorized work.
|
|
31
|
+
previously authorized work. Read the `Runtime` line before the first ticket: a change
|
|
32
|
+
binding present → continue; `legacy` and no ticket of this PRD carries legacy
|
|
33
|
+
receipts → register now (`node scripts/pincer-runtime.cjs register --prd .prd/prd-vN.md --authorization "<the user's approval, quoted>"`,
|
|
34
|
+
commit `.prd/changes/` and `.gitignore` as `Register PRD vN`); `legacy` with legacy receipts → run
|
|
35
|
+
`node scripts/pincer-runtime.cjs migrate --preview --prd .prd/prd-vN.md`, show the plan
|
|
36
|
+
(backups, receipts imported as history, `.gitignore` line) and ask once whether to
|
|
37
|
+
apply. Apply only on a yes, then commit the rewritten tickets, `.gitignore` and the
|
|
38
|
+
binding as `Migrate PRD vN to the runtime`. Never migrate silently, and never apply
|
|
39
|
+
when the preview reports a conflict.
|
|
27
40
|
|
|
28
41
|
## Loop (per ticket, in dependency order)
|
|
29
42
|
|
|
@@ -38,7 +51,9 @@ previously authorized work.
|
|
|
38
51
|
dispatch a subagent with a clean prompt: paste the full ticket body, the relevant
|
|
39
52
|
conventions, and nothing else.
|
|
40
53
|
3. **Verify:** `scripts/pincer-ticket.sh verify T-{NN}` — runs the Verification block and
|
|
41
|
-
writes the receipt only if it exits 0
|
|
54
|
+
writes the receipt only if it exits 0 (after migration it records an attempt with the
|
|
55
|
+
captured log under `.pincer/runtime/` and writes no receipt into the ticket; readiness
|
|
56
|
+
derives from the latest attempt and the current source). Red → fix and re-run; report the actual output,
|
|
42
57
|
not assumptions. Green output is the definition of done, not your confidence. If the
|
|
43
58
|
check only validated syntax or a build, say so — that is not behavioral proof. A
|
|
44
59
|
visual judgment is recorded separately in evaluation, not as the receipt, and a tool
|
|
@@ -56,7 +71,10 @@ previously authorized work.
|
|
|
56
71
|
- No error path leaks internals (stack traces, key names with values) to the client.
|
|
57
72
|
If the review changed code, run `verify` again — the receipt must match the code you commit.
|
|
58
73
|
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}`.
|
|
74
|
+
editing the checkboxes is allowed), then `scripts/pincer-ticket.sh done T-{NN}`. After
|
|
75
|
+
migration `done` consumes the current passing attempt and does not re-run the check; it
|
|
76
|
+
refuses with a reason code (`SOURCE_CHANGED`, `CHECK_CHANGED`, `CHECK_FAILED`,
|
|
77
|
+
`CRITERIA_UNTICKED`, …) and the next step when the latest attempt is not current. A
|
|
60
78
|
criterion that was cut is a scope change to record in the PRD, not a box to skip.
|
|
61
79
|
Inspect `git status --short`, preserve pre-existing staged work, and stage only the
|
|
62
80
|
explicit paths changed for this ticket plus its ticket file. Review `git diff --cached`
|
|
@@ -87,20 +105,36 @@ the script or `scripts/pincer-status.sh` printed, and hand the repair to the use
|
|
|
87
105
|
performs it in their own terminal. Then return through the lifecycle — `start`,
|
|
88
106
|
`verify`, `done` — so the ticket carries fresh verification; a restored receipt is
|
|
89
107
|
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
|
|
108
|
+
ticket repair. One exception: when the PRD is built with valid candidate evidence;
|
|
91
109
|
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
|
|
93
|
-
|
|
94
|
-
|
|
110
|
+
(or the candidate plus its evidence-only commit) with nothing untracked; the recorded
|
|
111
|
+
failure is explained by a working-tree change that has since been reverted (the failed
|
|
112
|
+
`last_check` was stamped while source differed from the candidate, and that difference
|
|
113
|
+
is gone); and the ticket's Verification block passes when run
|
|
114
|
+
directly rather than through `verify` (which would write a receipt), in the
|
|
115
|
+
same execution context as `verify` — the same shell, working directory, `PATH`
|
|
116
|
+
and environment, with no substituted binary and no repair made first — then
|
|
95
117
|
the committed evaluation still describes the tree. Say so, name the exact command
|
|
96
118
|
for the user to restore the ticket file in their own terminal, and
|
|
97
119
|
do not run `verify`, refresh the receipt or commit anything — the restored file is
|
|
98
120
|
what is already committed, not new evidence. If the block fails on that clean tree,
|
|
99
121
|
the failure is real: keep the failed `last_check` and repair through the lifecycle.
|
|
122
|
+
A changed executable, runner, working directory or environment repair requires a
|
|
123
|
+
new recorded verification through `verify`; the exception does not apply to it.
|
|
124
|
+
An unexplained failure cannot be cleared by restoring a receipt: when no
|
|
125
|
+
since-reverted source change explains it (a service down, a missing dependency, a
|
|
126
|
+
check that reads external data), keep the failure, name the cause you observed, and
|
|
127
|
+
ask for the environment to be repaired before `verify` runs again.
|
|
100
128
|
If source still differs from the candidate, name the differing paths and let the
|
|
101
129
|
user decide rather than asking which way to fix them; permission to restore a ticket
|
|
102
|
-
does not authorize discarding source changes.
|
|
103
|
-
|
|
130
|
+
does not authorize discarding source changes.
|
|
131
|
+
After migration (a change binding exists) recovery is the lifecycle itself: retain the
|
|
132
|
+
failure, repair the cause, run `verify` again; readiness derives from the latest attempt,
|
|
133
|
+
both attempts stay in `.pincer/runtime/` and no tracked file changes. Never restore a
|
|
134
|
+
ticket file or delete `.pincer/runtime` to obtain a green status; the legacy exception
|
|
135
|
+
above applies only before migration. A session that died mid-`verify` leaves a `running`
|
|
136
|
+
attempt: run `node scripts/pincer-runtime.cjs recover`, which finalizes it as
|
|
137
|
+
`interrupted` once the owner process is gone, then `verify` again.
|
|
104
138
|
|
|
105
139
|
## Budget rules
|
|
106
140
|
|
|
@@ -62,7 +62,25 @@ run the pipeline, then present results.
|
|
|
62
62
|
material decision; never make an ad-hoc `review: fixes` commit. Every fix commit
|
|
63
63
|
produces a new candidate: re-record `candidate`, re-run the checks against it, and
|
|
64
64
|
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
|
|
65
|
+
9. Persist evidence for the candidate under `.prd/evidence/prd-vN/<candidate>/`.
|
|
66
|
+
Migrated project (the `Runtime` status line names a change): run each executable
|
|
67
|
+
check through the runtime on the clean candidate view —
|
|
68
|
+
`node scripts/pincer-runtime.cjs check C-NN --candidate <sha> -- <command>` (one
|
|
69
|
+
command per check, the command line as run; `npm test` stays one aggregate check) —
|
|
70
|
+
then write the authored fields to a draft outside the evidence directory, for
|
|
71
|
+
example `.pincer/drafts/<sha>.json`: `environment.tools` and `environment.limitations`,
|
|
72
|
+
`coverage_review`, `requirements`, review and visual checks with their saved
|
|
73
|
+
artifacts, `visual_review`, and a stub `{"id": "C-NN", "kind": "command",
|
|
74
|
+
"required": true|false}` for each executable check. Then run
|
|
75
|
+
`node scripts/pincer-runtime.cjs evidence export --candidate <sha> --base <base> --prd .prd/prd-vN.md --draft <file>`.
|
|
76
|
+
The export writes `checks/C-NN.log` from the captured logs, fills `command`,
|
|
77
|
+
`result`, `provenance: runtime` and `attempt` from the attempts, labels review and
|
|
78
|
+
visual checks `provenance: authored`, computes the digests and writes an evidence
|
|
79
|
+
schema 2 manifest; it refuses a dirty tree, a HEAD that is not the candidate, a stub
|
|
80
|
+
without an attempt, and a `passed` or `failed` command result written by hand. A
|
|
81
|
+
tool that cannot run is recorded as an authored command check with
|
|
82
|
+
`result: unverified` and a note, as before. Legacy project (no change binding):
|
|
83
|
+
author the schema 1 manifest as follows.
|
|
66
84
|
- `checks/C-NN.log` — the command and a redacted summary or safe log of each
|
|
67
85
|
executable check. Never secrets, never an environment dump. Record
|
|
68
86
|
one check per command: `command` holds the command line as run, never prose
|
|
@@ -39,7 +39,9 @@ discovered consequential choice is surfaced before implementation.
|
|
|
39
39
|
- Every ticket gets a runnable command in its Verification block — a fenced `bash`
|
|
40
40
|
block that exits 0 only when the ticket is done. `scripts/pincer-ticket.sh verify`
|
|
41
41
|
runs it verbatim and stamps the receipt that `done` requires, so it must be
|
|
42
|
-
non-interactive and self-contained (no "check by hand").
|
|
42
|
+
non-interactive and self-contained (no "check by hand"). An optional
|
|
43
|
+
`timeout: <seconds>` frontmatter field (default 600) bounds the run; it is part of
|
|
44
|
+
the check identity, so changing it invalidates earlier passes.
|
|
43
45
|
- Each Verification section opens with `Proves:` — what the check establishes and
|
|
44
46
|
which regression it detects. A check for an executable change must exercise
|
|
45
47
|
observable behavior (including relevant rejection paths and, in brownfield work,
|
|
@@ -81,7 +83,14 @@ existing authorization for the same scope and order.
|
|
|
81
83
|
inspect existing staged changes, stage that PRD and the explicit new ticket paths,
|
|
82
84
|
review `git diff --cached`, and commit only those paths. Ask first — and finalize
|
|
83
85
|
once it is resolved — only when step 4 surfaced a newly discovered consequential
|
|
84
|
-
choice or a scope change the PRD does not cover.
|
|
86
|
+
choice or a scope change the PRD does not cover. Then register the change when the
|
|
87
|
+
`Runtime` status line says `legacy` and no ticket of this PRD carries legacy
|
|
88
|
+
receipts: `node scripts/pincer-runtime.cjs register --prd .prd/prd-vN.md --authorization "<the user's approval, quoted>"`,
|
|
89
|
+
then stage `.prd/changes/` and `.gitignore` (registration adds `.pincer/` to it) and
|
|
90
|
+
commit them as `Register PRD vN`. The authorization
|
|
91
|
+
text records the user's own words; running the command proves nothing by itself. A
|
|
92
|
+
project whose tickets carry legacy receipts is migrated from `/pincer-code` after a
|
|
93
|
+
preview, never here. Finish with:
|
|
85
94
|
"Tickets ready in `tickets/`. Run `/pincer-code` to start implementing."
|
|
86
95
|
|
|
87
96
|
## Authorization rule (shared by plan, narrow, code and evaluate)
|
|
@@ -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
|
|
30
|
-
|
|
31
|
-
|
|
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,13 @@ 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.
|
|
39
50
|
- Every file the manifest lists is tracked, and `git status --short` is empty before
|
|
40
51
|
and after the audit.
|
|
41
52
|
- Run the repository's candidate-wide release gate directly (`npm test`, or the
|
|
@@ -13,13 +13,26 @@ 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
|
|
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.
|
|
18
22
|
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.
|
|
23
|
+
next command. Quote the `Next` line as-is. When the `Runtime` line says `legacy`,
|
|
24
|
+
add the register or migrate command it names as the step that precedes the next
|
|
25
|
+
ticket (fresh project → `register`, legacy receipts → `migrate --preview`).
|
|
20
26
|
3. If a ticket is `in_progress`, read it and `git status`, then offer to resume it with
|
|
21
27
|
`/pincer-code T-{NN}`. If the script printed a warning, surface it — a done ticket
|
|
22
28
|
without a receipt was marked by hand and needs `scripts/pincer-ticket.sh verify T-{NN}`.
|
|
23
29
|
Never restore a ticket file from git to clear a warning; a failed attempt is a record.
|
|
24
30
|
The one exception is the tree-back-at-candidate case in the recovery section of
|
|
25
31
|
`/pincer-code`: the user restores the ticket file, and nothing is verified or committed.
|
|
32
|
+
It applies only when the recorded failure is explained by a since-reverted source
|
|
33
|
+
change and the block passes in the same execution context as `verify`; an
|
|
34
|
+
unexplained failure (a service down, a missing dependency) stays a failure until the
|
|
35
|
+
environment is repaired and `verify` passes again. After migration never restore a
|
|
36
|
+
ticket file or delete `.pincer/runtime` to clear a warning: repair the cause and run
|
|
37
|
+
`verify` again; a dead session's `running` attempt is finalized by
|
|
38
|
+
`node scripts/pincer-runtime.cjs recover`.
|