plumbbob 0.13.1 → 0.13.2

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.
@@ -2,7 +2,7 @@
2
2
  name: finish
3
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
- allowed-tools: Read, Write, Bash(plumbbob status:*), Bash(plumbbob finish:*)
5
+ allowed-tools: Read, Edit, Write, Bash(plumbbob status:*), Bash(plumbbob harvest:*), Bash(plumbbob order:*), Bash(plumbbob finish:*)
6
6
  ---
7
7
 
8
8
  # PlumbBob: finish the build (the close-out)
@@ -17,7 +17,21 @@ record.
17
17
 
18
18
  ## What this skill does, in order
19
19
 
20
- 1. **Write the report** to the active build's `report.md`
20
+ 1. **Settle a stop card still waiting.** Read `.plumbbob/detail.md`. When it opens on a
21
+ `# Detail · Range <N>` header, the last range's stop card is waiting for its reply, and
22
+ `/plumbbob:finish` typed at it is that reply, the move its Your Call block names
23
+ ([D102 (settle-in-one-reply)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d102)).
24
+ Record it the way `looks good` would before anything else: fold each blocker its
25
+ `## Harvest` section proposes into `intent.md` by the harvest skill's rules (read
26
+ `../harvest/SKILL.md` from this skill's base directory), then run `plumbbob harvest`,
27
+ which writes the range's review into the Log and flips the parks the card settled. A
28
+ finish that skipped it would leave the last range's review out of the Log and its parks
29
+ open in the report. When `plumbbob harvest` refuses with `step 13 joined it after it
30
+ landed`, a blocker went into the range the card reviews: move that step to a range
31
+ still to come, or a bare range of its own, leave the detail file as it is, fold nothing
32
+ again, and run `plumbbob harvest` once more. On any other refusal, report what it names
33
+ and stop before the report. Any other detail file, or none, has nothing waiting.
34
+ 2. **Write the report** to the active build's `report.md`
21
35
  (`.plumbbob/builds/<slug>/report.md`), from `intent.md` + `build-log.md`.
22
36
  The build-log's `## Log` is already the chronological history; `plumbbob checkpoint`
23
37
  wrote a dated line for every step as it landed. **Read it as the spine; do not
@@ -34,7 +48,7 @@ record.
34
48
  `## Stats` (the per-step receipts) itself, so do **not** hand-write either; a report
35
49
  that spells them out collides with the CLI's own tail. This is the "yeah, I did that"
36
50
  artifact. Write it by default; the human may edit it.
37
- 2. **Finish.** Run `plumbbob finish`, which appends the checkpoint SHAs to the
51
+ 3. **Finish.** Run `plumbbob finish`, which appends the checkpoint SHAs to the
38
52
  report and makes the final commit (subject `chore(<scope>): finish`, its body
39
53
  led by a `plumbbob finish` marker plus an optional proportional `--body`), then
40
54
  clears the control state (the in-flight markers, then `STATE` last; one delete
@@ -58,7 +72,7 @@ record.
58
72
  cannot analyze the extra redirect, so it blocks the command or stops to ask instead of
59
73
  letting this skill's allowance cover it. Omit `--body` entirely and the commit carries
60
74
  the `plumbbob finish` marker subject only.
61
- 3. **Point at the next goal.** Relay `plumbbob finish`'s output verbatim, blank lines
75
+ 4. **Point at the next goal.** Relay `plumbbob finish`'s output verbatim, blank lines
62
76
  included: its lead line, which names the branch the tracked folder now rides into the
63
77
  PR, any advisory beneath it, and `**Next Up**: Nothing planned - /plumbbob:plan`. That
64
78
  is the orientation tier's close (the
@@ -1,8 +1,8 @@
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) for every open parked item at once, and once the human settles them in one reply, fold a confirmed blocker into intent and record the rest with plumbbob harvest. A run's stop card carries its own harvest."
4
4
  disable-model-invocation: true
5
- allowed-tools: Read, Edit, Bash(plumbbob status:*), Bash(plumbbob order:*)
5
+ allowed-tools: Read, Edit, Write, Bash(plumbbob status:*), Bash(plumbbob order:*), Bash(plumbbob harvest:*)
6
6
  ---
7
7
 
8
8
  # PlumbBob: harvest the park list
@@ -25,12 +25,19 @@ DESIGN boundary, not mid-step. Read the dashboard injected above:
25
25
 
26
26
  A range's stop is the boundary that matters most. No harvest runs between the steps
27
27
  inside a range, so the parks it piled up wait for the stop where it lands, and a
28
- blocker among them is caught there before the next range builds on it.
28
+ blocker among them is caught there before the next range builds on it. A run's stop card
29
+ carries its harvest
30
+ ([D100 (stop-card)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d100)):
31
+ every open park is on the card with a proposed lean, and the reply that settles the card
32
+ records them, so there is nothing left for this skill to do there. If
33
+ `.plumbbob/detail.md` opens on a `# Detail · Range <N>` header, that card is still waiting:
34
+ **refuse**, since writing this skill's detail file would overwrite the range's review, and
35
+ point the human at the card's own reply (`looks good`, or a change to a lean).
29
36
 
