plumbbob 0.9.5 → 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +89 -87
  3. package/dist/cli-core.js +18 -8
  4. package/dist/cli.js +1 -1
  5. package/dist/lib/agents.js +26 -26
  6. package/dist/lib/buildlog.js +21 -11
  7. package/dist/lib/buildlogsync.js +8 -8
  8. package/dist/lib/check.js +14 -14
  9. package/dist/lib/commitbody.js +72 -0
  10. package/dist/lib/commitmsg.js +7 -7
  11. package/dist/lib/git.js +44 -15
  12. package/dist/lib/intent.js +20 -19
  13. package/dist/lib/latch.js +16 -16
  14. package/dist/lib/orient.js +36 -17
  15. package/dist/lib/reentry.js +3 -3
  16. package/dist/lib/settings.js +16 -16
  17. package/dist/lib/sidecar.js +70 -54
  18. package/dist/lib/templates.js +1 -1
  19. package/dist/verbs/abandon.js +122 -0
  20. package/dist/verbs/agent.js +25 -25
  21. package/dist/verbs/build.js +9 -9
  22. package/dist/verbs/check.js +6 -6
  23. package/dist/verbs/checkpoint.js +48 -47
  24. package/dist/verbs/doctor.js +35 -29
  25. package/dist/verbs/finish.js +27 -40
  26. package/dist/verbs/handoff.js +9 -8
  27. package/dist/verbs/init.js +9 -9
  28. package/dist/verbs/park.js +3 -3
  29. package/dist/verbs/recover.js +12 -12
  30. package/dist/verbs/revert.js +12 -12
  31. package/dist/verbs/spike.js +21 -21
  32. package/dist/verbs/start.js +49 -19
  33. package/dist/verbs/status.js +8 -8
  34. package/dist/verbs/turn.js +16 -16
  35. package/dist/verbs/use.js +4 -4
  36. package/node_modules/checkride/.claude-plugin/plugin.json +1 -1
  37. package/node_modules/checkride/CHANGELOG.md +401 -0
  38. package/node_modules/checkride/README.md +27 -9
  39. package/node_modules/checkride/dist/adapters.d.ts +12 -4
  40. package/node_modules/checkride/dist/adapters.d.ts.map +1 -1
  41. package/node_modules/checkride/dist/adapters.js +21 -1
  42. package/node_modules/checkride/dist/adapters.js.map +1 -1
  43. package/node_modules/checkride/dist/agent-setup/cursor.d.ts +9 -1
  44. package/node_modules/checkride/dist/agent-setup/cursor.d.ts.map +1 -1
  45. package/node_modules/checkride/dist/agent-setup/cursor.js +59 -1
  46. package/node_modules/checkride/dist/agent-setup/cursor.js.map +1 -1
  47. package/node_modules/checkride/dist/agent-setup/harness.d.ts +1 -1
  48. package/node_modules/checkride/dist/agent-setup/harness.d.ts.map +1 -1
  49. package/node_modules/checkride/dist/agent-setup/harness.js +10 -1
  50. package/node_modules/checkride/dist/agent-setup/harness.js.map +1 -1
  51. package/node_modules/checkride/dist/agent-setup/scripts.d.ts +23 -0
  52. package/node_modules/checkride/dist/agent-setup/scripts.d.ts.map +1 -1
  53. package/node_modules/checkride/dist/agent-setup/scripts.js +387 -82
  54. package/node_modules/checkride/dist/agent-setup/scripts.js.map +1 -1
  55. package/node_modules/checkride/dist/baseline/fallow.js +2 -2
  56. package/node_modules/checkride/dist/baseline/fingerprint.d.ts +14 -5
  57. package/node_modules/checkride/dist/baseline/fingerprint.d.ts.map +1 -1
  58. package/node_modules/checkride/dist/baseline/fingerprint.js +58 -5
  59. package/node_modules/checkride/dist/baseline/fingerprint.js.map +1 -1
  60. package/node_modules/checkride/dist/baseline/history.d.ts +98 -0
  61. package/node_modules/checkride/dist/baseline/history.d.ts.map +1 -0
  62. package/node_modules/checkride/dist/baseline/history.js +232 -0
  63. package/node_modules/checkride/dist/baseline/history.js.map +1 -0
  64. package/node_modules/checkride/dist/baseline/index.d.ts +4 -2
  65. package/node_modules/checkride/dist/baseline/index.d.ts.map +1 -1
  66. package/node_modules/checkride/dist/baseline/index.js +2 -1
  67. package/node_modules/checkride/dist/baseline/index.js.map +1 -1
  68. package/node_modules/checkride/dist/baseline/store.d.ts +30 -7
  69. package/node_modules/checkride/dist/baseline/store.d.ts.map +1 -1
  70. package/node_modules/checkride/dist/baseline/store.js +50 -16
  71. package/node_modules/checkride/dist/baseline/store.js.map +1 -1
  72. package/node_modules/checkride/dist/cli.d.ts +5 -1
  73. package/node_modules/checkride/dist/cli.d.ts.map +1 -1
  74. package/node_modules/checkride/dist/cli.js +98 -25
  75. package/node_modules/checkride/dist/cli.js.map +1 -1
  76. package/node_modules/checkride/dist/config.d.ts +33 -4
  77. package/node_modules/checkride/dist/config.d.ts.map +1 -1
  78. package/node_modules/checkride/dist/config.js +21 -6
  79. package/node_modules/checkride/dist/config.js.map +1 -1
  80. package/node_modules/checkride/dist/digest/digest.js +1 -1
  81. package/node_modules/checkride/dist/doctor.d.ts +2 -0
  82. package/node_modules/checkride/dist/doctor.d.ts.map +1 -1
  83. package/node_modules/checkride/dist/doctor.js +39 -1
  84. package/node_modules/checkride/dist/doctor.js.map +1 -1
  85. package/node_modules/checkride/dist/gate.d.ts +49 -4
  86. package/node_modules/checkride/dist/gate.d.ts.map +1 -1
  87. package/node_modules/checkride/dist/gate.js +143 -16
  88. package/node_modules/checkride/dist/gate.js.map +1 -1
  89. package/node_modules/checkride/dist/init.d.ts +8 -1
  90. package/node_modules/checkride/dist/init.d.ts.map +1 -1
  91. package/node_modules/checkride/dist/init.js +68 -7
  92. package/node_modules/checkride/dist/init.js.map +1 -1
  93. package/node_modules/checkride/dist/node-pin.d.ts +1 -1
  94. package/node_modules/checkride/dist/node-pin.js +1 -1
  95. package/node_modules/checkride/dist/orchestrator.d.ts +13 -0
  96. package/node_modules/checkride/dist/orchestrator.d.ts.map +1 -1
  97. package/node_modules/checkride/dist/orchestrator.js +118 -13
  98. package/node_modules/checkride/dist/orchestrator.js.map +1 -1
  99. package/node_modules/checkride/dist/pm/index.d.ts +1 -0
  100. package/node_modules/checkride/dist/pm/index.d.ts.map +1 -1
  101. package/node_modules/checkride/dist/pm/index.js.map +1 -1
  102. package/node_modules/checkride/dist/pm/launch.d.ts +23 -2
  103. package/node_modules/checkride/dist/pm/launch.d.ts.map +1 -1
  104. package/node_modules/checkride/dist/pm/launch.js +16 -0
  105. package/node_modules/checkride/dist/pm/launch.js.map +1 -1
  106. package/node_modules/checkride/dist/pm/translate.js +1 -1
  107. package/node_modules/checkride/dist/pm/translate.js.map +1 -1
  108. package/node_modules/checkride/dist/qa/mutation.d.ts +4 -4
  109. package/node_modules/checkride/dist/qa/mutation.js +4 -4
  110. package/node_modules/checkride/dist/recover.d.ts +48 -0
  111. package/node_modules/checkride/dist/recover.d.ts.map +1 -0
  112. package/node_modules/checkride/dist/recover.js +220 -0
  113. package/node_modules/checkride/dist/recover.js.map +1 -0
  114. package/node_modules/checkride/dist/smoke.d.ts +1 -1
  115. package/node_modules/checkride/dist/smoke.js +1 -1
  116. package/node_modules/checkride/dist/snippets.d.ts +1 -1
  117. package/node_modules/checkride/package.json +3 -2
  118. package/node_modules/checkride/schema/checkride.config.schema.json +9 -1
  119. package/node_modules/checkride/skills/check/SKILL.md +9 -1
  120. package/node_modules/checkride/templates/shared/styles/Repo/Drift.yml +41 -0
  121. package/node_modules/checkride/templates/shared/styles/Repo/Latin.yml +14 -0
  122. package/node_modules/checkride/templates/shared/styles/Repo/LyHyphen.yml +28 -0
  123. package/node_modules/checkride/templates/shared/styles/Repo/Minted.yml +33 -0
  124. package/node_modules/checkride/templates/shared/styles/Repo/ThereIs.yml +16 -0
  125. package/node_modules/checkride/templates/shared/styles/Repo/Weasel.yml +26 -0
  126. package/node_modules/checkride/templates/shared/vale.ini +34 -0
  127. package/package.json +13 -11
  128. package/skills/abandon/SKILL.md +20 -0
  129. package/skills/build/SKILL.md +69 -64
  130. package/skills/doctor/SKILL.md +11 -11
  131. package/skills/finish/SKILL.md +20 -19
  132. package/skills/harvest/SKILL.md +13 -12
  133. package/skills/park/SKILL.md +10 -10
  134. package/skills/plan/SKILL.md +63 -54
  135. package/skills/recover/SKILL.md +7 -7
  136. package/skills/refine/SKILL.md +18 -16
  137. package/skills/revert/SKILL.md +6 -6
  138. package/skills/spike/SKILL.md +9 -9
  139. package/skills/status/SKILL.md +5 -5
  140. package/skills/step/SKILL.md +17 -12
  141. package/skills/verify/SKILL.md +45 -40
  142. package/templates/build-log.md +7 -7
  143. package/templates/intent.md +49 -39
  144. package/templates/spike-report.md +10 -10
