plumbbob 0.13.6 → 0.13.8

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.
@@ -3,7 +3,7 @@ name: plan
3
3
  description: "Frame a fresh goal and author the whole plan (Frame, Decisions, Constraints, all Steps, and the build ranges) 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
- allowed-tools: Read, Edit, Write, Bash(plumbbob status:*), Bash(plumbbob handoff:*), Bash(plumbbob start:*), Bash(plumbbob checkpoint:*), Bash(plumbbob agent list:*)
6
+ allowed-tools: Read, Edit, Write, Bash(plumbbob status:*), Bash(plumbbob handoff:*), Bash(plumbbob start:*), Bash(plumbbob checkpoint:*), Bash(plumbbob defer:*), Bash(plumbbob agent list:*)
7
7
  ---
8
8
 
9
9
  # PlumbBob: plan a goal (the whole-goal move)
@@ -75,7 +75,29 @@ The argument only seeds how you get there.
75
75
  stake, in plain words, enough to judge it cold), then a `*lean:*` sub-line (your
76
76
  proposed resolution: one answer to react to, not a menu), so the human settles it in
77
77
  one pass without a round-trip. (A tiny, obvious question may stay one bare line; the
78
- sub-lines earn their keep only when a human decision genuinely waits on it.)
78
+ sub-lines earn their keep only when a human decision genuinely waits on it.) The plan
79
+ card tables the open questions, one row each, and a cell shows only the first sentence
80
+ of its line, so write each to stand on that sentence: the opener asks one question in
81
+ one sentence, `*plain:*` opens on why it matters, and `*lean:*` opens on the answer
82
+ ([D118 (questions-table)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d118)).
83
+ The rest of each line is for the cold reader of `intent.md`. The card's
84
+ `yes to all leans` move (or `yes to all leans except Q3: <their answer>`) settles them
85
+ in one reply: on each opener line swap `*resolve by:*` for `*resolved:* <date>, <the
86
+ answer>`, add the Decision the answer settles, and run `plumbbob handoff --plan` again.
87
+ A question the human would rather let the work answer is deferred, not resolved: on
88
+ `defer Q3 until <what settles it>`, run `plumbbob defer Q3 "<what settles it>"`, which
89
+ keeps the question and swaps its `*resolve by:*` for
90
+ `*deferred:* <date>, until <what settles it>` on the opener line, then run
91
+ `plumbbob handoff --plan` again. It stays open, the card lists it on a `Deferred` line
92
+ beneath the table, out of reach of `yes to all leans`, and the Questions row counts it
93
+ apart (`**1** to answer · 2 deferred`); once the work answers it, swap the marker for
94
+ `*resolved:*` as above
95
+ ([D120 (deferred-questions)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d120)).
96
+ A question the human keeps open on purpose, as the running log of something the build
97
+ tunes, is deferred the same way, until the work it logs; left on `*resolve by:*`, the
98
+ card counts it as a call still owed
99
+ ([D123 (defer-records)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d123)).
100
+ Deferring is the human's call, never yours: a lean you are unsure of is still a lean.
79
101
  4. **Author the Steps.** Write the **full build plan** under `## Steps` (each step a
80
102
  small, verifiable increment) in the exact format the parser reads:
81
103
 
@@ -163,7 +185,7 @@ The argument only seeds how you get there.
163
185
 
164
186
  **The card names the run, not the item.** The item's command is the range's
165
187
  definition: the form the parser reads, and the kind of stop it makes. The card names
166
- `/plumbbob:run` in the Range row beneath Next Up for the range holding the next step,
188
+ `/plumbbob:run` on the range line beneath Next Up for the range holding the next step,
167
189
  with the steps it will land beside it, and `/plumbbob:run 3` runs range 3 by its item number
168
190
  ([D95 (run-verb)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d95)).
169
191
  A range grants nothing until the human types the run that names it, and then the turn
@@ -215,7 +237,8 @@ The argument only seeds how you get there.
215
237
  a message that asks (`expand 2`, or any question) is answered from the detail file or
216
238
  `intent.md` and changes nothing; a message that directs is what to sharpen, cheap
217
239
  now, before any code. The revert move vanishes there on its own: nothing has landed
218
- to wind back.
240
+ to wind back. The turn is your framed plan, then that block, and nothing after it:
241
+ anything you would add goes above the `---` rule the block opens on.
219
242
  - **The plan commit is latched too.** Once the turn ledger exists, `checkpoint
220
243
  --plan` refuses to land in the same turn `start` stamped it: present the plan,
