plumbbob 0.9.2 → 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 +298 -24
- 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 +5 -4
- package/dist/verbs/check.js +6 -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
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: qa
|
|
3
|
+
description: Read checkride's quality artifacts — surviving mutants, dead code, duplication and the health score — and say what the test suite actually proves. Use when asked how healthy the codebase is, whether the tests are any good, where the risk or the tech debt is, what mutation testing found, or which files need better coverage. Reads a bounded report instead of megabytes of `.check/` artifacts, runs nothing, and reports which quality dimensions were never measured rather than guessing at them.
|
|
4
|
+
argument-hint: "[repo-path]"
|
|
5
|
+
allowed-tools: Read, Grep, Glob, Bash(node *), Bash(pnpm *), Bash(npx checkride*), Bash(yarn *), Bash(bunx *), Bash(wc *), Bash(git log *)
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# checkride: read the quality signal
|
|
9
|
+
|
|
10
|
+
checkride's gate answers one question — is the work done? — and answers it
|
|
11
|
+
pass/fail. These four artifacts answer a different one: **is the suite actually
|
|
12
|
+
testing anything, and where is the risk?** Nothing here is red or green. No
|
|
13
|
+
threshold fires. That is exactly why this is the easiest report in the repo to
|
|
14
|
+
hallucinate: with no failure to anchor to, a plausible-sounding list of eight
|
|
15
|
+
issues costs nothing to write and means nothing.
|
|
16
|
+
|
|
17
|
+
So the discipline is inverted from triage. The triage skill starts from a
|
|
18
|
+
failure and narrows to one cause. This skill starts from evidence and stops when
|
|
19
|
+
the evidence stops — which is sometimes after one finding, and sometimes after
|
|
20
|
+
none.
|
|
21
|
+
|
|
22
|
+
For a red gate, use the triage skill instead (`/checkride:check` under the
|
|
23
|
+
plugin, `/checkride-check` in Cursor, or `checkride triage` directly). This skill
|
|
24
|
+
reads what a *past* run left behind and never runs the gate itself.
|
|
25
|
+
|
|
26
|
+
## 1. Run the reader
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pnpm exec checkride qa
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Substitute the repo's package manager (`npx checkride`, `yarn checkride`, `bunx
|
|
33
|
+
checkride`). Pass a repo path as the one optional argument to read somewhere
|
|
34
|
+
other than the current directory.
|
|
35
|
+
|
|
36
|
+
If checkride is not a dependency of the target repo, run the copy the plugin
|
|
37
|
+
ships instead: `node "${CLAUDE_PLUGIN_ROOT}/dist/qa/cli.js"`. Both entry points
|
|
38
|
+
render the identical report.
|
|
39
|
+
|
|
40
|
+
It **runs nothing** — no stryker, no fallow, not the gate. It opens `.check/`,
|
|
41
|
+
folds each artifact to a ranked short list, and renders under 8 KB (the same
|
|
42
|
+
ceiling `--digest` uses). In checkride's own repo that is 2.3 MB of
|
|
43
|
+
`mutation.json` reduced to a page, which is the only reason a mutation finding
|
|
44
|
+
is affordable at all.
|
|
45
|
+
|
|
46
|
+
**Do not open any `.check/` file before this report names one.** Every count
|
|
47
|
+
below comes from a full pass over the artifact; the lists are ranked, not
|
|
48
|
+
truncated at random.
|
|
49
|
+
|
|
50
|
+
## 2. The ledger is the answer, not the preamble
|
|
51
|
+
|
|
52
|
+
Because the reader runs nothing, its first job is to say what it is actually
|
|
53
|
+
holding. Two head lines, then a table — and in a default consumer repo that is
|
|
54
|
+
very nearly the *whole* report.
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
- summary: `.check/summary.json` — `schema_version` 1, 1.5m ago, 1.5s
|
|
58
|
+
- covered: 3 slot(s) ran — links, docs, spell
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
- **`summary`** — what the artifacts beside it belong to, and how long ago. If it
|
|
62
|
+
reads `` `schema_version` is 2, not 1; STOP ``, then **stop**: the reader is
|
|
63
|
+
pinned to schema 1, and guessing across a version is how you invent a finding.
|
|
64
|
+
- **`covered`** — the slots that run actually touched. Three of seventeen means
|
|
65
|
+
the artifacts on disk mostly belong to *some other* run, and the ledger's
|
|
66
|
+
staleness column is the only thing standing between you and reporting them as
|
|
67
|
+
current. `covered: nothing` means there is no readable summary at all, so no
|
|
68
|
+
artifact here can be dated and none of them is evidence.
|
|
69
|
+
|
|
70
|
+
**Open your report with that covered count and the run's age**, the same way
|
|
71
|
+
the triage skill does. A quality claim without its coverage is an assertion
|
|
72
|
+
about the whole repo built from a fraction of it.
|
|
73
|
+
|
|
74
|
+
| state | what it means | what it licenses you to say |
|
|
75
|
+
| --- | --- | --- |
|
|
76
|
+
| `read` | fresh — written by the run whose summary sits beside it | evidence, present tense |
|
|
77
|
+
| `STALE` | on disk, but older than that run's start | a fact about the past, with the age always attached |
|
|
78
|
+
| `not opted in` | the slot is absent from `checkride.config.json`, so no run produces it | **nothing about this dimension** — name the remedy instead |
|
|
79
|
+
| `absent` | opted in, but no file — the slot has not run, or produced nothing | nothing; name the command |
|
|
80
|
+
| `too-large` / `unreadable` / `unrecognized` | the bytes are there but not usable | nothing; say which, because each has a different cause |
|
|
81
|
+
|
|
82
|
+
Two rules follow, and they are the ones that make this skill honest.
|
|
83
|
+
|
|
84
|
+
**A gap is a finding, not an edge case.** Three of the four artifacts come from
|
|
85
|
+
opt-in slots, and checkride's own gate never runs `mutation` at all. In a fresh
|
|
86
|
+
consumer repo you will find `dead.json` and nothing else. The honest report
|
|
87
|
+
there is the ledger plus the two commands that would produce data — *not* a page
|
|
88
|
+
of quality assessment extrapolated from one artifact. The reader already prints
|
|
89
|
+
the exact command or config entry for each gap; quote it rather than inventing
|
|
90
|
+
one.
|
|
91
|
+
|
|
92
|
+
**Never launder a stale number into a present-tense claim.** "Mutation score is
|
|
93
|
+
71%" is wrong when the file is 7.6 days old. "As of a stryker run 7.6 days ago,
|
|
94
|
+
71%" is right, and it carries its own warning. When a stale artifact is
|
|
95
|
+
load-bearing for a finding, check whether the code moved under it:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
git log -1 --format=%cr -- src/init.ts
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
If the file changed more recently than the artifact, the artifact describes code
|
|
102
|
+
that no longer exists. Say so and stop — do not report its findings as current.
|
|
103
|
+
|
|
104
|
+
## 3. Read in evidence order — strongest proof first
|
|
105
|
+
|
|
106
|
+
The reader emits its sections in the order you should reason about them, and
|
|
107
|
+
that order is not arbitrary. It ranks by **how much of the claim the artifact
|
|
108
|
+
already proved for you**:
|
|
109
|
+
|
|
110
|
+
1. **Surviving mutants** — the strongest evidence in the repo. Stryker *changed
|
|
111
|
+
the code* and the suite still passed. That is a demonstrated hole, not an
|
|
112
|
+
opinion, and no amount of coverage percentage can contradict it.
|
|
113
|
+
2. **Dead code** — a static claim about reachability. Usually right; wrong
|
|
114
|
+
exactly where entry points are dynamic, which is why `fallow.toml`'s `entry`
|
|
115
|
+
list exists.
|
|
116
|
+
3. **Structure** (`dupes`, `health`) — measurements against thresholds somebody
|
|
117
|
+
configured. A hotspot is a place to look, not a defect.
|
|
118
|
+
4. **Your own reading of the source** — last, and only when it names a file and
|
|
119
|
+
a line.
|
|
120
|
+
|
|
121
|
+
Work down that list and stop where the evidence stops. That is the whole
|
|
122
|
+
anti-hallucination device: findings are sorted by proof, so a short report is a
|
|
123
|
+
*strong* one.
|
|
124
|
+
|
|
125
|
+
### Mutation: survived and no-coverage want different fixes
|
|
126
|
+
|
|
127
|
+
The two undetected states look alike in a table and mean opposite things.
|
|
128
|
+
|
|
129
|
+
- **No-coverage** — no test reaches the line at all. The fix is a test that
|
|
130
|
+
executes it.
|
|
131
|
+
- **Survived** — a test *does* reach it and asserts nothing that would notice
|
|
132
|
+
the change. The fix is a stronger assertion in the test that already runs.
|
|
133
|
+
Adding another test that also does not look is the standard wrong answer, and
|
|
134
|
+
it raises line coverage while changing nothing.
|
|
135
|
+
|
|
136
|
+
The mutator name tells you what kind of hole it is:
|
|
137
|
+
|
|
138
|
+
| mutator | what its survival proves |
|
|
139
|
+
| --- | --- |
|
|
140
|
+
| `ConditionalExpression` | a branch condition can be forced true or false and nothing notices — usually one side of the branch is decorative. The most common survivor almost everywhere (359 of them in checkride's own repo) and the most informative |
|
|
141
|
+
| `BlockStatement` | an entire function body was emptied and the suite passed. The loudest signal in the table |
|
|
142
|
+
| `EqualityOperator` | a comparison flipped undetected — a boundary case nothing exercises |
|
|
143
|
+
| `LogicalOperator` | one arm of an `&&` / `\|\|` is never the deciding one in any test |
|
|
144
|
+
| `ArrayDeclaration`, `ObjectLiteral` | a literal was emptied unnoticed — the *contents* of that data are unasserted. Common on config tables, and often low-value (see below) |
|
|
145
|
+
| `Regex`, `StringLiteral` | the pattern or text is unasserted; frequently a message nobody should assert on |
|
|
146
|
+
|
|
147
|
+
**Not every survivor is worth killing.** Equivalent mutants — ones with no
|
|
148
|
+
observable behavior difference — are real and common: log text, a default
|
|
149
|
+
immediately overwritten, a `??` on a value that is never null. A suite driven to
|
|
150
|
+
100% mutation score is a suite full of assertions on things nobody cares about.
|
|
151
|
+
Rank survivors by **what the mutant proves about a path a user can reach**, and
|
|
152
|
+
say when you are dismissing one and why.
|
|
153
|
+
|
|
154
|
+
**Rank is not priority.** The reader ranks files by undetected count, which
|
|
155
|
+
tracks file *size* at least as much as risk — `src/init.ts` tops checkride's own
|
|
156
|
+
table largely because it is the biggest file with the most mutants. Read what
|
|
157
|
+
the survivors are before treating the top row as the most important work.
|
|
158
|
+
|
|
159
|
+
## 4. Ground the finding, or drop it
|
|
160
|
+
|
|
161
|
+
A finding must be able to name three things: **the artifact it came from, the
|
|
162
|
+
file and line, and — for a mutation finding — the test that should have caught
|
|
163
|
+
it and did not.** If you cannot name the test file you would edit, you have a
|
|
164
|
+
metric, not a finding.
|
|
165
|
+
|
|
166
|
+
So for the one or two survivors that look genuinely load-bearing:
|
|
167
|
+
|
|
168
|
+
1. Open the source at the sample line the report gave you (`Read` with an
|
|
169
|
+
`offset`, not the whole file).
|
|
170
|
+
2. Find the test that covers it — `src/__tests__/<name>.test.ts`, or `Grep` for
|
|
171
|
+
the function name.
|
|
172
|
+
3. Read what that test asserts. The finding is the sentence that comes out:
|
|
173
|
+
*"`resolveOrder` is called in three tests and all three assert only the
|
|
174
|
+
length of the result, so flipping its `<=` to `<` changes nothing they
|
|
175
|
+
check."*
|
|
176
|
+
|
|
177
|
+
"Coverage could be improved here" is not that sentence.
|
|
178
|
+
|
|
179
|
+
**Open at most two or three files.** If the report ranks eight, read the top one
|
|
180
|
+
properly rather than all eight badly — the same economy the triage skill uses
|
|
181
|
+
when it opens exactly one artifact.
|
|
182
|
+
|
|
183
|
+
## 5. Report
|
|
184
|
+
|
|
185
|
+
- **Evidence** — the covered-slot count, the run's age, then the ledger in a
|
|
186
|
+
line or two: what is fresh, what is stale and by how much, what was never
|
|
187
|
+
produced. Always first. A report that opens with a finding is a report that hid
|
|
188
|
+
its own uncertainty.
|
|
189
|
+
- **What the artifacts prove** — findings in evidence order, each grounded per
|
|
190
|
+
step 4. As many as the evidence supports, and no more.
|
|
191
|
+
- **What would produce the missing evidence** — the reader's own command or
|
|
192
|
+
config line for each gap. This is often the single most useful thing you can
|
|
193
|
+
say.
|
|
194
|
+
- **Judgment** — clearly labelled as yours, last, and only where it names a
|
|
195
|
+
file.
|
|
196
|
+
|
|
197
|
+
### The failure mode this skill exists to prevent
|
|
198
|
+
|
|
199
|
+
**Produce no fixed-size list.** Not "top 5 issues", not eight findings, not one
|
|
200
|
+
per artifact. The count is whatever the evidence supports, and **zero is a
|
|
201
|
+
legitimate answer** — a repo with a fresh, empty `dead.json` and three
|
|
202
|
+
unmeasured dimensions has exactly one honest thing to report: that three of four
|
|
203
|
+
quality dimensions are unmeasured. Padding that to five means inventing four.
|
|
204
|
+
|
|
205
|
+
Three specific ways it goes wrong:
|
|
206
|
+
|
|
207
|
+
- **Restating the metric as a finding.** "Health score is 80.9/B" is the ledger.
|
|
208
|
+
A finding names which function costs the points and why.
|
|
209
|
+
- **Grading the grade.** No number in `health.json` is a defect; the thresholds
|
|
210
|
+
are a configured opinion, and the score is 100 minus the penalties. When
|
|
211
|
+
nothing is over any threshold and the whole penalty is hotspots and unit size,
|
|
212
|
+
say that — do not manufacture violations to explain a B.
|
|
213
|
+
- **Turning a ranked list into a to-do list.** The tables are ranked so you know
|
|
214
|
+
where to *look*. Copying the top five rows into "recommendations" is
|
|
215
|
+
transcription wearing analysis's clothes.
|
|
216
|
+
|
|
217
|
+
## What this skill does not do
|
|
218
|
+
|
|
219
|
+
- **It runs nothing.** Not stryker (minutes to hours, and it rewrites your
|
|
220
|
+
source while it works), not fallow, not the gate. Naming the command is the
|
|
221
|
+
deliverable; running it is the human's call.
|
|
222
|
+
- **It does not gate.** None of these four dimensions has a pass/fail line, and
|
|
223
|
+
inventing one — "mutation score should be above 80" — turns a measurement into
|
|
224
|
+
a target, which is how it stops being a measurement.
|
|
225
|
+
- **It does not write tests.** Naming the unasserted branch is the deliverable.
|
|
226
|
+
Writing the test is the next request, and it should start from the named
|
|
227
|
+
mutant.
|
|
228
|
+
- **It does not triage a red gate.** That is the triage skill, which runs the
|
|
229
|
+
gate and reads different artifacts entirely.
|
|
230
|
+
- **It does not touch the baseline.** `checkride baseline` hides findings
|
|
231
|
+
permanently; that is never a reading step.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "plumbbob",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.5",
|
|
4
4
|
"description": "Attention-first build process: 12 skills + a CLI that keep you the decider — guidance on the work, a latch on the record.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude-code",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"vitest": "4.1.9"
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"checkride": "0.
|
|
62
|
+
"checkride": "0.10.2"
|
|
63
63
|
},
|
|
64
64
|
"bundleDependencies": [
|
|
65
65
|
"checkride"
|
package/skills/build/SKILL.md
CHANGED
|
@@ -16,14 +16,14 @@ another harness and go straight to `/plumbbob:verify` instead — plumbbob does
|
|
|
16
16
|
the diff appeared. When you do run it, it reads the plan, writes the step, and
|
|
17
17
|
carries straight through to the verify pause.
|
|
18
18
|
|
|
19
|
-
Since `/plumbbob:plan` lays down the whole step list up front, the happy path is to
|
|
19
|
+
Since `/plumbbob:plan` lays down the whole step list up front, the happy path is to run
|
|
20
20
|
`/plumbbob:build` once per step until done — each run builds the next undone step and stops
|
|
21
|
-
at the pause for your approval. **
|
|
21
|
+
at the pause for your approval. **Running `/plumbbob:build` again is itself the clock tick.**
|
|
22
22
|
|
|
23
23
|
A model note: this skill **inherits the session model** — nothing pins or switches
|
|
24
24
|
it. If the step you're about to build carries a `- model:` recommendation that
|
|
25
25
|
differs from the model you're running as, say so before implementing — the human can
|
|
26
|
-
`/model` and
|
|
26
|
+
switch with `/model` and rerun to honor it, or wave you on. Advisory, never a gate.
|
|
27
27
|
|
|
28
28
|
## What this skill does, in order
|
|
29
29
|
|
|
@@ -42,7 +42,8 @@ differs from the model you're running as, say so before implementing — the hum
|
|
|
42
42
|
`spike-NN-<slug>.md` in the build folder, stamped `via: step <n>`), then work the
|
|
43
43
|
experiment and record your **Findings** and **Verdict** there. A recorded verdict is
|
|
44
44
|
what the step's done-when should check — the report, not just the code, is the
|
|
45
|
-
deliverable. This is the same artifact `/plumbbob:spike` produces for a mid-build fork
|
|
45
|
+
deliverable. This is the same artifact `/plumbbob:spike` produces for a mid-build fork
|
|
46
|
+
— D70 (spike-reports).
|
|
46
47
|
3. **Read the plan.** Read the step's **done-when**, its **seam**, and the
|
|
47
48
|
**Decisions** and **Constraints** in `intent.md`. Build to *that* — the deciding
|
|
48
49
|
already happened, off the chat.
|
|
@@ -66,7 +67,8 @@ differs from the model you're running as, say so before implementing — the hum
|
|
|
66
67
|
raw output under `.check/` for the actual diagnostics; while iterating on a fix,
|
|
67
68
|
narrow the loop with `plumbbob check --bail --only <slots>` — the checkpoint gate
|
|
68
69
|
still runs everything) → self-review the diff against the done-when, the Decisions,
|
|
69
|
-
and the Constraints (a single structured read
|
|
70
|
+
and the Constraints (a single structured read; cite each with its slug from
|
|
71
|
+
`intent.md` — `C1 (no-new-deps)`, never a bare `C1`) → validate → **PAUSE
|
|
70
72
|
for the human's approval** → only on approval, checkpoint with
|
|
71
73
|
`plumbbob checkpoint <n> --body <<'BODY' … BODY` — a commit body **proportional to the
|
|
72
74
|
step** (a line for a trivial change, a short paragraph for a meatier one; no TIL scan,
|
|
@@ -74,13 +76,14 @@ differs from the model you're running as, say so before implementing — the hum
|
|
|
74
76
|
build-log's `## Log`, so the history writes itself — you only supply the body (or omit
|
|
75
77
|
`--body` for the deterministic done-when + seam + diffstat fallback). Do **not** bump
|
|
76
78
|
the version or changelog — that is the human's `/version` call.
|
|
77
|
-
- **A drifted subject is reconciled at the pause, never silently
|
|
78
|
-
title *is* the checkpoint subject (
|
|
79
|
-
corrected subject at the pause — `planned title → proposed
|
|
80
|
-
explicit approval, and only on approval land it by adding
|
|
81
|
-
checkpoint. Present nothing and the deterministic
|
|
82
|
-
untouched: the reconcile is the human-approved exception,
|
|
83
|
-
is the agent-authored subject D68
|
|
79
|
+
- **A drifted subject is reconciled at the pause, never silently.** The planned
|
|
80
|
+
title *is* the checkpoint subject — D68 (conventional-subjects). If the diff drifted
|
|
81
|
+
from it, **present** a corrected subject at the pause — `planned title → proposed
|
|
82
|
+
subject`, one line — for explicit approval, and only on approval land it by adding
|
|
83
|
+
`-m "<subject>"` to the checkpoint. Present nothing and the deterministic
|
|
84
|
+
title-derived subject lands untouched: the reconcile is the human-approved exception,
|
|
85
|
+
not a quiet `-m` swap (which is the agent-authored subject D68 (conventional-subjects)
|
|
86
|
+
refuses).
|
|
84
87
|
- **If `plumbbob status` shows a `harness bindings:` block**, fold any bound
|
|
85
88
|
`after`-agents into that self-review as advisory input — see **§ Running bound
|
|
86
89
|
agents**.
|
|
@@ -110,7 +113,7 @@ differs from the model you're running as, say so before implementing — the hum
|
|
|
110
113
|
run `plumbbob handoff` again and relay its boundary block — with the step gone from
|
|
111
114
|
in-flight it renders "step N checkpointed" and points at the next undone step, carrying
|
|
112
115
|
that step's `- model:` recommendation (the plan's smallest-model-that-fits call) so the
|
|
113
|
-
human knows which `/model` to select before
|
|
116
|
+
human knows which `/model` to select before running `/plumbbob:build` again. It is what
|
|
114
117
|
carries the plan's suggestion across a fresh context window, which inherits the session
|
|
115
118
|
model, not the plan's. No `- model:` line means any model will do. Guidance, never a
|
|
116
119
|
gate.
|
|
@@ -131,10 +134,10 @@ harness *is* bound, this is what each affected step gains, in lifecycle order.
|
|
|
131
134
|
`plumbbob agent run --step <n> --mode build` and let that agent author the step's code
|
|
132
135
|
instead of writing it yourself; its envelope reports what it did. You still own the verify
|
|
133
136
|
tick — the diff is reviewed the same way whoever wrote it.
|
|
134
|
-
- **A manifest's `when` prose is your cue to
|
|
137
|
+
- **A manifest's `when` prose is your cue to run an agent mid-build (step 4).** The three
|
|
135
138
|
slots are the only *declarative* lifecycle points; there is no config for "a salient
|
|
136
139
|
moment in the middle." That is judgment, and you are the frontier model in the room: when
|
|
137
|
-
the work reaches the situation a bound agent's `when` (or a step `note`) describes,
|
|
140
|
+
the work reaches the situation a bound agent's `when` (or a step `note`) describes, run
|
|
138
141
|
`plumbbob agent run <name> --step <n>` yourself. Prose is the orchestration language; you
|
|
139
142
|
are the workflow engine.
|
|
140
143
|
- **Route a non-`done` envelope by its status (step 4).** An agent that returns `blocked`
|
|
@@ -146,8 +149,8 @@ harness *is* bound, this is what each affected step gains, in lifecycle order.
|
|
|
146
149
|
- **`after` — advisory input to the verify tick (step 5).** After `plumbbob check`, run any
|
|
147
150
|
bound `after`-agents (`plumbbob agent run --step <n> --mode after`) and fold their
|
|
148
151
|
envelopes into the self-review as **advisory input** — they inform, they never gate
|
|
149
|
-
(checkride gates, the human is the clock; an `after`-agent that could fail a step
|
|
150
|
-
lock in
|
|
152
|
+
(checkride gates, the human is the clock; an `after`-agent that could fail a step would
|
|
153
|
+
be the old lock back in another form).
|
|
151
154
|
|
|
152
155
|
## `--auto` — let the agent be the clock (opt-in)
|
|
153
156
|
|
|
@@ -220,8 +223,9 @@ just the one more entry already in the halt list above.
|
|
|
220
223
|
Never route around it with a raw `git commit`. An explicit `/plumbbob:build --auto` or a typed
|
|
221
224
|
step range in the human's own prompt are the only self-approvals — **never write `auto`
|
|
222
225
|
into a settings file yourself to unlock a checkpoint. A grant you mint is no grant (the
|
|
223
|
-
latch ignores it
|
|
226
|
+
latch ignores it — D67 (auto-not-a-grant)); ask the human to type
|
|
227
|
+
`/plumbbob:build --auto` again instead.**
|
|
224
228
|
- **Close with the next model.** When a step lands, run `plumbbob handoff` and relay its
|
|
225
229
|
block — it cites the completed step and the next undone step, and names that next step's
|
|
226
230
|
`- model:` recommendation if it has one, which is what a fresh context window needs to
|
|
227
|
-
pick the right `/model` before
|
|
231
|
+
pick the right `/model` before the next run. Guidance, never a gate.
|
package/skills/finish/SKILL.md
CHANGED
|
@@ -23,7 +23,9 @@ record.
|
|
|
23
23
|
wrote a dated line for every step as it landed. **Read it as the spine; do not
|
|
24
24
|
re-narrate it.** The report adds only what the log does not already carry:
|
|
25
25
|
- **What shipped** — summarize from the `## Log` timeline; don't rebuild it step by step.
|
|
26
|
-
- **Decisions and why** — the settled calls that shaped the build (the *why* behind
|
|
26
|
+
- **Decisions and why** — the settled calls that shaped the build (the *why* behind
|
|
27
|
+
the log). Copy each one's `D# (slug)` from `intent.md` — never a bare `D#` — so
|
|
28
|
+
the report reads without flipping back to the intent.
|
|
27
29
|
- **Parked & harvested** — what was captured and how each was classified.
|
|
28
30
|
- **Final status** — done or partial, and what is left.
|
|
29
31
|
- **Deferred tangents** — the harvested items that become future work.
|
package/skills/harvest/SKILL.md
CHANGED
|
@@ -42,6 +42,7 @@ one line of reasoning, then **wait for the human to confirm or override**. Write
|
|
|
42
42
|
- Record each confirmed class in `build-log.md`'s `## Harvest` section.
|
|
43
43
|
- **Flip the harvested item** from `- [ ]` to `- [x]` in the Park list, so `/plumbbob:status`
|
|
44
44
|
stops counting it as open.
|
|
45
|
-
- A confirmed **blocker** also folds its decision into `intent.md
|
|
45
|
+
- A confirmed **blocker** also folds its decision into `intent.md` — slugged at birth
|
|
46
|
+
like any Decision (`D5 (retry-cap): <the call> — *because* <why>`), never a bare `D5`.
|
|
46
47
|
- Never reclassify or resolve an item the human hasn't confirmed, and default every
|
|
47
48
|
uncertain item to **tangent**, never to blocker.
|
package/skills/plan/SKILL.md
CHANGED
|
@@ -84,23 +84,24 @@ an agent can follow with `/plumbbob:build`. The argument only seeds how you get
|
|
|
84
84
|
sharpened just-in-time when you reach them with `/plumbbob:step`. Keep each small enough to
|
|
85
85
|
verify in one review pass.
|
|
86
86
|
|
|
87
|
-
**The title *is* the commit subject — author it as one**
|
|
87
|
+
**The title *is* the commit subject — author it as one**
|
|
88
|
+
([D68 (conventional-subjects)](../../docs/decisions.md#d68)): write each
|
|
88
89
|
`<title>` as a plain, single-line Conventional-Commit subject,
|
|
89
90
|
`type(scope): description`, and it lands in `git log` verbatim (its breaking `!`
|
|
90
91
|
honored) — this is how each step lands a *real* `feat`/`fix`/`chore` in the history.
|
|
91
92
|
Keep load-bearing detail — file paths, module names — in `seam` and `done-when`; it is
|
|
92
|
-
**never jammed into the title
|
|
93
|
+
**never jammed into the title**, which has to read as plain English and as a clean
|
|
93
94
|
subject at once. Aim for **≤72 characters** (GitHub's subject convention) — soft
|
|
94
|
-
guidance you eyeball at plan time, no lint, no gate
|
|
95
|
+
guidance you eyeball at plan time, no lint, no gate.
|
|
95
96
|
|
|
96
|
-
**Set the build's default scope, then let steps override it
|
|
97
|
+
**Set the build's default scope, then let steps override it**: fill the
|
|
97
98
|
`**Scope:**` header once with a short feature-level name — the catch-all every step
|
|
98
99
|
inherits — and give a step its own `(scope)` when it touches a distinct code area
|
|
99
100
|
(`plan`, `commitmsg`, `docs`). A step's `(scope)` names the *code area*; the header
|
|
100
101
|
names the *feature*, so scopes stay consistent and greppable across builds. Scope
|
|
101
102
|
resolves title-scope → `**Scope:**` default → build slug → bare, and type resolves
|
|
102
103
|
title-type → `feat`, so a scopeless plain title still yields a clean
|
|
103
|
-
`feat(<slug>): <title>` unchanged
|
|
104
|
+
`feat(<slug>): <title>` unchanged.
|
|
104
105
|
|
|
105
106
|
**Recommend a model per step where the signal is clear** *(optional)*: the
|
|
106
107
|
`- model:` sub-line names the **smallest model that can carry the step**, with the
|
|
@@ -129,7 +130,7 @@ an agent can follow with `/plumbbob:build`. The argument only seeds how you get
|
|
|
129
130
|
|
|
130
131
|
Keep it **bindings + prose only, never a conditional**: the file says *which*
|
|
131
132
|
agent, not *when* — the host model reads each manifest's `when` prose and a step's
|
|
132
|
-
`note` and decides when to
|
|
133
|
+
`note` and decides when to run one mid-build. Skip the file entirely when no step
|
|
133
134
|
uses an agent — the loop runs identically without it. The plan commit picks it
|
|
134
135
|
up automatically (it lives in the build folder).
|
|
135
136
|
6. **Commit the plan.** Once the human approves the frame and steps, run
|
|
@@ -143,7 +144,7 @@ an agent can follow with `/plumbbob:build`. The argument only seeds how you get
|
|
|
143
144
|
- **The plan commit is latched too.** Once the turn ledger exists, `checkpoint
|
|
144
145
|
--plan` refuses to land in the same turn `start` stamped it: present the plan,
|
|
145
146
|
**end the turn**, and the human's approving message is the tick that lets it
|
|
146
|
-
commit on
|
|
147
|
+
commit on the next run — the refusal *is* the plan pause. Never route around it with a
|
|
147
148
|
raw `git commit`. (One documented seam: the very first plan of a brand-new
|
|
148
149
|
session runs `start` *before* the turn hook has ever ticked, so that single
|
|
149
150
|
commit predates the ledger and stays guidance-governed — it lands without a
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: recover
|
|
3
|
+
description: Human-triggered driver for `plumbbob recover` — reconcile the control plane when the session looks wrong: a cursor pointing at a build that is gone, a step marked in flight that the plan no longer has, leftovers from an interrupted spike. Reports by default; `--fix` repairs the stale files it can.
|
|
4
|
+
argument-hint: "[--fix]"
|
|
5
|
+
disable-model-invocation: true
|
|
6
|
+
model: haiku
|
|
7
|
+
allowed-tools: Bash(plumbbob status:*), Bash(plumbbob recover:*)
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# PlumbBob — reconcile the control plane (driver)
|
|
11
|
+
|
|
12
|
+
Current session state (injected when this skill runs): !`plumbbob status 2>/dev/null || echo "plumbbob CLI not on PATH in this session. Marketplace install: confirm the plugin is enabled in /plugin, then /reload-plugins. Skills-dir/global install: npm i -g plumbbob && plumbbob init."`
|
|
13
|
+
|
|
14
|
+
This is a **driver skill** — a chat-side trigger for the mechanical `plumbbob recover` verb, so the whole workflow runs from the agent window instead of a terminal. It is `disable-model-invocation: true`: only the human fires it. It carries **no Edit and no Write tool** — its only action is to shell the verb and report the verb's output verbatim, including any refusal. The CLI is the source of truth: never retry a refused transition, and never edit a file to work around one.
|
|
15
|
+
|
|
16
|
+
Reach for it when the dashboard and reality disagree: `status` shows a build you thought you finished, or an empty plan for a build you know you wrote, or a step in flight you have no memory of starting. Those are the shapes a crashed session, a lost context window, or a mid-step build switch leaves behind. `/plumbbob:doctor` answers "is plumbbob installed correctly"; this answers "is this session's own state telling the truth".
|
|
17
|
+
|
|
18
|
+
## What it does
|
|
19
|
+
|
|
20
|
+
1. Run `plumbbob recover` via Bash. It reads the control plane — the active-build cursor, the step and spike markers, the latch's stamp, the agent handoff ledger, and any leftover spike worktrees — and prints one line per check.
|
|
21
|
+
2. Report that output verbatim, `✓` and `✗` lines alike. Every problem carries a `→` line naming the fix; relay those as written rather than paraphrasing them into your own advice.
|
|
22
|
+
3. **Only if the human asks for the repair**, run `plumbbob recover --fix`. It clears stale untracked control files and re-points a cursor when exactly one build survives. It never touches intent.md, the build log, the checkpoints ledger, a report, or git history — and it never lands or advances a step.
|
|
23
|
+
|
|
24
|
+
## What it will not do for you
|
|
25
|
+
|
|
26
|
+
- **Spike leftovers are reported, never removed.** Those worktrees sit outside the repo and may hold the only copy of what a spike learned, so the verb prints the exact `git worktree remove` / `git branch -D` commands and stops. Relay them; do not run them yourself.
|
|
27
|
+
- **A contradictory phase is yours to settle.** A spike and a step both marked in flight, or a step number the plan no longer contains, need a decision about which one is real — `--fix` deliberately leaves them alone.
|
|
28
|
+
- **It is not a rewind.** Recovering reconciles bookkeeping; it never restores lost work. Discarding a half-done step is `/plumbbob:revert`, and that is a different, destructive move the human asks for by name.
|
package/skills/refine/SKILL.md
CHANGED
|
@@ -44,10 +44,11 @@ is fine — refining is always available.
|
|
|
44
44
|
by what you built, a Constraint changed, a Step no longer matches the seam, or a
|
|
45
45
|
**step's title no longer describes what the diff actually does** — propose the edits
|
|
46
46
|
that bring `intent.md` back in line with the truth. A step title *is* its checkpoint
|
|
47
|
-
commit subject (
|
|
48
|
-
single-line `type(scope): description` subject, with
|
|
49
|
-
module names) in `seam` and `done-when`,
|
|
50
|
-
checkpoint body pass then reconciles and lands
|
|
47
|
+
commit subject — D68 (conventional-subjects) — so bringing a drifted one back in line
|
|
48
|
+
means keeping it a plain, single-line `type(scope): description` subject, with
|
|
49
|
+
load-bearing detail (file paths, module names) in `seam` and `done-when`,
|
|
50
|
+
**never jammed into the title** — the checkpoint body pass then reconciles and lands
|
|
51
|
+
that subject at the verify pause.
|
|
51
52
|
Show the before/after for each, and **write only what the human approves**.
|
|
52
53
|
|
|
53
54
|
## The hard contracts
|
package/skills/spike/SKILL.md
CHANGED
|
@@ -19,7 +19,7 @@ This is a **driver skill** — a chat-side trigger for the mechanical `plumbbob
|
|
|
19
19
|
2. Run `plumbbob spike "<slug>"`, `plumbbob spike report "<slug>"`, or `plumbbob spike done` via Bash.
|
|
20
20
|
3. Report the verb's output verbatim — the worktree it created or removed, the spike report it scaffolded, or any refusal. When the verb names a `spike-NN-<slug>.md` report, point the human at it; when `spike done` nudges that a verdict is unrecorded, relay that nudge verbatim.
|
|
21
21
|
|
|
22
|
-
## The spike report (
|
|
22
|
+
## The spike report — D70 (spike-reports)
|
|
23
23
|
|
|
24
24
|
Every spike leaves a durable `spike-NN-<slug>.md` in the build folder, beside `intent.md`/`report.md`, so the fork's verdict rides the branch into the PR instead of evaporating. The CLI scaffolds it from a template and numbers it — you never create or number the file:
|
|
25
25
|
|
package/skills/step/SKILL.md
CHANGED
|
@@ -16,7 +16,7 @@ build has actually taught you, right before you `/plumbbob:build` it. (Framing t
|
|
|
16
16
|
is the separate `/plumbbob:plan` move.) It can also add or re-cut a step when scope genuinely
|
|
17
17
|
grew — but its everyday job is to sharpen, not to invent.
|
|
18
18
|
|
|
19
|
-
## Two ways to
|
|
19
|
+
## Two ways to run it
|
|
20
20
|
|
|
21
21
|
- **`/plumbbob:step` (no input) → automatic sharpen.** Re-examine the next undone step
|
|
22
22
|
against the completed code, the Decisions, the Constraints, and the build-log, then
|
|
@@ -43,11 +43,11 @@ grew — but its everyday job is to sharpen, not to invent.
|
|
|
43
43
|
sharpened `<title>` a plain, single-line Conventional-Commit subject,
|
|
44
44
|
`type(scope): description` — it lands in `git log` verbatim, so as the step tightens
|
|
45
45
|
keep load-bearing detail (file paths, module names) in `seam` and `done-when`,
|
|
46
|
-
**never jammed into the title
|
|
46
|
+
**never jammed into the title**. A sharpened step carries its own `(scope)`
|
|
47
47
|
when it touches a distinct code area — one that **overrides the build-default**
|
|
48
48
|
`**Scope:**` header; drop the scope and it falls back to that default → build slug →
|
|
49
|
-
bare, and the type to `feat` ([D68](../../docs/decisions.md#d68)
|
|
50
|
-
≤72 chars, no gate
|
|
49
|
+
bare, and the type to `feat` ([D68 (conventional-subjects)](../../docs/decisions.md#d68)). Aim for a soft
|
|
50
|
+
≤72 chars, no gate. Revise the existing step in place; only append when you are
|
|
51
51
|
genuinely adding an increment.
|
|
52
52
|
4. **Revise the step's harness bindings if they drifted too** *(optional)*. If the
|
|
53
53
|
build carries a `harness.json` (beside `intent.md`) and the reality that moved the
|
package/skills/verify/SKILL.md
CHANGED
|
@@ -11,7 +11,8 @@ Current session state (injected when this skill runs): !`plumbbob status 2>/dev/
|
|
|
11
11
|
|
|
12
12
|
This is the **tick** — the one beat where the human is the clock. Whatever produced
|
|
13
13
|
the current diff — `/plumbbob:build`, your own hands, a vibe session, another harness —
|
|
14
|
-
this skill verifies it the same way: **it reads the diff, not the author
|
|
14
|
+
this skill verifies it the same way: **it reads the diff, not the author** — D3
|
|
15
|
+
(author-blind-executor).
|
|
15
16
|
|
|
16
17
|
## What this skill does, in order
|
|
17
18
|
|
|
@@ -27,7 +28,7 @@ this skill verifies it the same way: **it reads the diff, not the author**.
|
|
|
27
28
|
binds agents to this step's `after` slot, run `plumbbob agent run --step <n> --mode
|
|
28
29
|
after`. Their envelopes are **advisory input to the self-review, never a gate** —
|
|
29
30
|
`plumbbob check` already gated in step 1, and an `after`-agent that could fail a step
|
|
30
|
-
|
|
31
|
+
would be the old lock back in another form. Fold a `done` envelope's
|
|
31
32
|
`summary`/`body` into the review below; route a non-`done` one by its status: a
|
|
32
33
|
`blocked` agent couldn't finish — surface its `notes`, let the human unblock, re-run;
|
|
33
34
|
a `drift` agent found the plan no longer matches reality — stop and send the human to
|
|
@@ -39,20 +40,23 @@ this skill verifies it the same way: **it reads the diff, not the author**.
|
|
|
39
40
|
- the **Decisions** — does anything contradict a settled call?
|
|
40
41
|
- the **Constraints** — are any violated?
|
|
41
42
|
- any **`after`-agent findings** from step 2 — advisory, weigh them, don't defer to them.
|
|
42
|
-
Surface every mismatch plainly
|
|
43
|
+
Surface every mismatch plainly, and when you cite a Decision or Constraint, carry its
|
|
44
|
+
slug from `intent.md` — `C1 (no-new-deps)`, never a bare `C1` — so each finding reads
|
|
45
|
+
on its own. You are reviewing, not building — do not fix anything.
|
|
43
46
|
4. **Validate.** State, yes or no, whether the step's done-when is met, with the evidence.
|
|
44
47
|
5. **PAUSE.** Present the check result, the self-review (with any `after`-agent
|
|
45
48
|
findings), and the validation, then
|
|
46
49
|
**stop and wait for the human's explicit approval.** This is the convergence beat;
|
|
47
50
|
the human is the clock. Never checkpoint without it.
|
|
48
|
-
- **Reconcile a drifted subject here, in the open
|
|
49
|
-
checkpoint subject (
|
|
50
|
-
title no longer describes — the body pass may propose a
|
|
51
|
-
**presents** it at this pause for explicit approval: show
|
|
52
|
-
subject`, one line, as part of what the human OKs. This is
|
|
53
|
-
default
|
|
54
|
-
lands untouched. A silent `-m` swap is exactly the
|
|
55
|
-
— so a reconcile is
|
|
51
|
+
- **Reconcile a drifted subject here, in the open.** The planned title *is* the
|
|
52
|
+
checkpoint subject — D68 (conventional-subjects). If the diff drifted from it — the
|
|
53
|
+
step landed something the title no longer describes — the body pass may propose a
|
|
54
|
+
corrected subject, but it **presents** it at this pause for explicit approval: show
|
|
55
|
+
`planned title → proposed subject`, one line, as part of what the human OKs. This is
|
|
56
|
+
the exception, not the default: with **nothing presented**, the deterministic
|
|
57
|
+
title-derived subject lands untouched. A silent `-m` swap is exactly the
|
|
58
|
+
agent-authored subject D68 (conventional-subjects) refuses — so a reconcile is
|
|
59
|
+
*only ever* the visible, approved kind.
|
|
56
60
|
6. **Checkpoint** *(only after approval)*. Run `plumbbob checkpoint`: it makes the WIP
|
|
57
61
|
commit, records the SHA, flips the step to done, appends the step to the build-log's
|
|
58
62
|
`## Log`, and returns to DESIGN. The CLI owns the commit **subject** — a Conventional
|
|
@@ -79,7 +83,7 @@ this skill verifies it the same way: **it reads the diff, not the author**.
|
|
|
79
83
|
step gone from in-flight it renders `step N checkpointed — back at the boundary` and
|
|
80
84
|
points at the **next undone step**, carrying that step's `- model:` recommendation (the
|
|
81
85
|
plan's smallest-model-that-fits call) so the human knows which `/model` to select before
|
|
82
|
-
|
|
86
|
+
running `/plumbbob:build` again. This matters most across a context boundary: a fresh window
|
|
83
87
|
inherits the *session's* model, not the plan's suggestion, so this line is what carries
|
|
84
88
|
the recommendation over. The CLI owns the block, so it can't drift from what `plumbbob
|
|
85
89
|
status` reports; no `- model:` line means any model will do. Guidance, never a gate.
|
|
@@ -91,13 +95,14 @@ land a step in the same turn it was entered** — and that refusal **is** this p
|
|
|
91
95
|
an error to route around. If the checkpoint prints *"checkpoint refused — no human turn
|
|
92
96
|
since this step began,"* you have reached the pause the hard way: present the diff and
|
|
93
97
|
the self-review, **end the turn**, and the human's next message is the tick that lets
|
|
94
|
-
the checkpoint land when you
|
|
98
|
+
the checkpoint land when you run it again. **Never reach for a raw `git commit` to force the
|
|
95
99
|
land** — that forges the very record the latch exists to keep honest, and the
|
|
96
100
|
commit-ask hook asks the human about it anyway. The refusal is a healthy latch doing its
|
|
97
101
|
job on the *record* while the *work* plane stays free; a `/plumbbob:build --auto` or
|
|
98
102
|
a typed step range in the human's own prompt is the only self-approval — **never write
|
|
99
103
|
`auto` into a settings file to unlock the land; the latch ignores a model-minted grant
|
|
100
|
-
(
|
|
104
|
+
— D67 (auto-not-a-grant) — so ask the human to type `/plumbbob:build --auto` again
|
|
105
|
+
instead.**
|
|
101
106
|
|
|
102
107
|
## The hard contracts
|
|
103
108
|
|