@@ -1,44 +1,44 @@
1
1
  ---
2
2
  name: finish
3
- description: Finish the build — write the report (what shipped, decisions, parked/harvested items, deferred tangents), then make the final commit that closes the session. The build folder rides the branch into the PR — no separate archive. Report by default, no gate.
3
+ description: "Finish the build: write the report (what shipped, decisions, parked/harvested items, deferred tangents), then make the final commit that closes the session. The build folder rides the branch into the PR: no separate archive. Report by default, no gate."
4
4
  disable-model-invocation: true
5
5
  allowed-tools: Read, Write, Bash(plumbbob status:*), Bash(plumbbob finish:*)
6
6
  ---
7
7
 
8
- # PlumbBob — finish the build (the close-out)
8
+ # PlumbBob: finish the build (the close-out)
9
9
 
10
10
  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."`
11
11
 
12
12
  `/plumbbob:finish` ends the build: it captures what happened, then makes the final commit
13
- that closes the session. **Report by default** — no refuse-without-report gate,
13
+ that closes the session. **Report by default**: no refuse-without-report gate,
14
14
  and no separate docs phase. The build folder is tracked: it merges with the
15
- branch and shows up in the PR, so there is nothing to archive — the folder *is* the
15
+ branch and shows up in the PR, so there is nothing to archive; the folder *is* the
16
16
  record.
17
17
 
18
18
  ## What this skill does, in order
19
19
 
20
20
  1. **Write the report** to the active build's `report.md`
21
21
  (`.plumbbob/builds/<slug>/report.md`), from `intent.md` + `build-log.md`.