221
244
  **end the turn**, and the human's approving message is the tick that lets it
@@ -226,21 +249,25 @@ The argument only seeds how you get there.
226
249
  refusal.)
227
250
  - **The plan commit prints its own close.** `plumbbob checkpoint --plan` emits the
228
251
  whole boundary ending: `**Plan**: committed (<sha>)`, any advisory, and the state
229
- table headed by the pointer at the step the build starts on, its Range row naming the
252
+ table headed by the pointer at the step the build starts on, the range line beneath it naming the
230
253
  run that lands that step's range when the plan declares ranges. Relay that block whole and run no second command; the
231
254
  plan-pause card above is the one place `handoff` is still called, because no verb has
232
255
  run yet there.
233
- - **Say what the commit publishes.** The close-out line names the tracked folder:
234
- `.plumbbob/builds/<slug>/` now rides this branch into the PR, so teammates will
235
- see the plan and build record in review. In the same breath, offer the way out:
236
- a repo that won't track a tool folder can restart with `plumbbob start --local`
237
- (a fully untracked sidecar) before any steps are built.
238
- - **Record-only variant.** When the repo's own `.gitignore` excludes `.plumbbob/`,
239
- the folder can't ride the branch; `start` flags this up front, and the plan
240
- commit lands *record-only*: an empty commit whose message carries the plan
241
- (the `--body` earns its keep here), the files staying untracked. Say that
242
- instead: the rationale is published in `git log`, not the folder, so pass a
243
- fuller `--body` than you otherwise would, since the message is the whole record.
256
+ - **The card says what the commit publishes.** Until the plan commit lands, the plan
257
+ card's `looks good` row names the tracked folder, which rides this branch into the PR
258
+ (teammates will see the plan and build record in review), and a `keep it local` row
259
+ offers the way out. You compose neither note, before the
260
+ card or after it. When the human picks `keep it local`, run `plumbbob start --local`
261
+ on the open session: it excludes `.plumbbob/` in this clone, so the plan and finish
262
+ commits land record-only and the folder never rides the branch. Then run
263
+ `plumbbob handoff --plan` and end on the card, which now says record-only. Once the
264
+ plan has landed, the folder is in a commit and `start --local` refuses.
265
+ - **Record-only variant.** When the repo's own `.gitignore` excludes `.plumbbob/`, or
266
+ the session was kept local, the folder can't ride the branch; `start` flags a
267
+ gitignored repo up front, the card's `looks good` row says record-only, and the plan
268
+ commit lands as an empty commit whose message carries the plan, the files staying
269
+ untracked. The rationale is published in `git log`, not the folder, so pass a fuller
270
+ `--body` than you otherwise would, since the message is the whole record.
244
271
  8. **Offer to stress-test it.** Suggest `/plumbbob:refine` to attack the frame for holes (or
245
272
  to repair the plan as it drifts). Optional, the human's call.
246
273
 
@@ -3,7 +3,7 @@ name: refine
3
3
  description: "Keep intent.md true: attack the plan for holes (append as Open questions) and refine or repair the Frame, Decisions, Constraints, Steps, and build ranges to match reality (`ranges` re-cuts the whole section). Usable at any point; you propose, the human approves."
4
4
  argument-hint: "[focus | ranges]"
5
5
  disable-model-invocation: true
6
- allowed-tools: Read, Edit, Bash(plumbbob status:*), Bash(plumbbob order:*)
6
+ allowed-tools: Read, Edit, Bash(plumbbob status:*), Bash(plumbbob order:*), Bash(plumbbob defer:*)
7
7
  ---
8
8
 
9
9
  # PlumbBob: refine the plan
@@ -38,10 +38,24 @@ is fine; refining is always available.
38
38
  may stay one bare line; the sub-lines earn their keep only when a human decision
39
39
  genuinely waits on it.)
40
40
 