30
37
  ## What this skill does
31
38
 
32
- Walk the **Park list** in `build-log.md` item by item and, for each, **propose exactly
33
- one class**:
39
+ Walk the **Park list** in `build-log.md` and, for every open item, **propose exactly one
40
+ class**, all of them at once:
34
41
 
35
42
  - **blocker**: the plan was wrong or incomplete; can't proceed. Folds into `intent.md`
36
43
  and is handled now.
@@ -39,23 +46,50 @@ one class**:
39
46
 
40
47
  ## The one hard contract
41
48
 
42
- You **propose**; the **human calls it**. For each item, state your proposed class and
43
- one line of reasoning, then **wait for the human to confirm or override**. Write
44
- **only after** per-item confirmation:
49
+ You **propose**; the **human calls it**. Propose a class for every open item at once,
50
+ with one line of reasoning each, and the human settles them all in one reply
51
+ ([D102 (settle-in-one-reply)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d102)):
52
+ one reply per item is what made a harvest a chore, and seeing every proposal at once keeps
53
+ the call on each one theirs. The detail file you write first is the proposal; record
54
+ **only after** that reply confirms them:
45
55
 
46
- - Record each confirmed class in `build-log.md`'s `## Harvest` section.
47
- - **Flip the harvested item** from `- [ ]` to `- [x]` in the Park list, so `/plumbbob:status`
48
- stops counting it as open.
56
+ - Write the proposals into `.plumbbob/detail.md` first, under a `# Detail · Harvest`
57
+ header, one line per open item in a `## Harvest` section:
58
+ `- P6 → tangent: <the reason, one clause>`, the class written `blocker`, `tangent`,
59
+ or `pivot` (for a pivot signal). A park's handle is `P` and its place in the
60
+ Park list, counting the harvested lines too (the count the note sizes as
61
+ `parked 3 of 8 open`), and it is the one name the detail file, the turn, and the
62
+ human's reply all use
63
+ ([D105 (park-handles)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d105)).
64
+ Then list the same proposals in the turn, each with its handle and the park's text, and
65
+ end the turn there.
66
+ - A reply that changes a proposal (`make P7 a tangent`) is the human's call: rewrite
67
+ that line, list the proposals again, and end the turn. A reply that confirms them
68
+ (`looks good`) is what lets you write.
69
+ - On that confirmation, run `plumbbob harvest`
70
+ ([D104 (harvest-records)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d104)).
71
+ It flips each settled item from `- [ ]` to `- [x]` in the Park list, so
72
+ `/plumbbob:status` stops counting it as open, and records each confirmed class under
73
+ `build-log.md`'s `## Harvest` section. Relay its ending whole, the `**Recorded**:` line
74
+ and the Next Up beneath it. It refuses a proposal naming a handle the list lacks (`P9`
75
+ with eight parked) or a class other than blocker, tangent, or pivot; fix the line it
76
+ names and run it again.
49
77
  - A confirmed **blocker** also folds its decision into `intent.md`, slugged at birth
50
78
  like any Decision, anchored the same way
51
79
  (`- <a id="d5"></a>**D5 (retry-cap)**: <the call>, *because* <why>`), never a bare `D5`.
52
80
  A blocker that becomes a new step takes the next free number under `## Steps` and,
53
81
  when it has to land before an existing undone step, its place in the sequence through
54
82
  `plumbbob order 7 8 5` (the `## Build order` line), never by renumbering. When the plan
55
- carries `## Build ranges`, the new step goes into a range too (the one it builds with,
56
- or a bare range of its own when it brings a call the human has to make before it
57
- lands), and a range it breaks is re-cut in the same confirmed edit
83
+ carries `## Build ranges`, the new step goes into a range too: a range still to come
84
+ (the one it builds with), or a bare range of its own when it brings a call the human
85
+ has to make before it lands, and never a range that has landed, since that range's call
86
+ was made and the step would reopen it. A new range takes the next free item number, and
87
+ no item is renumbered, because the stop card's stamp, the detail file's header, and
88
+ `plumbbob harvest` find a landed range by its number. A range the step breaks is re-cut
89
+ in the same confirmed edit
58
90
  ([D92 (build-ranges)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d92));
59
91
  `plumbbob status` afterward carries a `⚠` row for any range still broken.
92
+ - Fold a confirmed blocker into `intent.md` before you run `plumbbob harvest`, so the
93
+ record and the plan agree when it lands.
60
94
  - Never reclassify or resolve an item the human hasn't confirmed, and default every
61
95
  uncertain item to **tangent**, never to blocker.