22
- The build-log's `## Log` is already the chronological history — `plumbbob checkpoint`
22
+ The build-log's `## Log` is already the chronological history; `plumbbob checkpoint`
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
- - **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
27
- the log). Copy each one's `D# (slug)` from `intent.md` — never a bare `D#` — so
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
27
+ the log). Copy each one's `D# (slug)` from `intent.md` (never a bare `D#`) so
28
28
  the report reads without flipping back to the intent.
29
- - **Parked & harvested** — what was captured and how each was classified.
30
- - **Final status** — done or partial, and what is left.
31
- - **Deferred tangents** — the harvested items that become future work.
29
+ - **Parked & harvested**: what was captured and how each was classified.
30
+ - **Final status**: done or partial, and what is left.
31
+ - **Deferred tangents**: the harvested items that become future work.
32
32
  This is the "yeah, I did that" artifact. Write it by default; the human may edit it.
33
33
  2. **Finish.** Run `plumbbob finish`, which appends the checkpoint SHAs to the
34
- report and makes the final commit — subject `chore(<scope>): finish`, its body
35
- led by a `plumbbob finish` marker plus an optional proportional `--body` — then
36
- clears the control state (the in-flight markers, then `STATE` last — one delete
34
+ report and makes the final commit (subject `chore(<scope>): finish`, its body
35
+ led by a `plumbbob finish` marker plus an optional proportional `--body`), then
36
+ clears the control state (the in-flight markers, then `STATE` last; one delete
37
37
  drops both the session sentinel and the active-build cursor it carries). The
38
38
  build folder stays in place, committed, and rides the branch into the PR.
39
39
 
40
40
  `--body` reads the close-out message from **stdin via a single-quoted heredoc
41
- redirect** — the same form the other verbs use:
41
+ redirect**, the same form the other verbs use:
42
42
 
43
43
  ```
44
44
  plumbbob finish --body <<'BODY'
@@ -48,16 +48,17 @@ record.
48
48
 
49
49
  Redirect the heredoc *into* the command (`--body <<'BODY'`). Do **not** pass it as
50
50
  an argument value (`--body "$(cat <<'BODY'…)"`): `--body` ignores an argument and
51
- reads stdin, so that form leaves stdin open with no EOF and the command hangs. Omit
51
+ always reads stdin. Under an agent harness that stdin is a socket, and `--body` now
52
+ refuses rather than blocking on one; the refusal names this exact heredoc form. Omit
52
53
  `--body` entirely and the commit carries the `plumbbob finish` marker subject only.
53
- 3. **Point at the next goal** — `/plumbbob:plan` to frame the next one.
54
+ 3. **Point at the next goal**: `/plumbbob:plan` to frame the next one.
54
55
 
55
56
  ## The hard contracts
56
57
 
57
58
  - **Report by default, never a gate.** Always offer the report; never wall the exit. A
58
- bug fix's report can be three lines — size it to the work.
59
+ bug fix's report can be three lines; size it to the work.
59
60
  - **The log is the history; the report is the synthesis.** `checkpoint` already recorded
60
- what shipped, step by step — finish applies the *unique additions* (the why, the deferred
61
+ what shipped, step by step; finish applies the *unique additions* (the why, the deferred
61
62
  tangents, the final status), it does not rewrite the timeline.
62
63
  - **The folder is the archive, never destroy**. `finish` keeps intent +
63
64
  build-log + report in `builds/<slug>/` and commits them; nothing is copied out and
@@ -1,37 +1,37 @@
1
1
  ---
2
2
  name: harvest
3
- description: Triage the park list at a step boundary — propose one class (blocker/tangent/pivot) per parked item, write only after the human confirms each, record under ## Harvest, and fold a confirmed blocker into intent.
3
+ description: "Triage the park list at a step boundary: propose one class (blocker/tangent/pivot) per parked item, write only after the human confirms each, record under ## Harvest, and fold a confirmed blocker into intent."
4
4
  disable-model-invocation: true
5
5
  allowed-tools: Read, Edit, Bash(plumbbob status:*)
6
6
  ---
7
7
 
8
- # PlumbBob — harvest the park list
8
+ # PlumbBob: harvest the park list
9
9
 
10
10
  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."`
11
11
 
12
12
  `/plumbbob:harvest` is the complement of `/plumbbob:park`: you parked ideas as seeds during a
13
- build; now, at a boundary, you harvest them — decide what each one is.
13
+ build; now, at a boundary, you harvest them: decide what each one is.
14
14
 
15
- ## When to run it — boundary only
15
+ ## When to run it: boundary only
16
16
 
17
17
  Harvest at a **step boundary**: after a step is checkpointed and you are back at the
18
18
  DESIGN boundary, not mid-step. Read the dashboard injected above:
19
19
 
20
- - `NO ACTIVE SESSION` — **refuse**; tell the human to `plumbbob start "<title>"` first.
20
+ - `NO ACTIVE SESSION`: **refuse**; tell the human to `plumbbob start "<title>"` first.
21
21
  - A step in flight (the dashboard reads `[BUILD]`, and `next →` points at finishing the
22
- step) — **refuse** and suggest finishing it with `/plumbbob:verify` before harvesting.
22
+ step): **refuse** and suggest finishing it with `/plumbbob:verify` before harvesting.
23
23
  Chasing parked items mid-step is the disease parking prevents.
24
- - At the boundary (the dashboard reads `[DESIGN]`) — go ahead.
24
+ - At the boundary (the dashboard reads `[DESIGN]`): go ahead.
25
25
 
26
26
  ## What this skill does
27
27
 
28
28
  Walk the **Park list** in `build-log.md` item by item and, for each, **propose exactly
29
29
  one class**:
30
30
 
31
- - **blocker** — the plan was wrong or incomplete; can't proceed. Folds into `intent.md`
31
+ - **blocker**: the plan was wrong or incomplete; can't proceed. Folds into `intent.md`
32
32
  and is handled now.