41
- Then walk the human through it in the chat: list every hole you appended, each as
42
- its explanation first and its lean second, and invite per-question answers; the
43
- human can settle any of them right there in one message, no doc-flipping, no extra
44
- round-trip per hole.
41
+ Then show the human what is open: run `plumbbob status --questions` and paste its
42
+ table whole, one row per open question with why it matters and your lean, each cell
43
+ the first sentence of its line, so write each line to stand on that sentence. Then
44
+ invite per-question answers; the human can settle any of them right there in one
45
+ message (`yes to all leans`, or `yes to all leans except Q3: <their answer>`), no
46
+ doc-flipping, no extra round-trip per hole. A resolved question gets
47
+ `*resolved:* <date>, <the answer>` in place of its `*resolve by:*` on the opener line. The human
48
+ can also leave one to the work (`defer Q3 until <what settles it>`): run
49
+ `plumbbob defer Q3 "<what settles it>"`, which keeps the question and swaps its
50
+ `*resolve by:*` for `*deferred:* <date>, until <what settles it>` on the opener line,
51
+ and the table moves it to a `Deferred` line beneath, still open
52
+ ([D120 (deferred-questions)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d120)).
53
+ A question the table still shows that the human has already set aside (parked, settled
54
+ as a tangent, or kept open as a log) is drift: propose deferring it, until what the
55
+ build says it waits on, rather than asking it again
56
+ ([D123 (defer-records)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d123)).
57
+ Never retype the table as a list of your own
58
+ ([D118 (questions-table)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d118)).
45
59
  - **Repair (re-sync to reality).** When the plan has drifted (a Decision was overtaken
46
60
  by what you built, a Constraint changed, a Step no longer matches the seam, or a
47
61
  **step's title no longer describes what the diff actually does**), propose the edits
@@ -3,7 +3,7 @@ name: run
3
3
  description: "Run what is left of the range holding the next step, or of range N: the plan's `## Build ranges` names the steps, the turn hook mints their grant from the plan, and the run walks them the way a typed range is walked, then ends on the stop card, the range's review with every open park proposed, which one reply settles. A bare range builds its one step to its pause. Reads the build skill beside it for the per-step loop."
4
4
  argument-hint: "[range-number]"
5
5
  disable-model-invocation: true
6
- allowed-tools: Read, Edit, Write, Bash(plumbbob status:*), Bash(plumbbob build:*), Bash(plumbbob handoff:*), Bash(plumbbob check:*), Bash(plumbbob checkpoint:*), Bash(plumbbob park:*), Bash(plumbbob agent:*), Bash(plumbbob spike:*), Bash(git diff:*), Bash(plumbbob harvest:*), Bash(plumbbob order:*), Bash(git log:*)
6
+ allowed-tools: Read, Edit, Write, Bash(plumbbob status:*), Bash(plumbbob build:*), Bash(plumbbob handoff:*), Bash(plumbbob check:*), Bash(plumbbob checkpoint:*), Bash(plumbbob park:*), Bash(plumbbob defer:*), Bash(plumbbob agent:*), Bash(plumbbob spike:*), Bash(git diff:*), Bash(plumbbob harvest:*), Bash(plumbbob order:*), Bash(git log:*)
7
7
  ---
8
8
 
9
9
  # PlumbBob: run a range
@@ -122,7 +122,7 @@ walk before it, since the checkpoint would refuse it. The halt list is the build
122
122
  red check, a self-review mismatch, a bound agent's `blocked` or `drift`, or a new decision
123
123
  ends at that step's pause card. `plumbbob build` names the top step as the top of the range
124
124
  you granted when it enters it. Once that step lands, its checkpoint prints the boundary
125
- with the Stop row (`| Stop | Range 3 of 5 landed - <its stop> |`); relay none of it, and end
125
+ with the Stop row (`| Stop | **Range 3** landed - <its stop> |`); relay none of it, and end
126
126
  the run on the stop card, below, in the same turn.
127
127
 
128
128
  **A bare range.** `grant: none, as a bare range builds to its pause`: build the range's one
@@ -207,6 +207,15 @@ it, and record nothing in this turn: `plumbbob harvest` refuses in the turn the
207
207
  because the human has not read it yet. If the turn is held with a reason saying the stop card
208
208
  is still owed, do exactly what the reason says.
209
209
 
210
+ *After a halt the human approved, the card comes short.* When the step that completed the
211
+ range halted at its pause and `looks good` landed it, the human read that step's Summary,
212
+ Readout, and recommendation a moment ago, so `plumbbob handoff --stop` prints only the
213
+ Harvested table, the moves, the state table with its Stop row, and the link
214
+ ([D119 (short-stop-after-a-halt)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d119)).
215
+ Write the range's detail file all the same, in full: the stop's record reads it, and
216
+ `show the stop` prints the card whole from it. Paste the short card exactly as it printed;
217
+ never add back the parts it left out.
218
+
210
219
  ## 6. The reply at a stop
211
220
 
212
221
  The card's proposals are settled in one reply
@@ -214,8 +223,9 @@ The card's proposals are settled in one reply
214
223
  and the Your Call block names the replies. Read the human's message as one of them:
215
224
 
216
225
  - **`looks good`** confirms the review and locks in every lean as proposed, as the line
217
- beneath the card's Your Call label says. Fold each confirmed blocker into `intent.md` by
218
- the harvest skill's rules first, then run `plumbbob harvest`, which flips the parks,
226
+ beneath the card's Your Call label says. Fold each confirmed blocker into `intent.md`, and
227
+ defer each open question a confirmed tangent sets aside, by the harvest skill's rules
228
+ first, then run `plumbbob harvest`, which flips the parks,
219
229
  writes the Harvest lines, and writes the range's review beneath a dated line in the Log.
220
230
  A blocker that becomes a step goes into a range still to come, or a bare range of its
221
231
  own, never into the range this card reviews: that range has landed, its call is the one
@@ -224,20 +234,24 @@ and the Your Call block names the replies. Read the human's message as one of th
224
234
  - **A change** (`make P7 a tangent`, or a change to the review) is direction, and the turn
225
235
  that makes it is your reply
226
236
  ([D110 (reply-after-the-card)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d110)).
227
- Rewrite the detail file's line or section, say in your own words what moved, then run
228
- `plumbbob handoff --stop` and paste the one-line reminder it prints beneath your reply.
237
+ Rewrite the detail file's line or section, run `plumbbob handoff --stop` last among your
238
+ tool calls and keep the one-line reminder it prints, then say in your own words what
239
+ moved and end the turn on that line, with no tool call after your reply
240
+ ([D121 (reply-after-the-tools)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d121)).
229
241
  The card does not come back for a change; nothing is recorded until `looks good`, which
230
242
  records every lean as the detail file then reads.
231
243
  - **A question**, or `expand 2`, is answered from the detail file, the range's commits, or
232
- the Log, never from recall; then run `plumbbob handoff --stop` and paste the one-line
233
- reminder it prints beneath your answer. Only `show the stop`, or any wording of it, takes
234
- `plumbbob handoff --stop --full`, and never to read the card for yourself.
244
+ the Log, never from recall: read what you need and run `plumbbob handoff --stop` first,
245
+ then write the answer, and end the turn on the one-line reminder it printed, with no tool
246
+ call after the answer. Only `show the stop`, or any wording of it, takes
247
+ `plumbbob handoff --stop --full`, which prints the card whole after a short one too, and
248
+ never to read the card for yourself.
235
249
  - **`/plumbbob:run`** typed at the card confirms everything the way `looks good` does, and
236
250
  runs the next range. Record first: fold the blockers and run `plumbbob harvest`, then read
237
251
  `plumbbob status --run "<the same argument>"` again. When its grant line says
238
252
  `unlike the run`, the record re-cut the range the run would walk (a blocker added or moved a
239
253
  step in it), and the grant the hook minted before the record no longer covers it: relay
240
- the record's ending whole and end the turn there, where its Range row names the re-cut run
254
+ the record's ending whole and end the turn there, where the range line beneath its Next Up names the re-cut run
241
255
  for the human to type
242
256
  ([D102 (settle-in-one-reply)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d102)).
243
257
  Otherwise relay the record's ending and walk the run from section 4.
@@ -39,3 +39,10 @@ annotate it.
39
39
  the `next →` names the run to type, `/plumbbob:run` with the steps it will land beside
40
40
  it. You relay the block with the rest; a `⚠` row is `/plumbbob:refine`'s to fix.
41
41
  4. If it reads `NO ACTIVE SESSION`, tell the human to `/plumbbob:plan` to frame a goal.
42
+ 5. If the human asks what is still open, run `plumbbob status --questions` and relay its
43
+ output whole: a table row per question that waits on the human, linked to its entry in
44
+ `intent.md`, with why it matters and the lean, and a `Deferred` line beneath it naming
45
+ the questions left to the work and what settles each
46
+ ([D120 (deferred-questions)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d120)).
47
+ Never list the questions in your own words
48
+ ([D118 (questions-table)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d118)).
@@ -146,7 +146,7 @@ this skill verifies it the same way: **it reads the diff, not the author**
146
146
  one, the write-versus-relay line of
147
147
  [D78 (em-dash-ban)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d78).
148
148
 
149
- *Then answer the reply in your own words.* The card shows once
149
+ *Then answer the reply in your own words, after every tool call.* The card shows once
150
150
  ([D110 (reply-after-the-card)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d110)):
151
151
  every later turn at this pause is your reply, closed by one line. A message that
152
152
  **asks** ("expand 2", "what does that mean?", "why did the seam row flag that?") is an
@@ -154,12 +154,17 @@ this skill verifies it the same way: **it reads the diff, not the author**
154
154
  `## Log` for an older step, never from recall. A message that **directs** is needs-work:
155
155
  make the change, run the check, and say what moved and what the check found; when the
156
156
  change moves what the card said, write the detail file again so the record matches what
157
- lands. Nothing lands until the human says `looks good`. Either way, then run
158
- `plumbbob handoff <n>` and paste its output beneath your reply, whole and verbatim: at a
159
- pause whose card has shown it prints one line,
160
- `**Next Up**: Back to Step <N> of <M> - <title>`, whatever changed since, so your reply
161
- stays on screen. The turn is your reply, then that line, and nothing after it. The CLI
162
- picks the form, never you: paste whichever one it prints, and never retype the card.
157
+ lands. Nothing lands until the human says `looks good`. Either way, every tool call
158
+ comes before your reply and none after it
159
+ ([D121 (reply-after-the-tools)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d121)):
160
+ read, edit, run the check, write the detail file, and run `plumbbob handoff <n>` last
161
+ among them. At a pause whose card has shown it prints one line,
162
+ `**Next Up**: Back to **Step N** on <Model> - <title>`, whatever changed since. Keep
163
+ that line, then write your reply, and end the turn on the line, whole and verbatim. The
164
+ turn is your tool calls, then your reply, then that line, and nothing after it: a
165
+ client that folds text written before a tool call (Zed, through the agent bridge) shows
166
+ the line and hides a reply written above the call. The CLI picks the form, never you:
167
+ paste whichever one it prints, and never retype the card.
163
168
 
164
169
  The card comes back one way: the human asks to see it (`show the pause`, or any wording
165
170
  of it). Then run `plumbbob handoff <n> --full` and paste its output whole, with nothing
@@ -129,7 +129,9 @@ Three lines:
129
129
  · *lean:* the model's proposed resolution: one answer to react to, not a menu
130
130
 
131
131
  The human reads *plain* to understand, then *lean* to approve or redirect: one
132
- pass, no round-trip.
132
+ pass, no round-trip. The plan card tables the open questions a row each, and a cell
133
+ shows only the first sentence of its line, so open the question, *plain*, and *lean*
134
+ each on a sentence that stands alone: the question, why it matters, the answer.
133
135
 
134
136
  When a question resolves, swap *resolve by:* for *resolved:* <date, the call> ON THE
135
137
  OPENER LINE, e.g.
@@ -146,6 +148,22 @@ build reports zero open questions
146
148
  ([D77 (placeholder-uncounted)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d77));
147
149
  fill it in and it counts.
148
150
 
151
+ When the human would rather let the work answer a question, it is deferred, not
152
+ resolved: `plumbbob defer Q4 "<what settles it>"` keeps the question and swaps
153
+ *resolve by:* for *deferred:* <date>, until <what settles it> ON THE OPENER LINE, so
154
+ the opener reads
155
+
156
+ **Q4 (latency-budget)**: What latency budget do we hold?, *deferred:* 2026-10-31, until step 4's latency numbers
157
+
158
+ It stays open and still counts, but the card lists it on a line beneath the table
159
+ rather than in it, so `yes to all leans` leaves it alone. Once the work answers it,
160
+ swap the marker for *resolved:* as above
161
+ ([D120 (deferred-questions)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d120)).
162
+ A question parked, settled as a tangent, or kept open as the running log of something
163
+ the build tunes waits on the work too, so it is deferred the same way; left on
164
+ *resolve by:*, the card counts it as a call still owed
165
+ ([D123 (defer-records)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d123)).
166
+
149
167
  Size to the work: a tiny build's single, obvious question may stay one bare line;
150
168
  the *plain:*/*lean:* pair earns its keep only when a human decision genuinely waits
151
169
  on it.