@@ -12,9 +12,11 @@ Current session state (injected when this skill runs): !`plumbbob status 2>/dev/
12
12
 
13
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
- **complete plan, including all the Steps**, so the happy path afterward is just
16
- `/plumbbob:build` until done. (Revising a single increment later is the separate `/plumbbob:step`
17
- move; do not confuse the two.)
15
+ **complete plan, including all the Steps and the build ranges**, so the happy path
16
+ afterward is `/plumbbob:run` until done: each run lands one range and stops where the plan
17
+ says a human call is due. A plan without ranges is driven with `/plumbbob:build`, a step
18
+ at a time, and `/plumbbob:build` stays the granular move inside any plan. (Revising a
19
+ single increment later is the separate `/plumbbob:step` move; do not confuse the two.)
18
20
 
19
21
  A model note: this skill **inherits the session model**; nothing pins or switches
20
22
  it. Planning is where frontier-class judgment pays for itself, so if the session is
@@ -42,7 +44,8 @@ Look at the argument the human gave and pick the mode yourself:
42
44
  genuinely ambiguous.
43
45
 
44
46
  All three modes converge on the **same artifact**: a complete, standalone `intent.md`
45
- an agent can follow with `/plumbbob:build`. The argument only seeds how you get there.
47
+ an agent can follow with `/plumbbob:run`, or with `/plumbbob:build` when it cuts no ranges.
48
+ The argument only seeds how you get there.
46
49
 
47
50
  ## What this skill does
48
51
 
@@ -120,8 +123,8 @@ an agent can follow with `/plumbbob:build`. The argument only seeds how you get
120
123
  5. **Cut the build ranges.** With the steps written, say where the build stops for a
121
124
  human call, under `## Build ranges`
122
125
  ([D92 (build-ranges)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d92)):
123
- one sentence on how to drive the build, then one numbered item per range, in the
124
- format the parser reads:
126
+ one sentence on how to drive the build, a `/plumbbob:run` per range, then one numbered
127
+ item per range, in the format the parser reads:
125
128
 
126
129
  ```markdown
127
130
  1. `/plumbbob:build 1`, **stop:** at step 1's pause, approve the schema before anything writes to it
@@ -148,16 +151,26 @@ an agent can follow with `/plumbbob:build`. The argument only seeds how you get
148
151
  Name every step in exactly one range, by its plan number. A fresh plan has no build
149
152
  order, so the ranges follow the numbering. Give each range a `- model:` line naming the
150
153
  strongest model any step inside it recommends, written plain the way a step's is,
151
- because that is the `/model` the human picks before typing the command; any other
154
+ because that is the `/model` the human picks before typing the run; any other
152
155
  sub-line (a `- note:` on what to watch for) is the reader's, and the CLI leaves it
153
156
  alone. Replace the template's placeholder item rather than writing beside it: an item
154
157
  still holding its `<...>` fill-ins reads as no range at all.
155
158
 
156
159
  **Size the ranges to the work.** A plan of two or three steps may carry one range, or
157
160
  none. When every step would be its own bare range, delete the section: the default
158
- loop already stops at each step's pause. A range is advice, never a grant
159
- ([D67 (auto-not-a-grant)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d67)):
160
- the card names the range to type beneath Next Up, and the human still types it.
161
+ loop already stops at each step's pause, and `/plumbbob:build` drives a plan without
162
+ ranges a step at a time.
163
+
164
+ **The card names the run, not the item.** The item's command is the range's
165
+ definition: the form the parser reads, and the kind of stop it makes. The card names
166
+ `/plumbbob:run` beneath Next Up for the range holding the next step, with the steps it
167
+ will land beside it, and `/plumbbob:run 3` runs range 3 by its item number
168
+ ([D95 (run-verb)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d95)).
169
+ A range grants nothing until the human types the run that names it, and then the turn
170
+ hook mints the grant from the plan as it stands
171
+ ([D96 (plan-names-the-grant)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d96)),
172
+ so a range you cut is never a grant you mint
173
+ ([D67 (auto-not-a-grant)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d67)).
161
174
  6. **Offer harness bindings** *(optional)*. If the build will lean on
162
175
  user-authored agents, author `harness.json` in the build folder (beside `intent.md`)
163
176
  and review it at the **same plan pause**, alongside the steps; bindings are
@@ -195,11 +208,13 @@ an agent can follow with `/plumbbob:build`. The argument only seeds how you get
195
208
  renders the your-call block with the moves that apply before anything is recorded and
196
209
  prints your recommendation last (the decision tier of the
197
210
  [turn anatomy](https://github.com/robmclarty/plumbbob/blob/main/docs/presentation.md)),
198
- so the moves are relayed, never hand-composed. *looks good* marks the plan decided and
199
- starts `/plumbbob:build` at the first undone step; a message that asks (`expand 2`, or
200
- any question) is answered from the detail file or `intent.md` and changes nothing; a
201
- message that directs is what to sharpen, cheap now, before any code. The revert move
202
- vanishes there on its own: nothing has landed to wind back.
211
+ so the moves are relayed, never hand-composed. *looks good* marks the plan decided, and
212
+ its row names the move the human types next: `/plumbbob:run` for the range holding
213
+ Step 1 when the plan declares ranges, `/plumbbob:build` for Step 1 when it does not;
214
+ a message that asks (`expand 2`, or any question) is answered from the detail file or
215
+ `intent.md` and changes nothing; a message that directs is what to sharpen, cheap
216
+ now, before any code. The revert move vanishes there on its own: nothing has landed
217
+ to wind back.
203
218
  - **The plan commit is latched too.** Once the turn ledger exists, `checkpoint
