plumbbob 0.9.3 → 0.9.5
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/.claude-plugin/plugin.json +1 -1
- package/README.md +15 -13
- package/dist/cli-core.js +19 -2
- package/dist/lib/check.js +46 -13
- package/dist/lib/intent.js +1 -1
- package/dist/lib/latch.js +3 -3
- package/dist/lib/reentry.js +70 -0
- package/dist/verbs/agent.js +2 -2
- package/dist/verbs/doctor.js +4 -4
- package/dist/verbs/finish.js +1 -1
- package/dist/verbs/recover.js +297 -0
- package/dist/verbs/revert.js +2 -2
- package/dist/verbs/spike.js +8 -2
- package/hooks/post-edit.sh +4 -4
- package/hooks/pre-bash-commit.sh +3 -3
- package/node_modules/checkride/.claude-plugin/plugin.json +11 -0
- package/node_modules/checkride/CHANGELOG.md +1003 -0
- package/node_modules/checkride/LICENSE +201 -21
- package/node_modules/checkride/README.md +171 -30
- package/node_modules/checkride/dist/__tests__/fixtures/released-stanzas.d.ts +15 -0
- package/node_modules/checkride/dist/__tests__/fixtures/released-stanzas.d.ts.map +1 -0
- package/node_modules/checkride/dist/__tests__/fixtures/released-stanzas.js +17 -0
- package/node_modules/checkride/dist/__tests__/fixtures/released-stanzas.js.map +1 -0
- package/node_modules/checkride/dist/adapters.d.ts +18 -6
- package/node_modules/checkride/dist/adapters.d.ts.map +1 -1
- package/node_modules/checkride/dist/adapters.js +42 -23
- package/node_modules/checkride/dist/adapters.js.map +1 -1
- package/node_modules/checkride/dist/agent-setup/claude.d.ts +88 -0
- package/node_modules/checkride/dist/agent-setup/claude.d.ts.map +1 -0
- package/node_modules/checkride/dist/agent-setup/claude.js +305 -0
- package/node_modules/checkride/dist/agent-setup/claude.js.map +1 -0
- package/node_modules/checkride/dist/agent-setup/command.d.ts +43 -0
- package/node_modules/checkride/dist/agent-setup/command.d.ts.map +1 -0
- package/node_modules/checkride/dist/agent-setup/command.js +77 -0
- package/node_modules/checkride/dist/agent-setup/command.js.map +1 -0
- package/node_modules/checkride/dist/agent-setup/cursor.d.ts +61 -0
- package/node_modules/checkride/dist/agent-setup/cursor.d.ts.map +1 -0
- package/node_modules/checkride/dist/agent-setup/cursor.js +189 -0
- package/node_modules/checkride/dist/agent-setup/cursor.js.map +1 -0
- package/node_modules/checkride/dist/agent-setup/files.d.ts +50 -0
- package/node_modules/checkride/dist/agent-setup/files.d.ts.map +1 -0
- package/node_modules/checkride/dist/agent-setup/files.js +80 -0
- package/node_modules/checkride/dist/agent-setup/files.js.map +1 -0
- package/node_modules/checkride/dist/agent-setup/harness.d.ts +101 -0
- package/node_modules/checkride/dist/agent-setup/harness.d.ts.map +1 -0
- package/node_modules/checkride/dist/agent-setup/harness.js +84 -0
- package/node_modules/checkride/dist/agent-setup/harness.js.map +1 -0
- package/node_modules/checkride/dist/agent-setup/hook.d.ts +45 -52
- package/node_modules/checkride/dist/agent-setup/hook.d.ts.map +1 -1
- package/node_modules/checkride/dist/agent-setup/hook.js +64 -95
- package/node_modules/checkride/dist/agent-setup/hook.js.map +1 -1
- package/node_modules/checkride/dist/agent-setup/index.d.ts +10 -4
- package/node_modules/checkride/dist/agent-setup/index.d.ts.map +1 -1
- package/node_modules/checkride/dist/agent-setup/index.js +9 -4
- package/node_modules/checkride/dist/agent-setup/index.js.map +1 -1
- package/node_modules/checkride/dist/agent-setup/scripts.d.ts +58 -0
- package/node_modules/checkride/dist/agent-setup/scripts.d.ts.map +1 -0
- package/node_modules/checkride/dist/agent-setup/scripts.js +299 -0
- package/node_modules/checkride/dist/agent-setup/scripts.js.map +1 -0
- package/node_modules/checkride/dist/agent-setup/skills.d.ts +31 -0
- package/node_modules/checkride/dist/agent-setup/skills.d.ts.map +1 -0
- package/node_modules/checkride/dist/agent-setup/skills.js +56 -0
- package/node_modules/checkride/dist/agent-setup/skills.js.map +1 -0
- package/node_modules/checkride/dist/artifacts/configured.d.ts +30 -0
- package/node_modules/checkride/dist/artifacts/configured.d.ts.map +1 -0
- package/node_modules/checkride/dist/artifacts/configured.js +45 -0
- package/node_modules/checkride/dist/artifacts/configured.js.map +1 -0
- package/node_modules/checkride/dist/artifacts/format.d.ts +33 -0
- package/node_modules/checkride/dist/artifacts/format.d.ts.map +1 -0
- package/node_modules/checkride/dist/artifacts/format.js +56 -0
- package/node_modules/checkride/dist/artifacts/format.js.map +1 -0
- package/node_modules/checkride/dist/artifacts/freshness.d.ts +32 -0
- package/node_modules/checkride/dist/artifacts/freshness.d.ts.map +1 -0
- package/node_modules/checkride/dist/artifacts/freshness.js +37 -0
- package/node_modules/checkride/dist/artifacts/freshness.js.map +1 -0
- package/node_modules/checkride/dist/artifacts/index.d.ts +22 -0
- package/node_modules/checkride/dist/artifacts/index.d.ts.map +1 -0
- package/node_modules/checkride/dist/artifacts/index.js +19 -0
- package/node_modules/checkride/dist/artifacts/index.js.map +1 -0
- package/node_modules/checkride/dist/artifacts/json.d.ts +31 -0
- package/node_modules/checkride/dist/artifacts/json.d.ts.map +1 -0
- package/node_modules/checkride/dist/artifacts/json.js +47 -0
- package/node_modules/checkride/dist/artifacts/json.js.map +1 -0
- package/node_modules/checkride/dist/artifacts/raw.d.ts +60 -0
- package/node_modules/checkride/dist/artifacts/raw.d.ts.map +1 -0
- package/node_modules/checkride/dist/artifacts/raw.js +91 -0
- package/node_modules/checkride/dist/artifacts/raw.js.map +1 -0
- package/node_modules/checkride/dist/artifacts/summary.d.ts +69 -0
- package/node_modules/checkride/dist/artifacts/summary.d.ts.map +1 -0
- package/node_modules/checkride/dist/artifacts/summary.js +108 -0
- package/node_modules/checkride/dist/artifacts/summary.js.map +1 -0
- package/node_modules/checkride/dist/atomic.d.ts +16 -1
- package/node_modules/checkride/dist/atomic.d.ts.map +1 -1
- package/node_modules/checkride/dist/atomic.js +25 -3
- package/node_modules/checkride/dist/atomic.js.map +1 -1
- package/node_modules/checkride/dist/baseline/fallow.d.ts +9 -5
- package/node_modules/checkride/dist/baseline/fallow.d.ts.map +1 -1
- package/node_modules/checkride/dist/baseline/fallow.js +161 -58
- package/node_modules/checkride/dist/baseline/fallow.js.map +1 -1
- package/node_modules/checkride/dist/baseline/fingerprint.d.ts +7 -7
- package/node_modules/checkride/dist/baseline/fingerprint.d.ts.map +1 -1
- package/node_modules/checkride/dist/baseline/fingerprint.js +16 -19
- package/node_modules/checkride/dist/baseline/fingerprint.js.map +1 -1
- package/node_modules/checkride/dist/baseline/index.d.ts +4 -4
- package/node_modules/checkride/dist/baseline/index.d.ts.map +1 -1
- package/node_modules/checkride/dist/baseline/index.js +4 -4
- package/node_modules/checkride/dist/baseline/index.js.map +1 -1
- package/node_modules/checkride/dist/baseline/store.d.ts +12 -4
- package/node_modules/checkride/dist/baseline/store.d.ts.map +1 -1
- package/node_modules/checkride/dist/baseline/store.js +16 -9
- package/node_modules/checkride/dist/baseline/store.js.map +1 -1
- package/node_modules/checkride/dist/baseline-command.d.ts +5 -5
- package/node_modules/checkride/dist/baseline-command.js +7 -7
- package/node_modules/checkride/dist/baseline-command.js.map +1 -1
- package/node_modules/checkride/dist/cli.d.ts +17 -4
- package/node_modules/checkride/dist/cli.d.ts.map +1 -1
- package/node_modules/checkride/dist/cli.js +259 -18
- package/node_modules/checkride/dist/cli.js.map +1 -1
- package/node_modules/checkride/dist/config.d.ts +84 -8
- package/node_modules/checkride/dist/config.d.ts.map +1 -1
- package/node_modules/checkride/dist/config.js +122 -18
- package/node_modules/checkride/dist/config.js.map +1 -1
- package/node_modules/checkride/dist/digest/digest.d.ts +5 -5
- package/node_modules/checkride/dist/digest/digest.js +5 -5
- package/node_modules/checkride/dist/digest/index.d.ts +2 -2
- package/node_modules/checkride/dist/digest/index.js +2 -2
- package/node_modules/checkride/dist/doctor.d.ts +25 -6
- package/node_modules/checkride/dist/doctor.d.ts.map +1 -1
- package/node_modules/checkride/dist/doctor.js +193 -27
- package/node_modules/checkride/dist/doctor.js.map +1 -1
- package/node_modules/checkride/dist/gate.d.ts +135 -0
- package/node_modules/checkride/dist/gate.d.ts.map +1 -0
- package/node_modules/checkride/dist/gate.js +490 -0
- package/node_modules/checkride/dist/gate.js.map +1 -0
- package/node_modules/checkride/dist/init.d.ts +72 -12
- package/node_modules/checkride/dist/init.d.ts.map +1 -1
- package/node_modules/checkride/dist/init.js +324 -81
- package/node_modules/checkride/dist/init.js.map +1 -1
- package/node_modules/checkride/dist/json.d.ts +21 -0
- package/node_modules/checkride/dist/json.d.ts.map +1 -0
- package/node_modules/checkride/dist/json.js +21 -0
- package/node_modules/checkride/dist/json.js.map +1 -0
- package/node_modules/checkride/dist/links.d.ts +31 -5
- package/node_modules/checkride/dist/links.d.ts.map +1 -1
- package/node_modules/checkride/dist/links.js +141 -32
- package/node_modules/checkride/dist/links.js.map +1 -1
- package/node_modules/checkride/dist/node-pin.d.ts +129 -0
- package/node_modules/checkride/dist/node-pin.d.ts.map +1 -0
- package/node_modules/checkride/dist/node-pin.js +211 -0
- package/node_modules/checkride/dist/node-pin.js.map +1 -0
- package/node_modules/checkride/dist/orchestrator.d.ts +40 -10
- package/node_modules/checkride/dist/orchestrator.d.ts.map +1 -1
- package/node_modules/checkride/dist/orchestrator.js +196 -102
- package/node_modules/checkride/dist/orchestrator.js.map +1 -1
- package/node_modules/checkride/dist/pack.d.ts +8 -9
- package/node_modules/checkride/dist/pack.d.ts.map +1 -1
- package/node_modules/checkride/dist/pack.js +53 -17
- package/node_modules/checkride/dist/pack.js.map +1 -1
- package/node_modules/checkride/dist/pm/detect.d.ts +6 -1
- package/node_modules/checkride/dist/pm/detect.d.ts.map +1 -1
- package/node_modules/checkride/dist/pm/detect.js +6 -1
- package/node_modules/checkride/dist/pm/detect.js.map +1 -1
- package/node_modules/checkride/dist/pm/index.d.ts +6 -2
- package/node_modules/checkride/dist/pm/index.d.ts.map +1 -1
- package/node_modules/checkride/dist/pm/index.js +6 -2
- package/node_modules/checkride/dist/pm/index.js.map +1 -1
- package/node_modules/checkride/dist/pm/launch.d.ts +51 -0
- package/node_modules/checkride/dist/pm/launch.d.ts.map +1 -0
- package/node_modules/checkride/dist/pm/launch.js +92 -0
- package/node_modules/checkride/dist/pm/launch.js.map +1 -0
- package/node_modules/checkride/dist/pm/tools.d.ts +73 -0
- package/node_modules/checkride/dist/pm/tools.d.ts.map +1 -0
- package/node_modules/checkride/dist/pm/tools.js +124 -0
- package/node_modules/checkride/dist/pm/tools.js.map +1 -0
- package/node_modules/checkride/dist/pm/translate.d.ts +35 -9
- package/node_modules/checkride/dist/pm/translate.d.ts.map +1 -1
- package/node_modules/checkride/dist/pm/translate.js +78 -18
- package/node_modules/checkride/dist/pm/translate.js.map +1 -1
- package/node_modules/checkride/dist/proc.d.ts +30 -0
- package/node_modules/checkride/dist/proc.d.ts.map +1 -0
- package/node_modules/checkride/dist/proc.js +42 -0
- package/node_modules/checkride/dist/proc.js.map +1 -0
- package/node_modules/checkride/dist/qa/cli.d.ts +20 -0
- package/node_modules/checkride/dist/qa/cli.d.ts.map +1 -0
- package/node_modules/checkride/dist/qa/cli.js +24 -0
- package/node_modules/checkride/dist/qa/cli.js.map +1 -0
- package/node_modules/checkride/dist/qa/dead.d.ts +39 -0
- package/node_modules/checkride/dist/qa/dead.d.ts.map +1 -0
- package/node_modules/checkride/dist/qa/dead.js +88 -0
- package/node_modules/checkride/dist/qa/dead.js.map +1 -0
- package/node_modules/checkride/dist/qa/dupes.d.ts +45 -0
- package/node_modules/checkride/dist/qa/dupes.d.ts.map +1 -0
- package/node_modules/checkride/dist/qa/dupes.js +62 -0
- package/node_modules/checkride/dist/qa/dupes.js.map +1 -0
- package/node_modules/checkride/dist/qa/health.d.ts +85 -0
- package/node_modules/checkride/dist/qa/health.d.ts.map +1 -0
- package/node_modules/checkride/dist/qa/health.js +109 -0
- package/node_modules/checkride/dist/qa/health.js.map +1 -0
- package/node_modules/checkride/dist/qa/index.d.ts +23 -0
- package/node_modules/checkride/dist/qa/index.d.ts.map +1 -0
- package/node_modules/checkride/dist/qa/index.js +22 -0
- package/node_modules/checkride/dist/qa/index.js.map +1 -0
- package/node_modules/checkride/dist/qa/mutation.d.ts +80 -0
- package/node_modules/checkride/dist/qa/mutation.d.ts.map +1 -0
- package/node_modules/checkride/dist/qa/mutation.js +195 -0
- package/node_modules/checkride/dist/qa/mutation.js.map +1 -0
- package/node_modules/checkride/dist/qa/qa.d.ts +71 -0
- package/node_modules/checkride/dist/qa/qa.d.ts.map +1 -0
- package/node_modules/checkride/dist/qa/qa.js +158 -0
- package/node_modules/checkride/dist/qa/qa.js.map +1 -0
- package/node_modules/checkride/dist/qa/read.d.ts +40 -0
- package/node_modules/checkride/dist/qa/read.d.ts.map +1 -0
- package/node_modules/checkride/dist/qa/read.js +47 -0
- package/node_modules/checkride/dist/qa/read.js.map +1 -0
- package/node_modules/checkride/dist/qa/render.d.ts +26 -0
- package/node_modules/checkride/dist/qa/render.d.ts.map +1 -0
- package/node_modules/checkride/dist/qa/render.js +310 -0
- package/node_modules/checkride/dist/qa/render.js.map +1 -0
- package/node_modules/checkride/dist/security.d.ts +45 -0
- package/node_modules/checkride/dist/security.d.ts.map +1 -0
- package/node_modules/checkride/dist/security.js +86 -0
- package/node_modules/checkride/dist/security.js.map +1 -0
- package/node_modules/checkride/dist/smoke.d.ts +5 -5
- package/node_modules/checkride/dist/smoke.js +5 -5
- package/node_modules/checkride/dist/snippets.d.ts +26 -29
- package/node_modules/checkride/dist/snippets.d.ts.map +1 -1
- package/node_modules/checkride/dist/snippets.js +26 -30
- package/node_modules/checkride/dist/snippets.js.map +1 -1
- package/node_modules/checkride/dist/tool-json.d.ts +33 -0
- package/node_modules/checkride/dist/tool-json.d.ts.map +1 -0
- package/node_modules/checkride/dist/tool-json.js +58 -0
- package/node_modules/checkride/dist/tool-json.js.map +1 -0
- package/node_modules/checkride/dist/triage/cli.d.ts +21 -0
- package/node_modules/checkride/dist/triage/cli.d.ts.map +1 -0
- package/node_modules/checkride/dist/triage/cli.js +26 -0
- package/node_modules/checkride/dist/triage/cli.js.map +1 -0
- package/node_modules/checkride/dist/triage/doctor-fold.d.ts +51 -0
- package/node_modules/checkride/dist/triage/doctor-fold.d.ts.map +1 -0
- package/node_modules/checkride/dist/triage/doctor-fold.js +88 -0
- package/node_modules/checkride/dist/triage/doctor-fold.js.map +1 -0
- package/node_modules/checkride/dist/triage/env.d.ts +54 -0
- package/node_modules/checkride/dist/triage/env.d.ts.map +1 -0
- package/node_modules/checkride/dist/triage/env.js +81 -0
- package/node_modules/checkride/dist/triage/env.js.map +1 -0
- package/node_modules/checkride/dist/triage/gate.d.ts +61 -0
- package/node_modules/checkride/dist/triage/gate.d.ts.map +1 -0
- package/node_modules/checkride/dist/triage/gate.js +121 -0
- package/node_modules/checkride/dist/triage/gate.js.map +1 -0
- package/node_modules/checkride/dist/triage/index.d.ts +22 -0
- package/node_modules/checkride/dist/triage/index.d.ts.map +1 -0
- package/node_modules/checkride/dist/triage/index.js +20 -0
- package/node_modules/checkride/dist/triage/index.js.map +1 -0
- package/node_modules/checkride/dist/triage/render.d.ts +19 -0
- package/node_modules/checkride/dist/triage/render.d.ts.map +1 -0
- package/node_modules/checkride/dist/triage/render.js +419 -0
- package/node_modules/checkride/dist/triage/render.js.map +1 -0
- package/node_modules/checkride/dist/triage/triage.d.ts +83 -0
- package/node_modules/checkride/dist/triage/triage.d.ts.map +1 -0
- package/node_modules/checkride/dist/triage/triage.js +131 -0
- package/node_modules/checkride/dist/triage/triage.js.map +1 -0
- package/node_modules/checkride/package.json +17 -15
- package/node_modules/checkride/schema/checkride.config.schema.json +62 -5
- package/node_modules/checkride/schema/checkride.summary.schema.json +1 -1
- package/node_modules/checkride/skills/check/SKILL.md +257 -0
- package/node_modules/checkride/skills/qa/SKILL.md +231 -0
- package/node_modules/checkride/templates/shared/cspell.json +1 -0
- package/node_modules/checkride/templates/shared/oxlintrc.json +1 -1
- package/package.json +2 -2
- package/skills/build/SKILL.md +23 -19
- package/skills/finish/SKILL.md +3 -1
- package/skills/harvest/SKILL.md +2 -1
- package/skills/plan/SKILL.md +8 -7
- package/skills/recover/SKILL.md +28 -0
- package/skills/refine/SKILL.md +5 -4
- package/skills/spike/SKILL.md +1 -1
- package/skills/step/SKILL.md +4 -4
- package/skills/verify/SKILL.md +19 -14
- package/templates/intent.md +8 -7
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "plumbbob",
|
|
3
3
|
"displayName": "PlumbBob",
|
|
4
|
-
"version": "0.9.
|
|
4
|
+
"version": "0.9.5",
|
|
5
5
|
"description": "Attention-first build process — driver skills + a CLI that keep you the decider: guidance on the work, a latch on the record.",
|
|
6
6
|
"author": { "name": "Rob McLarty", "email": "hello@robmclarty.com", "url": "https://robmclarty.com" },
|
|
7
7
|
"homepage": "https://github.com/robmclarty/plumbbob#readme",
|
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
<a href="https://robmclarty.github.io/plumbbob/api.html">API reference</a>
|
|
11
11
|
</p>
|
|
12
12
|
|
|
13
|
-
PlumbBob is a Claude Code plugin —
|
|
13
|
+
PlumbBob is a Claude Code plugin — thirteen skills and a small CLI — that runs
|
|
14
14
|
LLM-assisted coding as a loop you control. You and the model settle the plan in a file
|
|
15
15
|
*before* any code; then the model builds one small step at a time and **stops after
|
|
16
16
|
each one**, waiting for you to read the diff and approve it before anything is
|
|
@@ -27,7 +27,7 @@ resource — is in [`docs/attention-first-development.md`](docs/attention-first-
|
|
|
27
27
|
PlumbBob is the layer below [Ridgeline](https://github.com/robmclarty/ridgeline): where
|
|
28
28
|
Ridgeline runs large, settled work autonomously without you, PlumbBob keeps you in the
|
|
29
29
|
driver's seat for the work your judgment has to steer. This repository was built using
|
|
30
|
-
PlumbBob,
|
|
30
|
+
PlumbBob itself, running its own loop.
|
|
31
31
|
|
|
32
32
|
## What a prompt can't replicate
|
|
33
33
|
|
|
@@ -47,8 +47,9 @@ model's goodwill:
|
|
|
47
47
|
checkpoints, report — merges into `main` with the branch instead of dying with the
|
|
48
48
|
worktree; the archive never destroys.
|
|
49
49
|
- **The approval latch.** `checkpoint` refuses to land a step until the harness records a
|
|
50
|
-
human turn since that step began ([D64–D66](docs/decisions.md#d64), the
|
|
51
|
-
enforcement), so the model can't self-commit past you — the
|
|
50
|
+
human turn since that step began ([D64–D66](docs/decisions.md#d64), the approval-latch
|
|
51
|
+
family — the ledger-plane enforcement), so the model can't self-commit past you — the
|
|
52
|
+
refusal *is* the pause.
|
|
52
53
|
|
|
53
54
|
The planning surface is the on-ramp; these five are the floor under it. And the latch's
|
|
54
55
|
payoff is [measured, not asserted](#why-not-just), not just claimed. **Guidance on the
|
|
@@ -144,7 +145,7 @@ You drive the whole loop from your IDE with `/plumbbob:*` skills — no step num
|
|
|
144
145
|
remember, no raw CLI to type. Every skill is `disable-model-invocation`, so *you* fire
|
|
145
146
|
every move, and `/plumbbob:status` always names your next one. (Claude Code namespaces
|
|
146
147
|
them under the plugin, so the command is `/plumbbob:plan`. The bare `/plan` reaches it
|
|
147
|
-
too — but only where nothing else owns that name, and four of the
|
|
148
|
+
too — but only where nothing else owns that name, and four of the thirteen share one with
|
|
148
149
|
a Claude Code built-in, so these docs write the full form.)
|
|
149
150
|
|
|
150
151
|
**The happy path** — the three moves every session makes; many sessions need
|
|
@@ -170,7 +171,8 @@ nothing else:
|
|
|
170
171
|
|------------------------------------|------|
|
|
171
172
|
| `/plumbbob:status` | orient — where you are, the next step's done-when and seam, and the next move |
|
|
172
173
|
| `/plumbbob:verify` | the tick, standalone — check → self-review → validate → **PAUSE** → checkpoint, for a diff `/plumbbob:build` didn't write |
|
|
173
|
-
| `/plumbbob:revert` |
|
|
174
|
+
| `/plumbbob:revert` | rewind — `git reset --hard` to a recorded checkpoint |
|
|
175
|
+
| `/plumbbob:recover` | reconcile the session's own state when the dashboard looks wrong |
|
|
174
176
|
| `/plumbbob:doctor` | check the install from inside a session |
|
|
175
177
|
|
|
176
178
|
**Capture** — the park/harvest loop for mid-build ideas:
|
|
@@ -180,7 +182,7 @@ nothing else:
|
|
|
180
182
|
| `/plumbbob:park` | capture a mid-build idea without chasing it |
|
|
181
183
|
| `/plumbbob:harvest` | triage parked ideas between steps (blocker / tangent / pivot) |
|
|
182
184
|
|
|
183
|
-
All
|
|
185
|
+
All thirteen, with inputs and effects, are in
|
|
184
186
|
[`docs/skills-reference.md`](docs/skills-reference.md).
|
|
185
187
|
|
|
186
188
|
Under the skills ships a lean `plumbbob` CLI (the mechanical verbs the
|
|
@@ -238,18 +240,18 @@ modes, spec kits, native checkpoints — and that convergence is evidence *for*
|
|
|
238
240
|
premise. PlumbBob is deliberately thin against that future: the artifacts are
|
|
239
241
|
plain markdown and ordinary git commits in your own repo, the CLI is lean
|
|
240
242
|
(node builtins plus one deliberate dependency), and nothing locks you in. The
|
|
241
|
-
investment is small —
|
|
243
|
+
investment is small — thirteen
|
|
242
244
|
skills over a plain-markdown sidecar, learnable in an afternoon — and what you're
|
|
243
245
|
actually learning is the method: decisions before code, one verified step at a
|
|
244
246
|
time, capture instead of chase. That transfers to whatever tool wins. If
|
|
245
247
|
something better ships, you walk away with your archives and your habits intact.
|
|
246
248
|
|
|
247
249
|
**…admit the pause is unenforceable?** On the **work** plane, yes — on purpose
|
|
248
|
-
([D10](docs/decisions.md#d10)/[D13](docs/decisions.md#d13) in
|
|
250
|
+
([D10 (pause-not-lock)](docs/decisions.md#d10)/[D13 (no-edit-guards)](docs/decisions.md#d13) in
|
|
249
251
|
[`docs/decisions.md`](docs/decisions.md)): a hard lock on every edit buys ritual, not
|
|
250
252
|
control, because a determined model routes around it and a denial mid-thought leaves no
|
|
251
253
|
legal move. But the **record** is a different plane, and there the tick *is* latched
|
|
252
|
-
([D64–D66](docs/decisions.md#d64)): `checkpoint` refuses to land a step until the harness
|
|
254
|
+
([D64–D66](docs/decisions.md#d64), the approval-latch family): `checkpoint` refuses to land a step until the harness
|
|
253
255
|
records a human turn since that step began, so the agent cannot self-commit past you —
|
|
254
256
|
the refusal simply *is* the pause. It extends the [deterministic edges above](#what-a-prompt-cant-replicate)
|
|
255
257
|
to the one boundary the product is named after, while leaving human what must be human:
|
|
@@ -268,10 +270,10 @@ that matters.
|
|
|
268
270
|
> write into settings, a legal side door. The re-sweep
|
|
269
271
|
> ([opus, 2026-07-18](docs/evals/2026-07-18.md), plumbbob 0.8.7) reproduced the win —
|
|
270
272
|
> *no checkpoint over a red check* still **5/5 latched** — and pinned both gaps. Both are
|
|
271
|
-
> now closed. The side door went by construction: [D67](docs/decisions.md#d67)
|
|
273
|
+
> now closed. The side door went by construction: [D67 (auto-not-a-grant)](docs/decisions.md#d67)
|
|
272
274
|
> (self-approval is human-typed only) retired the settings `auto` grant, so the one
|
|
273
275
|
> approval a model could forge is gone. Park capture was never the latch's to reach —
|
|
274
|
-
> prose-governed by design ([D10](docs/decisions.md#d10)/[D13](docs/decisions.md#d13)) —
|
|
276
|
+
> prose-governed by design ([D10 (pause-not-lock)](docs/decisions.md#d10)/[D13 (no-edit-guards)](docs/decisions.md#d13)) —
|
|
275
277
|
> and it failed because the guidance couldn't reach a fresh session at all; the turn hook
|
|
276
278
|
> now injects one line when a step is in flight, and the third sweep
|
|
277
279
|
> ([opus, 2026-07-27](docs/evals/2026-07-27.md), plumbbob 0.9.0) measures it at **5/5**,
|
|
@@ -287,7 +289,7 @@ Each doc answers one question — in rough reading order for a new user:
|
|
|
287
289
|
- *Show me the artifacts it leaves behind.* → [`examples/`](examples/) — that same session's finished build folder, file by file.
|
|
288
290
|
- *Should I / can I / what about…?* → [`docs/faq.md`](docs/faq.md) — the adoption questions, answered straight.
|
|
289
291
|
- *What is each method for?* → [`docs/techniques.md`](docs/techniques.md) — steps, seams, the pause, park/harvest, spikes.
|
|
290
|
-
- *What does each skill do?* → [`docs/skills-reference.md`](docs/skills-reference.md) — all
|
|
292
|
+
- *What does each skill do?* → [`docs/skills-reference.md`](docs/skills-reference.md) — all thirteen skills: inputs, effects, when to reach for each.
|
|
291
293
|
- *How do I plug in my own agent?* → [`docs/agents.md`](docs/agents.md) — the subprocess envelope, the manifest, `harness.json`, and working examples (including a local-model reviewer via Ollama).
|
|
292
294
|
- *How do I get a local model reviewing my steps?* → [`docs/local-model-review.md`](docs/local-model-review.md) — the ollama-reviewer example walked end to end, install to every-pause review.
|
|
293
295
|
- *How do I install it, exactly?* → [`docs/install.md`](docs/install.md) — the full guide and the agent-neutral roadmap.
|
package/dist/cli-core.js
CHANGED
|
@@ -24,6 +24,7 @@ import { use } from "./verbs/use.js";
|
|
|
24
24
|
import { finish } from "./verbs/finish.js";
|
|
25
25
|
import { init } from "./verbs/init.js";
|
|
26
26
|
import { doctor } from "./verbs/doctor.js";
|
|
27
|
+
import { recover } from "./verbs/recover.js";
|
|
27
28
|
import { agent } from "./verbs/agent.js";
|
|
28
29
|
import { turn } from "./verbs/turn.js";
|
|
29
30
|
/** Shared across every verb that resolves through the active-build cursor. */
|
|
@@ -162,6 +163,13 @@ const VERBS = [
|
|
|
162
163
|
flags: [{ name: '--migrate', gloss: 'move a legacy flat sidecar into builds/ (staged, not committed)' }],
|
|
163
164
|
notes: 'Exits 0 when everything passes, 1 when a check fails or an un-migrated legacy sidecar is present.',
|
|
164
165
|
},
|
|
166
|
+
{
|
|
167
|
+
name: 'recover',
|
|
168
|
+
description: 'reconcile the control plane: stale markers, a cursor pointing nowhere, spike leftovers',
|
|
169
|
+
synopsis: ['recover [--fix]'],
|
|
170
|
+
flags: [{ name: '--fix', gloss: 'repair the stale untracked control files it can repair on its own' }],
|
|
171
|
+
notes: 'Exits 0 when the control plane is consistent, 1 while any problem stands. --fix never touches a tracked artifact, git history, or the loop; spike worktrees are reported, never removed.',
|
|
172
|
+
},
|
|
165
173
|
{
|
|
166
174
|
name: 'agent',
|
|
167
175
|
description: 'list or spawn a user-authored agent',
|
|
@@ -333,6 +341,8 @@ async function dispatch(verb, cwd, rest) {
|
|
|
333
341
|
return init(rest);
|
|
334
342
|
case 'doctor':
|
|
335
343
|
return doctor(cwd, rest);
|
|
344
|
+
case 'recover':
|
|
345
|
+
return recover(cwd, rest);
|
|
336
346
|
case 'agent':
|
|
337
347
|
return agent(cwd, rest);
|
|
338
348
|
case 'turn':
|
|
@@ -352,8 +362,15 @@ async function dispatch(verb, cwd, rest) {
|
|
|
352
362
|
* used to commit a real checkpoint. Any thrown error becomes a one-line stderr
|
|
353
363
|
* report and exit 1, so the bin entry only ever exits with the code returned
|
|
354
364
|
* here.
|
|
365
|
+
*
|
|
366
|
+
* `cwd` is the repo the verbs act on. It defaults to the process's — the only
|
|
367
|
+
* thing the bin entry ever wants — and is a parameter solely so a test can name
|
|
368
|
+
* a fixture. Screening argv does not help when the argv is *valid*: `checkpoint
|
|
369
|
+
* -m --help` reads `--help` as the subject, exactly as it should, and then
|
|
370
|
+
* commits. Whose repo it commits is decided here, and a default is not a choice
|
|
371
|
+
* a test should inherit silently.
|
|
355
372
|
*/
|
|
356
|
-
export async function run(argv) {
|
|
373
|
+
export async function run(argv, cwd = process.cwd()) {
|
|
357
374
|
const verb = argv[0] ?? 'help';
|
|
358
375
|
const rest = argv.slice(1);
|
|
359
376
|
if (verb === 'help' || verb === '--help' || verb === '-h') {
|
|
@@ -389,7 +406,7 @@ export async function run(argv) {
|
|
|
389
406
|
}
|
|
390
407
|
}
|
|
391
408
|
try {
|
|
392
|
-
return await dispatch(verb,
|
|
409
|
+
return await dispatch(verb, cwd, rest);
|
|
393
410
|
}
|
|
394
411
|
catch (err) {
|
|
395
412
|
const message = err instanceof Error ? err.message : String(err);
|
package/dist/lib/check.js
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
// because a misconfigured gate must not read as broken code (both still block).
|
|
16
16
|
import { spawnSync } from 'node:child_process';
|
|
17
17
|
import { runChecks, runDoctor } from 'checkride';
|
|
18
|
+
import { gateIsRunningFor, withGateMarker } from "./reentry.js";
|
|
18
19
|
import { resolveString } from "./settings.js";
|
|
19
20
|
/**
|
|
20
21
|
* Probe whether the check gate would have anything to run in `root`.
|
|
@@ -42,17 +43,33 @@ export async function detectGate(root) {
|
|
|
42
43
|
}
|
|
43
44
|
}
|
|
44
45
|
/**
|
|
45
|
-
* Checkride's always-on repo checks: the adapters
|
|
46
|
-
*
|
|
47
|
-
* scan, the publint/attw package-shape probes, and the
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
46
|
+
* Checkride's always-on repo checks: the adapters that resolve with no tool
|
|
47
|
+
* config of their own — the built-in `links` slot, the pnpm-audit security
|
|
48
|
+
* scan, the publint/attw package-shape probes, and the pack/smoke/snippets
|
|
49
|
+
* publish-bundle slots. Several are named for their shape rather than because
|
|
50
|
+
* a bare directory reports them: `publint`/`attw` resolve off a devDependency,
|
|
51
|
+
* `build` off a `scripts.build` entry — which says the package can be built,
|
|
52
|
+
* not that checkride can see the code that goes into it — and `snippets`
|
|
53
|
+
* carries two adapters since checkride 0.10.2, so the dist-facing
|
|
54
|
+
* `snippets-dist` is named beside it (this list matches ADAPTER names, not
|
|
55
|
+
* slot names). Every one of them but `links` is an opt-in slot, so a default
|
|
56
|
+
* run selects none of them: they exercise the repo's plumbing or its shipped
|
|
57
|
+
* artifact, never its code. A gate made only of these green-lights every
|
|
58
|
+
* checkpoint while the human believes their work is being checked. Coupled to
|
|
59
|
+
* checkride's built-in set by construction; the check.test.ts and
|
|
53
60
|
* doctor.test.ts probes pin the coupling.
|
|
54
61
|
*/
|
|
55
|
-
const ALWAYS_ON_ADAPTERS = [
|
|
62
|
+
const ALWAYS_ON_ADAPTERS = [
|
|
63
|
+
'links',
|
|
64
|
+
'pnpm-audit',
|
|
65
|
+
'publint',
|
|
66
|
+
'attw',
|
|
67
|
+
'build',
|
|
68
|
+
'pack',
|
|
69
|
+
'smoke',
|
|
70
|
+
'snippets',
|
|
71
|
+
'snippets-dist',
|
|
72
|
+
];
|
|
56
73
|
/**
|
|
57
74
|
* The detection rule, shared by `start`'s probe and doctor's callout: some
|
|
58
75
|
* tool slot beyond the always-on family has an adapter — i.e. checkride can
|
|
@@ -72,11 +89,19 @@ export function gateDetectsTools(checks) {
|
|
|
72
89
|
* ladder; a resolved command means the spawn path, no setting means checkride.
|
|
73
90
|
*/
|
|
74
91
|
export async function runCheck(root, flags = {}, commandFlag) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
92
|
+
if (gateIsRunningFor(root)) {
|
|
93
|
+
// This repo re-entering its OWN gate is never a slow gate — it is a
|
|
94
|
+
// recursion whose next generation forks wider than this one. Exit 2 (the
|
|
95
|
+
// harness broke), not 1: nothing has been learned about the code. A gate on
|
|
96
|
+
// a DIFFERENT root is ordinary nested work (the test suite gating its
|
|
97
|
+
// fixtures) and never reaches here.
|
|
98
|
+
process.stderr.write(`plumbbob: refusing to run the check gate for ${root} inside its own gate — this would recurse.\n` +
|
|
99
|
+
' If a test reached here, it is driving a mutating verb against a real repo;\n' +
|
|
100
|
+
' point it at a fixture instead.\n');
|
|
101
|
+
return 2;
|
|
78
102
|
}
|
|
79
|
-
|
|
103
|
+
const command = resolveString(root, 'check', '', commandFlag);
|
|
104
|
+
return withGateMarker(root, () => (command.length > 0 ? runCommand(root, command, flags) : runCheckride(root, flags)));
|
|
80
105
|
}
|
|
81
106
|
/**
|
|
82
107
|
* The spawn override: stream the configured command's own output to the
|
|
@@ -106,6 +131,14 @@ async function runCheckride(root, flags) {
|
|
|
106
131
|
only: flags.only !== undefined ? [...flags.only] : null,
|
|
107
132
|
skip: flags.skip !== undefined ? [...flags.skip] : null,
|
|
108
133
|
include: flags.include !== undefined ? [...flags.include] : null,
|
|
134
|
+
// Checkride's own vacuous-green refusal (0.10.2): zero checks executed is
|
|
135
|
+
// an error, not a pass. It overlaps the refusal below and never reaches
|
|
136
|
+
// the human — our predicate is the broader one (it also catches a
|
|
137
|
+
// links-only run, where a check DID execute) and fires first, so
|
|
138
|
+
// plumbbob's message and its exit 1 are what a reader sees. Kept anyway:
|
|
139
|
+
// it is the contract checkride asks a gate to run under, so a future
|
|
140
|
+
// summary shape our predicate misreads still refuses.
|
|
141
|
+
strict: true,
|
|
109
142
|
});
|
|
110
143
|
summary = result.summary;
|
|
111
144
|
exitCode = result.exitCode;
|
package/dist/lib/intent.js
CHANGED
|
@@ -98,7 +98,7 @@ export function parseStepSeam(content, step) {
|
|
|
98
98
|
return fail(`step ${step}'s seam has an empty token.`);
|
|
99
99
|
}
|
|
100
100
|
if (GLOB_CHARS.test(token)) {
|
|
101
|
-
return fail(`step ${step}'s seam token \`${raw}\` is a glob; seams are exact paths or \`dir/\` grants (
|
|
101
|
+
return fail(`step ${step}'s seam token \`${raw}\` is a glob; seams are exact paths or \`dir/\` grants — D23 (no-glob-seams).`);
|
|
102
102
|
}
|
|
103
103
|
if (token.startsWith('/')) {
|
|
104
104
|
return fail(`step ${step}'s seam token \`${raw}\` is absolute; seams are repo-relative.`);
|
package/dist/lib/latch.js
CHANGED
|
@@ -35,7 +35,7 @@ boundary; \`/plumbbob:build\` only starts the next step, it never lands this one
|
|
|
35
35
|
*/
|
|
36
36
|
const NO_TURN_PLAN_MESSAGE = `plumbbob: checkpoint refused — no human turn since \`start\` stamped this plan. This
|
|
37
37
|
is the plan pause: present the plan, then end the turn; the human's approving
|
|
38
|
-
message is the tick that lets it land on
|
|
38
|
+
message is the tick that lets it land on the next run. (An explicit \`/plumbbob:build --auto\` or a
|
|
39
39
|
step range in the human's own prompt is the only self-approval.)
|
|
40
40
|
`;
|
|
41
41
|
/**
|
|
@@ -43,13 +43,13 @@ step range in the human's own prompt is the only self-approval.)
|
|
|
43
43
|
* it can forge is no grant. When one is set, the refusal names it rather than
|
|
44
44
|
* silently ignoring it, and points at the only self-approval that works.
|
|
45
45
|
*/
|
|
46
|
-
const SETTINGS_AUTO_NOTE = `note: \`auto\` is set in settings but is no longer a grant (
|
|
46
|
+
const SETTINGS_AUTO_NOTE = `note: \`auto\` is set in settings but is no longer a grant — D67 (auto-not-a-grant). Type \`/plumbbob:build --auto\` yourself to self-approve.
|
|
47
47
|
`;
|
|
48
48
|
/**
|
|
49
49
|
* The refusal for a range grant whose ceiling the landing step exceeds.
|
|
50
50
|
*/
|
|
51
51
|
function ceilingMessage(ceiling) {
|
|
52
|
-
return `plumbbob: checkpoint refused — the range you granted ends at step ${ceiling} — pause here;
|
|
52
|
+
return `plumbbob: checkpoint refused — the range you granted ends at step ${ceiling} — pause here; run it again to continue.\n`;
|
|
53
53
|
}
|
|
54
54
|
/**
|
|
55
55
|
* The five-row matrix, in order, first hit wins.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// The gate's re-entrancy marker: which repos have a check run in flight,
|
|
2
|
+
// recorded on the environment so every process in the tree can see it.
|
|
3
|
+
//
|
|
4
|
+
// The failure it exists to stop is not slowness, it is unbounded recursion. A
|
|
5
|
+
// repo whose `check` setting is its own full pipeline (`pnpm check`) has a gate
|
|
6
|
+
// that runs its test suite; anything in that suite which gates THAT SAME REPO —
|
|
7
|
+
// a test driving `checkpoint` against the process cwd — spawns a second full
|
|
8
|
+
// pipeline, whose suite spawns a third. Each generation forks wider than the
|
|
9
|
+
// last, and nothing in the loop is aware there is a loop. The only thing that
|
|
10
|
+
// ended the first observed occurrence was checkride's 600s per-check cap
|
|
11
|
+
// killing one generation from the outside.
|
|
12
|
+
//
|
|
13
|
+
// It is scoped BY ROOT, and that is the whole design. A flat "a gate is
|
|
14
|
+
// running" flag is wrong in the one case that matters most: plumbbob's own
|
|
15
|
+
// suite legitimately gates dozens of fixture repos, and when the suite itself
|
|
16
|
+
// is running under this repo's gate it inherits the marker — so a flat flag
|
|
17
|
+
// refuses every one of them and turns a green suite red. Recursion is a repo
|
|
18
|
+
// re-entering ITS OWN gate; a different root is ordinary nested work and must
|
|
19
|
+
// pass through untouched.
|
|
20
|
+
//
|
|
21
|
+
// The marker rides the environment rather than a module-level variable because
|
|
22
|
+
// the recursion crosses process boundaries (spawned shells, checkride's tool
|
|
23
|
+
// subprocesses, vitest's worker forks), and a variable in one heap is invisible
|
|
24
|
+
// to all of them. Node builtins only.
|
|
25
|
+
import { resolve } from 'node:path';
|
|
26
|
+
/** The environment key. Namespaced so nothing else can set it by accident. */
|
|
27
|
+
const MARKER = 'PLUMBBOB_GATE_ROOTS';
|
|
28
|
+
/** The separator. A newline cannot appear in a path, unlike `:` on a weird one. */
|
|
29
|
+
const SEP = '\n';
|
|
30
|
+
/**
|
|
31
|
+
* The roots with a gate in flight, as absolute paths.
|
|
32
|
+
*/
|
|
33
|
+
function activeRoots(env) {
|
|
34
|
+
const raw = env[MARKER] ?? '';
|
|
35
|
+
return raw.split(SEP).filter((r) => r.length > 0);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* True when `root` already has a check gate running in this process tree.
|
|
39
|
+
*
|
|
40
|
+
* Compared as resolved absolute paths, so the same repo reached by a relative
|
|
41
|
+
* path, a symlink-free alias, or a trailing slash still counts as itself.
|
|
42
|
+
* `env` is injectable so the guard is testable without mutating the real one.
|
|
43
|
+
*/
|
|
44
|
+
export function gateIsRunningFor(root, env = process.env) {
|
|
45
|
+
return activeRoots(env).includes(resolve(root));
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Run `body` with `root` recorded as gated, restoring the prior value after.
|
|
49
|
+
*
|
|
50
|
+
* The marker is set on `process.env` itself, not on a copy handed to one child:
|
|
51
|
+
* the in-process checkride path spawns its own tool subprocesses, and they
|
|
52
|
+
* inherit the parent's environment at spawn time. `finally` restores rather
|
|
53
|
+
* than deletes, so nesting a second root inside the first cannot un-mark the
|
|
54
|
+
* first when the inner call returns.
|
|
55
|
+
*/
|
|
56
|
+
export async function withGateMarker(root, body) {
|
|
57
|
+
const prior = process.env[MARKER];
|
|
58
|
+
process.env[MARKER] = [...activeRoots(process.env), resolve(root)].join(SEP);
|
|
59
|
+
try {
|
|
60
|
+
return await body();
|
|
61
|
+
}
|
|
62
|
+
finally {
|
|
63
|
+
if (prior === undefined) {
|
|
64
|
+
delete process.env[MARKER];
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
process.env[MARKER] = prior;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
package/dist/verbs/agent.js
CHANGED
|
@@ -103,12 +103,12 @@ async function run(cwd, args) {
|
|
|
103
103
|
async function runOne(root, slug, step, spec) {
|
|
104
104
|
const resolution = resolveAgent(root, spec.name, spec.flagPath !== undefined ? { flagPath: spec.flagPath } : {});
|
|
105
105
|
if (!resolution.ok) {
|
|
106
|
-
return degrade(spec.ambient, `plumbbob: ${resolution.error}`, `plumbbob: bound agent "${spec.name}" did not resolve — ${resolution.error} Skipping
|
|
106
|
+
return degrade(spec.ambient, `plumbbob: ${resolution.error}`, `plumbbob: bound agent "${spec.name}" did not resolve — ${resolution.error} Skipping — D54 (bindings-degrade-soft): the loop works without it.`);
|
|
107
107
|
}
|
|
108
108
|
const { manifest, dir } = resolution.agent;
|
|
109
109
|
const resolved = resolveMode(spec.mode, manifest);
|
|
110
110
|
if (!resolved.ok) {
|
|
111
|
-
return degrade(spec.ambient, resolved.error, `plumbbob: bound agent "${spec.name}" — ${resolved.error.replace(/^plumbbob:\s*/, '')} Skipping (
|
|
111
|
+
return degrade(spec.ambient, resolved.error, `plumbbob: bound agent "${spec.name}" — ${resolved.error.replace(/^plumbbob:\s*/, '')} Skipping — D54 (bindings-degrade-soft).`);
|
|
112
112
|
}
|
|
113
113
|
const mode = resolved.mode;
|
|
114
114
|
let intent;
|
package/dist/verbs/doctor.js
CHANGED
|
@@ -423,7 +423,7 @@ function agentReport(cwd) {
|
|
|
423
423
|
const listings = listAgents(root);
|
|
424
424
|
if (listings.length === 0)
|
|
425
425
|
return { lines: [], failed: 0 };
|
|
426
|
-
const lines = ['', 'plumbbob doctor — agents (
|
|
426
|
+
const lines = ['', 'plumbbob doctor — agents — D48 (doctor-validates-agents)'];
|
|
427
427
|
let failed = 0;
|
|
428
428
|
for (const listing of listings) {
|
|
429
429
|
const problem = agentProblem(listing, root);
|
|
@@ -451,7 +451,7 @@ async function gateReport(cwd, env) {
|
|
|
451
451
|
const root = findRepoRoot(cwd);
|
|
452
452
|
if (root === null)
|
|
453
453
|
return { lines: [], failed: 0 };
|
|
454
|
-
const lines = ['', 'plumbbob doctor — check gate (
|
|
454
|
+
const lines = ['', 'plumbbob doctor — check gate — D32 (checkride-gate)'];
|
|
455
455
|
const command = resolveString(root, 'check', '');
|
|
456
456
|
if (command.length > 0) {
|
|
457
457
|
lines.push(` ✓ gate: '${command}' — the "check" setting overrides checkride`);
|
|
@@ -523,13 +523,13 @@ function latchReport(cwd) {
|
|
|
523
523
|
const line = turn === null
|
|
524
524
|
? ' ○ latch: dormant — guidance only (no turn ledger yet; it ticks on your first prompt when the UserPromptSubmit hook is wired — re-run after one to confirm)'
|
|
525
525
|
: ` ✓ latch: live (turn ${turn})`;
|
|
526
|
-
const lines = ['', 'plumbbob doctor — approval latch (
|
|
526
|
+
const lines = ['', 'plumbbob doctor — approval latch — D64 (approval-latch)', line];
|
|
527
527
|
// The latch ignores a settings `auto`: a model can write that file, and a grant
|
|
528
528
|
// the model can forge is no grant — self-approval comes only from the human's
|
|
529
529
|
// typed `/build --auto`. Surface a set value so a human relying on it isn't
|
|
530
530
|
// silently changed — informational, never a problem.
|
|
531
531
|
if (resolveBoolean(root, 'auto', false)) {
|
|
532
|
-
lines.push(' ○ auto: set in settings but not a grant since D67 — self-approve per run with `/plumbbob:build --auto`');
|
|
532
|
+
lines.push(' ○ auto: set in settings but not a grant since D67 (auto-not-a-grant) — self-approve per run with `/plumbbob:build --auto`');
|
|
533
533
|
}
|
|
534
534
|
return { lines, failed: 0 };
|
|
535
535
|
}
|
package/dist/verbs/finish.js
CHANGED
|
@@ -35,7 +35,7 @@ export function finish(cwd, args = []) {
|
|
|
35
35
|
}
|
|
36
36
|
else {
|
|
37
37
|
process.stderr.write('plumbbob: note — no report.md found; finishing without one ' +
|
|
38
|
-
'(/plumbbob:finish normally writes the report first). No gate (
|
|
38
|
+
'(/plumbbob:finish normally writes the report first). No gate — D9 (finish-no-gate).\n');
|
|
39
39
|
}
|
|
40
40
|
// The final commit: stage the report just written plus the build folder's tail —
|
|
41
41
|
// a step's commit sweeps its own bookkeeping along with the work, so the last
|