33
- - **tangent** — a different path, not clearly better. **The default** — defer or kill.
34
- - **pivot signal** — real evidence the whole approach is wrong. Stop and replan.
33
+ - **tangent**: a different path, not clearly better. **The default**: defer or kill.
34
+ - **pivot signal**: real evidence the whole approach is wrong. Stop and replan.
35
35
 
36
36
  ## The one hard contract
37
37
 
@@ -42,7 +42,8 @@ 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` — slugged at birth
46
- like any Decision (`D5 (retry-cap): <the call> — *because* <why>`), never a bare `D5`.
45
+ - A confirmed **blocker** also folds its decision into `intent.md`, slugged at birth
46
+ like any Decision, anchored the same way
47
+ (`- <a id="d5"></a>**D5 (retry-cap)**: <the call>, *because* <why>`), never a bare `D5`.
47
48
  - Never reclassify or resolve an item the human hasn't confirmed, and default every
48
49
  uncertain item to **tangent**, never to blocker.
@@ -1,35 +1,35 @@
1
1
  ---
2
2
  name: park
3
- description: Compose one tidy tagged park line, get the human's OK in-turn, then capture it by shelling `plumbbob park` — never by editing a file. The capture half of the park/harvest loop.
3
+ description: "Compose one tidy tagged park line, get the human's OK in-turn, then capture it by shelling `plumbbob park`, never by editing a file. The capture half of the park/harvest loop."
4
4
  argument-hint: "[idea]"
5
5
  disable-model-invocation: true
6
6
  model: haiku
7
7
  allowed-tools: Bash(plumbbob status:*), Bash(plumbbob park:*)
8
8
  ---
9
9
 
10
- # PlumbBob — park an idea (capture, don't chase)
10
+ # PlumbBob: park an idea (capture, don't chase)
11
11
 
12
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
13
 
14
14
  `/plumbbob:park` is the **capture** half of the loop; `/plumbbob:harvest` is where parked items
15
- get triaged later. Capturing the instant an idea arrives — instead of acting on
16
- it — is the whole point: it protects the step in flight.
15
+ get triaged later. Capturing the instant an idea arrives (instead of acting on
16
+ it) is the whole point: it protects the step in flight.
17
17
 
18
18
  ## Wrong-state refusal
19
19
 
20
20
  Parking needs an **active session** to capture into. Read the dashboard injected above: if
21
21
  it is `NO ACTIVE SESSION`, **refuse** and tell the human to run `plumbbob start
22
- "<title>"` first. Any time the session is live — at the boundary, mid-step, or in a spike —
22
+ "<title>"` first. Any time the session is live (at the boundary, mid-step, or in a spike)
23
23
  is fine; capture is always available, which is the whole point of parking.
24
24
 
25
25
  ## What this skill does
26
26
 
27
27
  Take the idea, problem, or "ooh what if" the human just had and **compose it into one