204
219
  --plan` refuses to land in the same turn `start` stamped it: present the plan,
205
220
  **end the turn**, and the human's approving message is the tick that lets it
@@ -210,7 +225,8 @@ an agent can follow with `/plumbbob:build`. The argument only seeds how you get
210
225
  refusal.)
211
226
  - **The plan commit prints its own close.** `plumbbob checkpoint --plan` emits the
212
227
  whole boundary ending: `**Plan**: committed (<sha>)`, any advisory, and the pointer at
213
- the step the build starts on. Relay that block whole and run no second command; the
228
+ the step the build starts on, with the run that lands its range named beneath it when
229
+ the plan declares ranges. Relay that block whole and run no second command; the
214
230
  plan-pause card above is the one place `handoff` is still called, because no verb has
215
231
  run yet there.
216
232
  - **Say what the commit publishes.** The close-out line names the tracked folder:
@@ -59,8 +59,11 @@ is fine; refining is always available.
59
59
 
60
60
  **A repair keeps the build ranges true.** When the plan carries `## Build ranges`, a
61
61
  step the repair adds goes into a range (the one it builds with, or a bare range of its
62
- own when it brings a call the human has to make before it lands), and a range the
63
- repair breaks is re-cut in the same before/after
62
+ own when it brings a call the human has to make before it lands), never a range that
63
+ has landed, since that range's call was made and the step would reopen it. A new range
64
+ takes the next free item number, and no item is renumbered, because the stop card's
65
+ stamp, the detail file's header, and `plumbbob harvest` find a landed range by its
66
+ number. A range the repair breaks is re-cut in the same before/after
64
67
  ([D92 (build-ranges)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d92)).
65
68
  Read `plumbbob status` once the edits are written: its ranges block carries a `⚠` row
66
69
  for a range naming a step the plan lacks, a step two ranges name, a step the build order
@@ -0,0 +1,256 @@
1
+ ---
2
+ name: run
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
+ argument-hint: "[range-number]"
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:*)
7
+ ---
8
+
9
+ # PlumbBob: run a range
10
+
11
+ Current session state (injected when this skill runs): !`plumbbob status --run "$ARGUMENTS" 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
+
13
+ A run is one range of the plan being built. `/plumbbob:run` runs what is left of the range
14
+ holding the next undone step in build order, the step in flight counted undone, and
15
+ `/plumbbob:run 3` runs range 3, by the item number the plan's `## Build ranges` gives it
16
+ ([D95 (run-verb)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d95)).
17
+ The plan names the steps, so you never work them out from the chat: the run header above the
18
+ dashboard names them, and the turn hook minted their grant from the plan when the human typed
19
+ the run
20
+ ([D96 (plan-names-the-grant)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d96)).
21
+
22
+ This skill carries only what is the run's own: reading the header, refusing, how a run
23
+ starts, and the stop card it ends on. The loop that builds each step belongs to the build
24
+ skill, and the classes a park settles as belong to the harvest skill; you read both rather
25
+ than recall them
26
+ ([D99 (one-loop)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d99)).
27
+
28
+ ## 1. Read the build skill first
29
+
30
+ Before anything else, read `../build/SKILL.md` from this skill's base directory: the path
31
+ printed above this skill as its base directory, so `<base directory>/../build/SKILL.md`.
32
+ Read the file every run, whole; a copy of it from memory drifts. The parts a run follows are
33
+ its sections **What this skill does, in order** (steps 2 to 5: entering a step, reading the
34
+ plan, implementing within the seam, parking a tangent, and the verify tick with its pause),
35
+ **`--auto`: let the agent be the clock (opt-in)** with its halt list, **A step range (`N-M`,
36
+ or a list like `20,5-9`) is a bounded `--auto`**, **Running bound agents** when the dashboard
37
+ shows a `harness bindings:` block, and **The hard contracts**.
38
+
39
+ Its rules about its own invocation are about `/plumbbob:build` and do not apply here: its
40
+ first step (picking the step from its arguments) and its rule that the invocation outranks
41
+ its injected dashboard. For a run, this skill's invocation and the run header take their
42
+ place, below. Its rule for a clean halt (relay the top step's checkpoint block and end the
43
+ turn) gives way to the stop card here, below.
44
+
45
+ At the stop card you also read `../harvest/SKILL.md` from the same base directory, for its
46
+ three classes, its default, and its rules for folding a confirmed blocker into the plan.
47
+
48
+ ## 2. Read the run header
49
+
50
+ The injected state opens on the run header when the run names a range it can walk:
51
+
52
+ ```text
53
+ run range 3 of 5 · steps 6-9 · ends at step 9's boundary
54
+ stop: review the card on a live boundary before the skills teach it
55
+ grant: steps 6-9
56
+ ```
57
+
58
+ The first line is the range, what is left of it in the order the run builds it, and where
59
+ the run ends: at the boundary after its last step for a range that lands its steps, or at
60
+ the pause of its one step for a bare range. The `stop:` line is the call the plan reserved
61
+ for the end of the range. The `grant:` line is what the turn hook minted at the keystroke,
62
+ and the dashboard beneath marks the run's first step `← requested`.
63
+
64
+ A fourth line, `waiting: range 2 of 5's stop card, recorded before the run`, means the last
65
+ range's stop card is still waiting for its reply. The run typed at it is that reply: settle
66
+ the card first (section 6, below), then walk the run.
67
+
68
+ **The typed number and the grant outrank the header.** The hook read the plan the human
69
+ typed against, so its grant is the run. When the human typed a number and the header names
70
+ another range (the host never passed the number through), or the grant line says
71
+ `unlike the run`, walk exactly the steps the grant names and say so in one line. A
72
+ `range M` grant, from a hook older than step lists, lands the steps up to M.
73
+
74
+ `grant: none` beside a range that lands its steps means the hook minted nothing, because
75
+ the plugin's hook is older than the run or the prompt was not a typed `/plumbbob:run`, so
76
+ no step could land without a pause. Report that in a sentence or two, name the range's own
77
+ command from the plan's `## Build ranges` (`/plumbbob:build 6-9`) as the way to land it by
78
+ hand, and stop without building. **Never write a grant yourself to get past it: a grant you
79
+ mint is no grant, and the latch ignores it
80
+ ([D67 (auto-not-a-grant)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d67)).**
81
+
82
+ ## 3. Refuse what the run cannot walk
83
+
84
+ No run header above the dashboard means the run names nothing it can walk, and the hook
85
+ minted nothing for it
86
+ ([D97 (run-refuses)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d97)).
87
+ The dashboard's `next →` line carries the refusal and the move that unblocks it: a plan
88
+ without ranges (`/plumbbob:refine ranges`, or `/plumbbob:build` for the next step alone), a
89
+ next step no range names or a flagged range (`/plumbbob:refine ranges`), a range that has
90
+ landed or a number the plan lacks (the run the card names instead), nothing left
91
+ (`/plumbbob:finish`), a step in flight outside the range typed (`/plumbbob:verify` or
92
+ `/plumbbob:abandon` it), or a spike open (`plumbbob spike done`). A span or a list of ranges
93
+ (`/plumbbob:run 2-4`) is a form no run defines, and it refuses the same way.
94
+
95
+ Report the refusal in a sentence or two, quoting the move from that line, and stop: enter
96
+ no step, build nothing, and run no checkpoint. `NO ACTIVE SESSION` refuses too, with
97
+ `/plumbbob:plan` as the move.
98
+
99
+ ## 4. Run the range
100
+
101
+ **A step waiting at its pause.** When the dashboard's phase reads `[BUILD]`, a step is in
102
+ flight, and the header's first step is that step. A run typed there is that pause's
103
+ `looks good`: land it the way the build skill lands an approved pause, with
104
+ `plumbbob checkpoint <n> --body <<'BODY'` and a body proportional to the step, and do not
105
+ enter it again with `plumbbob build`. The checkpoint runs the check, so the step lands only
106
+ on green. When the checkpoint refuses on a red check, the step stays at its pause: write the
107
+ detail file, run `plumbbob handoff`, paste its block, and end the turn. When the step is not
108
+ finished (its done-when unmet, and no pause card for it in this conversation), finish
109
+ building it first, then verify and land it the same way. Once it lands, a bare range's run
110
+ ends there: relay the checkpoint's block whole and end the turn. A run whose landing range
111
+ that step completed ends on the stop card, below, even when the paused step was the range's
112
+ last. Otherwise carry on through what is left, below. A halt the human approves with
113
+ `looks good` lands its step the same way, and when that landing completes the run's range
114
+ (its checkpoint block carries the `**Stop**:` part for it), the run ends on the stop card
115
+ too.
116
+
117
+ **A range that lands its steps.** Walk it exactly as the build skill walks a typed range,
118
+ in its section on step ranges: start at the header's first undone step, build each step the
119
+ grant names in build order, check, self-review, and checkpoint it on green, and take the
120
+ next undone step in build order after each landing. A step the grant does not name halts the
121
+ walk before it, since the checkpoint would refuse it. The halt list is the build skill's: a
122
+ red check, a self-review mismatch, a bound agent's `blocked` or `drift`, or a new decision
123
+ ends at that step's pause card. `plumbbob build` names the top step as the top of the range
124
+ you granted when it enters it. Once that step lands, its checkpoint prints the boundary
125
+ with the Stop part (`**Stop**: Range 3 of 5 landed - <its stop>`); relay none of it, and end
126
+ the run on the stop card, below, in the same turn.
127
+
128
+ **A bare range.** `grant: none, as a bare range builds to its pause`: build the range's one
129
+ step to its pause exactly as the build skill's default path does for `/plumbbob:build <n>`:
130
+ enter it, implement it, verify it, write the detail file, run `plumbbob handoff`, paste its
131
+ block, and end the turn. The plan reserved this pause for a call, and the header's `stop:`
132
+ line names it, so your recommendation speaks to that call.
133
+
134
+ ## 5. End on the stop card
135
+
136
+ A run that lands its range ends on the stop card
137
+ ([D100 (stop-card)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d100)):
138
+ the review the plan's stop asked for, with every open park on it and a lean proposed for
139
+ each. The checkpoint that landed the range's last step marked its ending as owing the card,
140
+ and the turn will not close on that boundary
141
+ ([D103 (stop-latched)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d103)).
142
+
143
+ *Write the range's detail file.* Overwrite `.plumbbob/detail.md` in the range's shape:
144
+
145
+ ```markdown
146
+ # Detail · Range <N> · <the stop, as the plan words it>
147
+
148
+ ── recap · range <N> of <M> ──
149
+ done-when met
150
+ decisions honored: D1 (some-slug), D2 (another-slug)
151
+ constraints all honored
152
+
153
+ ## Summary
154
+
155
+ <what the whole range built, in a sentence or a short paragraph>
156
+
157
+ ## 1 <the first highlight across the range: one sentence, one move>
158
+
159
+ <the full story>
160
+
161
+ ## Harvest
162
+
163
+ - P<handle> → <blocker, tangent, or pivot>: <the reason, one clause>
164
+
165
+ ## Recommendation
166
+
167
+ <The move.> <The reason, one or two sentences.>
168
+ ```
169
+
170
+ The header names the range by its item number, and that is how `checkpoint` and
171
+ `plumbbob harvest` tell the file from a step's. The three rows judge the whole range: every
172
+ step's done-when, the decisions any step exercised, and the constraints. The Summary and the
173
+ highlights are the range's, not its last step's, and you draw them from the range's
174
+ checkpoint bodies (`git log` over its commits) and their entries in the build-log's `## Log`,
175
+ never from recall, since a long run can compact its context partway through and lose its
176
+ early steps. A step that landed a hair off comes first among the highlights; five at most.
177
+
178
+ The `## Harvest` section carries one line for every open park in the build-log's
179
+ `## Park list`. A park's handle is `P` and its place in that list, counting the harvested
180
+ lines too, which is the count the note sizes as `parked 3 of 8 open`: the third line ever
181
+ parked is `P3` whether or not the two above it are flipped, and the card, the detail file,
182
+ and the human's reply all name it `P3`
183
+ ([D105 (park-handles)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d105)).
184
+ Propose one class per park by the harvest skill's rules, `tangent` for anything uncertain,
185
+ with the reason in one clause; the card prints it as the park's lean
186
+ (`→ lean: tangent, <the reason>`), so write the class and the reason alone and leave the
187
+ punctuation to handoff. A park you leave out reads `no lean proposed` on the card and stays
188
+ open. The section vanishes when no park is open, and so does the card's Harvested part
189
+ ([D100 (stop-card)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d100)).
190
+ The recommendation speaks to the plan's stop, the header's `stop:` line, and to the
191
+ proposals: the move you would take on both, then why.
192
+
193
+ *Render it and stop.* Run `plumbbob handoff --stop` and paste its output whole, verbatim, at
194
+ top level, trailing blank line included, then end the turn. Write nothing before it or after
195
+ it, and record nothing in this turn: `plumbbob harvest` refuses in the turn the card printed,
196
+ because the human has not read it yet. If the turn is held with a reason saying the stop card
197
+ is still owed, do exactly what the reason says.
198
+
199
+ ## 6. The reply at a stop
200
+
201
+ The card's proposals are settled in one reply
202
+ ([D102 (settle-in-one-reply)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d102)),
203
+ and the Your Call block names the replies. Read the human's message as one of them:
204
+
205
+ - **`looks good`** confirms the review and locks in every lean as proposed, as the line
206
+ beneath the card's Your Call label says. Fold each confirmed blocker into `intent.md` by
207
+ the harvest skill's rules first, then run `plumbbob harvest`, which flips the parks,
208
+ writes the Harvest lines, and writes the range's review beneath a dated line in the Log.
209
+ A blocker that becomes a step goes into a range still to come, or a bare range of its
210
+ own, never into the range this card reviews: that range has landed, its call is the one
211
+ being made, and the step would reopen it. Relay the record's ending whole and end the
212
+ turn. It commits nothing; the record rides the next step's checkpoint.
213
+ - **A change** (`make P7 a tangent`, or a change to the review) is direction. Rewrite the
214
+ detail file's line or section, run `plumbbob handoff --stop`, paste the whole card it
215
+ prints, and end the turn. Nothing is recorded until `looks good`.
216
+ - **A question**, or `expand 2`, is answered from the detail file, the range's commits, or
217
+ the Log, never from recall; then run `plumbbob handoff --stop` and paste what it prints
218
+ beneath your answer, which is the one-line reminder while the stop is unchanged.
219
+ `show the stop`, or a session without the card in front of it, takes
220
+ `plumbbob handoff --stop --full`.
221
+ - **`/plumbbob:run`** typed at the card confirms everything the way `looks good` does, and
222
+ runs the next range. Record first: fold the blockers and run `plumbbob harvest`, then read
223
+ `plumbbob status --run "<the same argument>"` again. When its grant line says
224
+ `unlike the run`, the record re-cut the range the run would walk (a blocker added or moved a
225
+ step in it), and the grant the hook minted before the record no longer covers it: relay
226
+ the record's ending whole and end the turn there, where its note names the re-cut run for
227
+ the human to type
228
+ ([D102 (settle-in-one-reply)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d102)).
229
+ Otherwise relay the record's ending and walk the run from section 4.
230
+ - **`/plumbbob:finish`** at the plan's last range is the finish skill's to settle: it
231
+ records the card the way `looks good` would before it writes the report.
232
+
233
+ `plumbbob harvest` refuses a proposal naming a handle the list lacks (`P9` with eight
234
+ parked) and a class outside the three, and it refuses a detail file no card showed; fix what the refusal names, run
235
+ `plumbbob handoff --stop` again, and end the turn on the card. One refusal takes another
236
+ path: `step 13 joined it after it landed` means a blocker went into the range the card
237
+ reviews. Move that step to a range still to come, or a bare range of its own, leave
238
+ `.plumbbob/detail.md` as it is, fold nothing again, and run `plumbbob harvest` once more in
239
+ the same turn, which records; `plumbbob handoff --stop` would refuse there.
240
+
241
+ ## The hard contracts
242
+
243
+ - **The human types the run.** You never start one: `looks good` lands a step and never
244
+ starts the next range, and nothing chains ranges. A run ends where its range does, on the
245
+ stop card, or at a pause for a bare range or a halt, and the next run waits for the human's
246
+ next prompt.
247
+ - **The plan names the steps.** Walk what the header and the grant name, never a range
248
+ worked out from the chat, and never a step beyond the grant.
249
+ - **The latch holds the record.** A refused checkpoint is a pause, never an error to route
250
+ around: write the detail file, run `plumbbob handoff`, paste its block, and end the turn.
251
+ Never land a step with a raw `git commit`, and never write a grant into a settings or
252
+ control file; ask the human to type the run again instead.
253
+ - **The reply records the stop.** Never run `plumbbob harvest` in the turn the stop card
254
+ printed; the human's reply to the card is what records it, and the classes stay their call.
255
+ - **One loop.** Read `../build/SKILL.md` every run; the build skill is the engine both verbs
256
+ drive, and two copies of it would drift apart.
@@ -34,6 +34,8 @@ annotate it.
34
34
  3. When the plan carries `## Build ranges`, the dashboard lists them beneath the steps:
35
35
  `ranges 2 of 5 done`, `✓` on a landed range and `▸` on the one holding the next step,
36
36
  each undone range's stop on the line beneath it, and a `⚠` row for any range the plan
37
- has outgrown. Its `next →` then names the range's command to type. You relay the block
38
- with the rest; a `⚠` row is `/plumbbob:refine`'s to fix.
37
+ has outgrown. A landed range whose stop card still waits for its reply reads
38
+ `← stop card waiting`, and the `next →` names that card first. Each row keeps the command the plan wrote, the range's definition, while
39
+ the `next →` names the run to type, `/plumbbob:run` with the steps it will land beside
40
+ it. You relay the block with the rest; a `⚠` row is `/plumbbob:refine`'s to fix.
39
41
  4. If it reads `NO ACTIVE SESSION`, tell the human to `/plumbbob:plan` to frame a goal.
@@ -59,12 +59,21 @@ grew, but its everyday job is to sharpen, not to invent.
59
59
  `6-9,14` for a step numbered past the next range), or a bare range of its own when it
60
60
  brings a call the human has to make before it lands
61
61
  ([D92 (build-ranges)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d92)).
62
+ Either way it is a range still to come, never a range that has landed, since that
63
+ range's call was made and the step would reopen it. A new range takes the next free
64
+ item number, and no item is renumbered, because the stop card's stamp, the detail
65
+ file's header, and `plumbbob harvest` find a landed range by its number.
62
66
  A step the build order places between two of a range's steps belongs to that range. A