28
- tidy, tagged line** — short, legible, self-contained, and carrying a **one-clause why**
28
+ tidy, tagged line**: short, legible, self-contained, and carrying a **one-clause why**
29
29
  (what it is *and* why it's worth revisiting), so it still reads cleanly weeks later when
30
30
  harvest triages it cold. Then:
31
31
 
32
- 1. **Show the composed line to the human** and wait for **in-turn approval** — they
32
+ 1. **Show the composed line to the human** and wait for **in-turn approval**: they
33
33
  confirm it as-is or edit the wording.
34
34
  2. **Only after** that approval, capture it by running `plumbbob park "<the
35
35
  approved line>"` via Bash.
@@ -38,8 +38,8 @@ harvest triages it cold. Then:
38
38
 
39
39
  The capture itself is the **dumb CLI**, never an edit. This skill carries **no Edit and
40
40
  no Write tool** on purpose: you may not append to `build-log.md` yourself. Compose, get
41
- approval, then shell `plumbbob park` — that is the only write path. If approval
42
- never comes, capture nothing. (When the human's **own message** states the idea — a
43
- tangent they raise mid-build — that message **is** the approval: capture it directly
41
+ approval, then shell `plumbbob park`; that is the only write path. If approval
42
+ never comes, capture nothing. (When the human's **own message** states the idea, a
43
+ tangent they raise mid-build, that message **is** the approval: capture it directly
44
44
  with `plumbbob park`, don't ask again. Deferring in words without the CLI line captures
45
45
  nothing.)
@@ -1,27 +1,27 @@
1
1
  ---
2
2
  name: plan
3
- description: "Frame a fresh goal and author the whole plan — Frame, Decisions, Constraints, and all Steps — before any code. Three input modes: no arg interviews you; a file path (or @-mention) absorbs a spec; any other text expands your inline intent."
3
+ description: "Frame a fresh goal and author the whole plan (Frame, Decisions, Constraints, and all Steps) before any code. Three input modes: no arg interviews you; a file path (or @-mention) absorbs a spec; any other text expands your inline intent."
4
4
  argument-hint: "[spec-path | intent]"
5
5
  disable-model-invocation: true
6
6
  allowed-tools: Read, Edit, Write, Bash(plumbbob status:*), Bash(plumbbob start:*), Bash(plumbbob checkpoint:*), Bash(plumbbob agent list:*)
7
7
  ---
8
8
 
9
- # PlumbBob — plan a goal (the whole-goal move)
9
+ # PlumbBob: plan a goal (the whole-goal move)
10
10
 
11
11
  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."`
12
12
 
13
- `/plumbbob:plan` is the **whole-goal** move — it opens a session and gets the deciding out
13
+ `/plumbbob:plan` is the **whole-goal** move; it opens a session and gets the deciding out
14
14
  of your head and onto `intent.md` *before* any code. By default it authors the
15
15
  **complete plan, including all the Steps**, so the happy path afterward is just
16
16
  `/plumbbob:build` until done. (Revising a single increment later is the separate `/plumbbob:step`
17
17
  move; do not confuse the two.)
18
18
 
19
- A model note: this skill **inherits the session model** — nothing pins or switches
19
+ A model note: this skill **inherits the session model**; nothing pins or switches
20
20
  it. Planning is where frontier-class judgment pays for itself, so if the session is
21
- running a small model, suggest `/model opus` (or better) before framing — the
21
+ running a small model, suggest `/model opus` (or better) before framing: the
22
22
  human's call, never a gate.
23
23
 
24
- ## Three input modes (disambiguated for you — no quotes needed)
24
+ ## Three input modes (disambiguated for you; no quotes needed)
25
25
 
26
26
  Look at the argument the human gave and pick the mode yourself:
27
27
 
@@ -32,10 +32,10 @@ Look at the argument the human gave and pick the mode yourself:
32
32
  the token with the `Read` tool; if Claude Code has already injected the referenced
33
33
  file's contents into your context, treat that as the spec rather than re-fetching.
34
34
  Read the spec and distill it into `intent.md`, **retaining enough detail that
35
- `intent.md` stands on its own** — don't just link to the source. Add a one-line
35
+ `intent.md` stands on its own**; don't just link to the source. Add a one-line
36
36
  provenance (`*Source: <path>*`) and, for anything sizable, a `## Source` appendix
37
- preserving the original text. Any prose wrapped around the reference (e.g. "absorb
38
- @spec.md") is extra intent — fold it in. (If the token isn't a real file, fall to
37
+ preserving the original text. Any prose wrapped around the reference (for example "absorb
38
+ @spec.md") is extra intent; fold it in. (If the token isn't a real file, fall to
39
39
  mode 3.)
40
40
  3. **Any other text → expand the inline intent.** Treat the text as the human's
41
41
  rough plan, expand it into the full `intent.md`, and ask only about what is
@@ -50,53 +50,56 @@ an agent can follow with `/plumbbob:build`. The argument only seeds how you get
50
50
  to create `.plumbbob/` (baseline recorded, session opened). If a session already
51
51
  exists, say so and edit the existing `intent.md` rather than starting over.
52
52
  - **If `start` warns that the gate sees no code checks**, surface that to the
53
- human now — while they're still deciding, not at the first refused
54
- checkpoint — and offer to set the `check` key in `.plumbbob/settings.json`
55
- (e.g. `"check": "npm test"`) before any step is built.
53
+ human now (while they're still deciding, not at the first refused
54
+ checkpoint) and offer to set the `check` key in `.plumbbob/settings.json`
55
+ (for example `"check": "npm test"`) before any step is built.
56
56
  2. **Frame** (`.plumbbob/intent.md`), with the human: the **Problem** in plain words,
57
57
  the **smallest thing** that solves it, what **done looks like**, and what you are
58
- **explicitly NOT doing**. This is the human's convergence — propose wording, but
58
+ **explicitly NOT doing**. This is the human's convergence: propose wording, but
59
59
  the human decides every line.
60
60
  3. **Decisions & Constraints.** Record the settled calls (one line each, with the
61
- *because*) and the hard rules the build must honor. **Slug each at birth** — mint a
62
- two- or three-word slug where the item is born (`D1 (default-waves): …`,
63
- `C1 (no-new-deps): …`) and copy that slug at every reference site, so a later
64
- mention reads `D4 (default-waves)` and stays legible: **never a bare `D4`/`C6`/`Q2`
65
- reference — always carry its gloss**, so a cold reader never has to hunt the number
66
- down. An unresolved hole goes to **Open questions**, never guessed into a Decision —
67
- and it goes in the expanded form the template shows: a slugged opener (the hole as a
68
- question), a `*plain:*` sub-line (what's at stake, in plain words, enough to judge it
69
- cold), then a `*lean:*` sub-line (your proposed resolution — one answer to react to,
70
- not a menu), so the human settles it in one pass without a round-trip. (A tiny,
71
- obvious question may stay one bare line; the sub-lines earn their keep only when a
72
- human decision genuinely waits on it.)
73
- 4. **Author the Steps.** Write the **full build plan** under `## Steps` — each step a
74
- small, verifiable increment in the exact format the parser reads:
61
+ *because*) and the hard rules the build must honor. **Anchor and slug each at birth**:
62
+ mint a two- or three-word slug where the item is born and give it an anchor for
63
+ references to land on (`- <a id="d1"></a>**D1 (default-waves)**: …`,
64
+ `- <a id="c1"></a>**C1 (no-new-deps)**: …`), then cite it everywhere else in the file
65
+ as `[D4 (default-waves)](#d4)`, carrying that slug verbatim: **never a bare
66
+ `D4`/`C6`/`Q2` reference, and never a linkless one**: one link to the definition,
67
+ one glance at the gloss, so a cold reader never has to hunt the number down.
68
+ An unresolved hole goes to **Open questions**, never guessed into a Decision,
69
+ and it goes in the expanded form the template shows: an anchored, slugged opener
70
+ (the hole as a question, `- <a id="q1"></a>**Q1 (default-waves)**: …`, so
71
+ `[Q1 (default-waves)](#q1)` has somewhere to land), a `*plain:*` sub-line (what's at
72
+ stake, in plain words, enough to judge it cold), then a `*lean:*` sub-line (your
73
+ proposed resolution: one answer to react to, not a menu), so the human settles it in
74
+ one pass without a round-trip. (A tiny, obvious question may stay one bare line; the
75
+ sub-lines earn their keep only when a human decision genuinely waits on it.)
76
+ 4. **Author the Steps.** Write the **full build plan** under `## Steps` (each step a
77
+ small, verifiable increment) in the exact format the parser reads:
75
78
 
76
79
  ```markdown
77
- 1. [ ] feat(scope): <title> — **done when:** <criterion, ideally a test or check result>
80
+ 1. [ ] feat(scope): <title>, **done when:** <criterion, ideally a test or check result>
78
81
  - seam: `<file>`, `<file>`
79
- - model: <optional — smallest that can carry it, with the one-phrase why>
82
+ - model: <optional; smallest that can carry it, with the one-phrase why>
80
83
  ```
81
84
 
82
85
  Every step needs a **done-when** `/plumbbob:verify` can check and a **seam** (the exact
83
- paths it touches). Later steps may be fuzzier than the first — that's fine; they get
86
+ paths it touches). Later steps may be fuzzier than the first (that's fine); they get
84
87
  sharpened just-in-time when you reach them with `/plumbbob:step`. Keep each small enough to
85
88
  verify in one review pass.
86
89
 
87
- **The title *is* the commit subject — author it as one**
88
- ([D68 (conventional-subjects)](../../docs/decisions.md#d68)): write each
90
+ **The title *is* the commit subject; author it as one**
91
+ ([D68 (conventional-subjects)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d68)): write each
89
92
  `<title>` as a plain, single-line Conventional-Commit subject,
90
93
  `type(scope): description`, and it lands in `git log` verbatim (its breaking `!`
91
- honored) — this is how each step lands a *real* `feat`/`fix`/`chore` in the history.
92
- Keep load-bearing detail — file paths, module names — in `seam` and `done-when`; it is
94
+ honored); this is how each step lands a *real* `feat`/`fix`/`chore` in the history.
95
+ Keep load-bearing detail (file paths, module names) in `seam` and `done-when`; it is
93
96
  **never jammed into the title**, which has to read as plain English and as a clean
94
- subject at once. Aim for **≤72 characters** (GitHub's subject convention) — soft
97
+ subject at once. Aim for **≤72 characters** (GitHub's subject convention): soft
95
98
  guidance you eyeball at plan time, no lint, no gate.
96
99
 
97
100
  **Set the build's default scope, then let steps override it**: fill the
98
- `**Scope:**` header once with a short feature-level name — the catch-all every step
99
- inherits — and give a step its own `(scope)` when it touches a distinct code area
101
+ `**Scope:**` header once with a short feature-level name (the catch-all every step
102
+ inherits) and give a step its own `(scope)` when it touches a distinct code area
100
103
  (`plan`, `commitmsg`, `docs`). A step's `(scope)` names the *code area*; the header
101
104
  names the *feature*, so scopes stay consistent and greppable across builds. Scope
102
105
  resolves title-scope → `**Scope:**` default → build slug → bare, and type resolves
@@ -105,19 +108,19 @@ an agent can follow with `/plumbbob:build`. The argument only seeds how you get
105
108
 
106
109
  **Recommend a model per step where the signal is clear** *(optional)*: the
107
110
  `- model:` sub-line names the **smallest model that can carry the step**, with the
108
- one-phrase why — the human buys capability only where the step needs it. E.g.
109
- `model: sonnet — mechanical, fully specified by the done-when` for rote edits;
110
- `model: opus — strong-assertion test authoring` where the tests do the thinking;
111
- `model: fable — subtle cross-cutting design` for judgment-heavy or creative work.
112
- It is advisory metadata for the human — `/plumbbob:status` surfaces it before each build —
111
+ one-phrase why; the human buys capability only where the step needs it. E.g.
112
+ `model: sonnet (mechanical, fully specified by the done-when)` for rote edits;
113
+ `model: opus (strong-assertion test authoring)` where the tests do the thinking;
114
+ `model: fable (subtle cross-cutting design)` for judgment-heavy or creative work.
115
+ It is advisory metadata for the human (`/plumbbob:status` surfaces it before each build),
113
116
  never a gate, and nothing switches models automatically. Write it plain (no
114
117
  backticks) and omit it when any model would do.
115
118
  5. **Offer harness bindings** *(optional)*. If the build will lean on
116
119
  user-authored agents, author `harness.json` in the build folder (beside `intent.md`)
117
- and review it at the **same plan pause**, alongside the steps — bindings are
120
+ and review it at the **same plan pause**, alongside the steps; bindings are
118
121
  plan-adjacent configuration, so they converge with the plan. It binds agents to a
119
- step's three lifecycle slots — `before` (context in), `build` (the diff), `after`
120
- (advisory review) — with an optional prose `note`; a `defaults` block binds every
122
+ step's three lifecycle slots, `before` (context in), `build` (the diff), and `after`
123
+ (advisory review), with an optional prose `note`; a `defaults` block binds every
121
124
  step. Run `plumbbob agent list` to see what's resolvable, per step:
122
125
 
123
126
  ```json
@@ -129,31 +132,37 @@ an agent can follow with `/plumbbob:build`. The argument only seeds how you get
129
132
  ```
130
133
 
131
134
  Keep it **bindings + prose only, never a conditional**: the file says *which*
132
- agent, not *when* — the host model reads each manifest's `when` prose and a step's
135
+ agent, not *when*; the host model reads each manifest's `when` prose and a step's
133
136
  `note` and decides when to run one mid-build. Skip the file entirely when no step
134
- uses an agent — the loop runs identically without it. The plan commit picks it
137
+ uses an agent; the loop runs identically without it. The plan commit picks it
135
138
  up automatically (it lives in the build folder).
136
139
  6. **Commit the plan.** Once the human approves the frame and steps, run
137
- `plumbbob checkpoint --plan` to commit the scaffold on its own — subject
140
+ `plumbbob checkpoint --plan` to commit the scaffold on its own: subject
138
141
  `chore(<scope>): plan` (with a `plumbbob plan` body marker), only `.plumbbob/builds/<slug>/`,
139
142
  a `plan <sha>` line in
140
143
  `checkpoints`. This keeps the first step's diff clean, so history reads
141
144
  baseline → plan → steps. Pass a proportional `--body` (the single-quoted stdin
142
145
  heredoc) when the rationale is worth carrying; skip it for a small plan. Do this
143
- only on the human's approval — the plan is their convergence.
146
+ only on the human's approval; the plan is their convergence.
144
147
  - **The plan commit is latched too.** Once the turn ledger exists, `checkpoint
145
148
  --plan` refuses to land in the same turn `start` stamped it: present the plan,
146
149
  **end the turn**, and the human's approving message is the tick that lets it
147
- commit on the next run — the refusal *is* the plan pause. Never route around it with a
150
+ commit on the next run; the refusal *is* the plan pause. Never route around it with a
148
151
  raw `git commit`. (One documented seam: the very first plan of a brand-new
149
152
  session runs `start` *before* the turn hook has ever ticked, so that single
150
- commit predates the ledger and stays guidance-governed — it lands without a
153
+ commit predates the ledger and stays guidance-governed; it lands without a
151
154
  refusal.)
152
155
  - **Say what the commit publishes.** The close-out line names the tracked folder:
153
156
  `.plumbbob/builds/<slug>/` now rides this branch into the PR, so teammates will
154
157
  see the plan and build record in review. In the same breath, offer the way out:
155
158
  a repo that won't track a tool folder can restart with `plumbbob start --local`
156
159
  (a fully untracked sidecar) before any steps are built.
160
+ - **Record-only variant.** When the repo's own `.gitignore` excludes `.plumbbob/`,
161
+ the folder can't ride the branch; `start` flags this up front, and the plan
162
+ commit lands *record-only*: an empty commit whose message carries the plan
163
+ (the `--body` earns its keep here), the files staying untracked. Say that
164
+ instead: the rationale is published in `git log`, not the folder, so pass a
165
+ fuller `--body` than you otherwise would, since the message is the whole record.
157
166
  7. **Offer to stress-test it.** Suggest `/plumbbob:refine` to attack the frame for holes (or
158
167
  to repair the plan as it drifts). Optional, the human's call.
159
168
 
@@ -161,17 +170,17 @@ an agent can follow with `/plumbbob:build`. The argument only seeds how you get
161
170
 
162
171
  Make it easy and non-intrusive:
163
172
 
164
- - **Triage size first.** A tiny change earns a 3-line Frame and one Step, fast — never
173
+ - **Triage size first.** A tiny change earns a 3-line Frame and one Step, fast: never
165
174
  ceremony on a one-liner. Scale the questions to the work.
166
175
  - **Propose, don't interrogate.** Offer concrete suggestions the human can **accept as-is
167
- without typing** ("done-when: the 6th request in 60s returns 429 — good?"), while
176
+ without typing** ("done-when: the 6th request in 60s returns 429, good?"), while
168
177
  taking arbitrary detail when they want to give it, including pointers to other files.
169
178
  - **Let them double back.** They will revise as the picture sharpens; that's expected.
170
179
  They can also edit `intent.md` by hand at any time, or call `/plumbbob:refine` to repair it.
171
180
 
172
181
  ## The hard contracts
173
182
 
174
- - **Deciding before code.** `/plumbbob:plan` writes `intent.md` only — never source.
183
+ - **Deciding before code.** `/plumbbob:plan` writes `intent.md` only, never source.
175
184
  - **The human converges.** You surface options and draft wording; the human picks.
176
185
  An unresolved hole is an Open question, not a guessed Decision.
177
186
  - **Stands on its own.** Whatever the input mode, the finished `intent.md` carries
@@ -1,28 +1,28 @@
1
1
  ---
2
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.
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
4
  argument-hint: "[--fix]"
5
5
  disable-model-invocation: true
6
6
  model: haiku
7
7
  allowed-tools: Bash(plumbbob status:*), Bash(plumbbob recover:*)
8
8
  ---
9
9
 
10
- # PlumbBob — reconcile the control plane (driver)
10
+ # PlumbBob: reconcile the control plane (driver)
11
11
 
12
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
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.
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
15
 
16
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
17
 
18
18
  ## What it does
19
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.
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
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.
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
23
 
24
24
  ## What it will not do for you
25
25
 
26
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.
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, and not an exit.** Recovering reconciles bookkeeping; it never restores lost work and never drops a step. Discarding a half-done step is `/plumbbob:revert` (destructive), and dropping one while keeping its work in the tree is `/plumbbob:abandon`; both are different moves the human asks for by name.
@@ -1,16 +1,16 @@
1
1
  ---
2
2
  name: refine
3
- description: Keep intent.md true — attack the plan for holes (append as Open questions) and refine or repair the Frame, Decisions, Constraints, and Steps to match reality. Usable at any point; you propose, the human approves.
3
+ description: "Keep intent.md true: attack the plan for holes (append as Open questions) and refine or repair the Frame, Decisions, Constraints, and Steps to match reality. Usable at any point; you propose, the human approves."
4
4
  argument-hint: "[focus]"
5
5
  disable-model-invocation: true
6
6
  allowed-tools: Read, Edit, Bash(plumbbob status:*)
7
7
  ---
8
8
 
9
- # PlumbBob — refine the plan
9
+ # PlumbBob: refine the plan
10
10
 
11
11
  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."`
12
12
 
13
- `/plumbbob:refine` keeps `intent.md` honest. Use it at **any point** — right after `/plumbbob:plan`
13
+ `/plumbbob:refine` keeps `intent.md` honest. Use it at **any point**: right after `/plumbbob:plan`
14
14
  to stress-test a fresh frame, or mid-build to repair a plan that drifted from what the
15
15
  code is actually doing. It is the document-level complement to `/plumbbob:step` (which only
16
16
  sharpens the *next* step): `/plumbbob:refine` works the *whole* plan.
@@ -20,34 +20,36 @@ sharpens the *next* step): `/plumbbob:refine` works the *whole* plan.
20
20
  This skill refines an existing plan, so it needs one. Read the state injected above: if
21
21
  it is `NO ACTIVE SESSION`, **refuse** in one line and tell the human to run
22
22
  `plumbbob start "<title>"` (or `/plumbbob:plan`) first, and edit nothing. Every active state
23
- is fine — refining is always available.
23
+ is fine; refining is always available.
24
24
 
25
25
  ## Two modes
26
26
 
27
27
  - **Attack (diverge in the problem space).** Hand the **Frame**, **Decisions**, and
28
- **Architecture sketch** a cold, adversarial read and surface holes — ambiguities,
28
+ **Architecture sketch** a cold, adversarial read and surface holes: ambiguities,
29
29
  unhandled edge cases, hidden assumptions, collisions with the existing code. Append
30
- each under `## Open questions` in the expanded form the template shows — an opener
31
- line (the hole as a question, slugged at birth: `- Q2 (some-slug): …`), a `*plain:*`
32
- sub-line (what's at stake in plain words, enough to judge it cold), and a `*lean:*`
33
- sub-line (your proposed resolution — one answer to react to, not a menu). Never
34
- append a hole as a Decision: resolving it is the human's convergence, not yours —
30
+ each under `## Open questions` in the expanded form the template shows: an opener
31
+ line (the hole as a question, anchored and slugged at birth like any Decision,
32
+ `- <a id="q2"></a>**Q2 (some-slug)**: …`, so a `[Q2 (some-slug)](#q2)` reference
33
+ elsewhere in the file lands on it), a `*plain:*` sub-line (what's at stake in plain
34
+ words, enough to judge it cold), and a `*lean:*` sub-line (your proposed resolution:
35
+ one answer to react to, not a menu). Never
36
+ append a hole as a Decision: resolving it is the human's convergence, not yours;
35
37
  the lean proposes; this mode surfaces, it does not decide. (A tiny, obvious question
36
38
  may stay one bare line; the sub-lines earn their keep only when a human decision
37
39
  genuinely waits on it.)
38
40
 
39
41
  Then walk the human through it in the chat: list every hole you appended, each as
40
- its explanation first and its lean second, and invite per-question answers — the
42
+ its explanation first and its lean second, and invite per-question answers; the
41
43
  human can settle any of them right there in one message, no doc-flipping, no extra
42
44
  round-trip per hole.
43
- - **Repair (re-sync to reality).** When the plan has drifted — a Decision was overtaken
45
+ - **Repair (re-sync to reality).** When the plan has drifted (a Decision was overtaken
44
46
  by what you built, a Constraint changed, a Step no longer matches the seam, or a
45
- **step's title no longer describes what the diff actually does** — propose the edits
47
+ **step's title no longer describes what the diff actually does**), propose the edits
46
48
  that bring `intent.md` back in line with the truth. A step title *is* its checkpoint
47
- commit subject — D68 (conventional-subjects) — so bringing a drifted one back in line
49
+ commit subject ([D68 (conventional-subjects)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d68)), so bringing a drifted one back in line
48
50
  means keeping it a plain, single-line `type(scope): description` subject, with
49
51
  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
52
+ **never jammed into the title**; the checkpoint body pass then reconciles and lands
51
53
  that subject at the verify pause.
52
54
  Show the before/after for each, and **write only what the human approves**.
53
55
 
@@ -57,5 +59,5 @@ is fine — refining is always available.
57
59
  approves every change to `intent.md`. Never guess a hole into a Decision.
58
60
  - **Open questions for holes, edits for drift.** New uncertainty goes to
59
61
  `## Open questions`; settled drift gets repaired in place once the human OKs it.
60
- - **Refine the plan, not the code.** `/plumbbob:refine` touches `intent.md` only — turning a
62
+ - **Refine the plan, not the code.** `/plumbbob:refine` touches `intent.md` only; turning a
61
63
  decision into a diff is `/plumbbob:build` or your own hands, never this skill.
@@ -1,20 +1,20 @@
1
1
  ---
2
2
  name: revert
3
- description: Human-triggered driver for `plumbbob revert` — git reset --hard to a checkpoint SHA (discarding the half-done step) and return to the boundary.
3
+ description: "Human-triggered driver for `plumbbob revert`: git reset --hard to a checkpoint SHA (discarding the half-done step) and return to the boundary."
4
4
  argument-hint: "[--to <step>]"
5
5
  disable-model-invocation: true
6
6
  model: haiku
7
7
  allowed-tools: Bash(plumbbob status:*), Bash(plumbbob revert:*)
8
8
  ---
9
9
 
10
- # PlumbBob — revert to a checkpoint (driver)
10
+ # PlumbBob: revert to a checkpoint (driver)
11
11
 
12
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
13
 
14
- This is a **driver skill** — a chat-side trigger for the mechanical `plumbbob revert` 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.
14
+ This is a **driver skill**: a chat-side trigger for the mechanical `plumbbob revert` 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
15
 
16
16
  ## What it does
17
17
 
18
- 1. Read an optional target step from the way you were invoked (e.g. `/plumbbob:revert --to 2` → step `2`). With no target, revert goes to the last done-checkpoint.
19
- 2. Run `plumbbob revert` (or `plumbbob revert --to <n>`) via Bash. This is a `git reset --hard` — it discards the current in-progress step. Run it exactly as the human asked; do not add or drop the `--to` on your own.
20
- 3. Report the verb's output verbatim — which checkpoint it reset to, or any refusal.
18
+ 1. Read an optional target step from the way you were invoked (for example `/plumbbob:revert --to 2` → step `2`). With no target, revert goes to the last done-checkpoint.
19
+ 2. Run `plumbbob revert` (or `plumbbob revert --to <n>`) via Bash. This is a `git reset --hard`; it discards the current in-progress step *and its work*. If the human wants to drop the step but keep the working-tree diff, that is `/plumbbob:abandon`, not revert. Run it exactly as the human asked; do not add or drop the `--to` on your own.
20
+ 3. Report the verb's output verbatim: which checkpoint it reset to, or any refusal.