63
67
  split or re-cut that moves where a call falls moves the stop with it, so re-cut any
64
68
  range the edit breaks, and show the range edit in the same before/after, since it
65
- changes where the human will be asked. Then read `plumbbob status`: its ranges block
66
- carries a `⚠` row for any range still broken, and none once every undone step sits in
67
- exactly one range.
69
+ changes where the human will be asked. The edit lands on the item's command, the
70
+ range's definition, not on the command the card names: the card names `/plumbbob:run`
71
+ for the range, and the turn hook mints a run's grant from the plan as the human types
72
+ the run, so the next run lands the range as you re-cut it, while a run already typed
73
+ keeps the grant it minted
74
+ ([D96 (plan-names-the-grant)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d96)).
75
+ Then read `plumbbob status`: its ranges block carries a `⚠` row for any range still
76
+ broken, and none once every undone step sits in exactly one range.
68
77
  4. **Revise the step's harness bindings if they drifted too** *(optional)*. If the
69
78
  build carries a `harness.json` (beside `intent.md`) and the reality that moved the
70
79
  step also changed which agents it wants, sharpen that step's slot bindings
@@ -58,7 +58,11 @@ this skill verifies it the same way: **it reads the diff, not the author**
58
58
  "here is the pause", for reading the check verdict back in prose, or for a closing
59
59
  courtesy. Each fact appears once, in its part.
60
60
 
61
- *Write the detail file.* Before you call `plumbbob handoff`, overwrite
61
+ *Write the detail file.* If `.plumbbob/detail.md` opens on a `# Detail · Range <N>`
62
+ header and the dashboard above marks that range `← stop card waiting`, that card is still
63
+ waiting: **refuse**, since writing this skill's detail file would overwrite the range's
64
+ review, and point the human at the card's own reply (`looks good`, or a change to a
65
+ lean). Otherwise, before you call `plumbbob handoff`, overwrite
62
66
  `.plumbbob/detail.md`. It is the wire handoff parses, and it is the only path by which
63
67
  the judgment you formed in steps 2 through 4 reaches the turn:
64
68
 
@@ -69,9 +69,11 @@ characters (GitHub's subject convention: soft, no gate).
69
69
  The `(scope)` names the primary code area the step touches (`plan`, `commitmsg`); the
70
70
  build's `**Scope:**` header is the feature-level catch-all a step overrides. Scope
71
71
  resolves title-scope → `**Scope:**` default → build slug → bare, and type resolves
72
- title-type → `feat`. Then drive `/plumbbob:build` until done. Later steps may be
73
- fuzzier than the first; sharpen the next one just-in-time with `/plumbbob:step` (empty input
74
- auto-syncs it), and use `/plumbbob:refine` to repair the whole plan when a blocker rewrites it.)*
72
+ title-type → `feat`. Then drive the build: `/plumbbob:run` a range at a time when the
73
+ plan cuts ranges below, `/plumbbob:build` a step at a time when it does not. Later
74
+ steps may be fuzzier than the first; sharpen the next one just-in-time with
75
+ `/plumbbob:step` (empty input auto-syncs it), and use `/plumbbob:refine` to repair the
76
+ whole plan when a blocker rewrites it.)*
75
77
 
76
78
  1. [ ] feat: <step>, **done when:** <criterion, ideally a test or check result>
77
79
  - seam: `<file>`, `<file>`
@@ -91,15 +93,17 @@ agree. A step keeps its number for life; this line is where the sequence lives.)
91
93
  ## Build ranges
92
94
 
93
95
  *(Where the build stops for a human call, written with the steps: one numbered item per
94
- range, the command the human types, then `**stop:**` and the call that ends it, with an
96
+ range, the command that defines it, then `**stop:**` and the call that ends it, with an
95
97
  optional `- model:` line naming the model to run it on. The command's form says where it
96
98
  stops: a bare `/plumbbob:build 4` builds step 4 to its pause, so its stop is a decision
97
99
  made before the step lands, and a span such as `/plumbbob:build 5-9` lands every step it
98
100
  names, so its stop is a review of what landed. A range ends where a human call is due
99
- and nowhere else, so a plan of two or three steps may need one range or none. The card
100
- names the range to type beneath Next Up and the dashboard lists them, but a range is
101
- advice, never a grant: the human still types the command (plumbbob
102
- [D92 (build-ranges)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d92)).
101
+ and nowhere else, so a plan of two or three steps may need one range or none. The
102
+ dashboard lists the ranges, and the card names `/plumbbob:run` beneath Next Up for the
103
+ range holding the next step: it runs what is left of that range, and `/plumbbob:run 3`
104
+ runs range 3. The item's command stays the range's definition, and a range grants
105
+ nothing until the human types the run that names it (plumbbob
106
+ [D96 (plan-names-the-grant)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d96)).
103
107
  The item below is scaffold while it holds its `<...>` fill-ins; fill it in, or delete
104
108
  the section when the build needs no range.)*
105
109