plumbbob 0.10.3 → 0.11.0

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.
@@ -21,15 +21,19 @@ record.
21
21
  (`.plumbbob/builds/<slug>/report.md`), from `intent.md` + `build-log.md`.
22
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
- 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
24
+ re-narrate it.** The report adds only what the log does not already carry, one `##`
25
+ section apiece, in this order:
26
+ - `## What shipped`: summarize from the `## Log` timeline; don't rebuild it step by step.
27
+ - `## Decisions and why`: the settled calls that shaped the build (the *why* behind
27
28
  the log). Copy each one's `D# (slug)` from `intent.md` (never a bare `D#`) so
28
29
  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.
32
- This is the "yeah, I did that" artifact. Write it by default; the human may edit it.
30
+ - `## Parked & harvested`: what was captured and how each was classified.
31
+ - `## Final status`: done or partial, and what is left.
32
+ - `## Deferred tangents`: the harvested items that become future work.
33
+ Stop there. `plumbbob finish` appends `## Checkpoints` (the baseline and step SHAs) and
34
+ `## Stats` (the per-step receipts) itself, so do **not** hand-write either; a report
35
+ that spells them out collides with the CLI's own tail. This is the "yeah, I did that"
36
+ artifact. Write it by default; the human may edit it.
33
37
  2. **Finish.** Run `plumbbob finish`, which appends the checkpoint SHAs to the
34
38
  report and makes the final commit (subject `chore(<scope>): finish`, its body
35
39
  led by a `plumbbob finish` marker plus an optional proportional `--body`), then
@@ -51,7 +55,14 @@ record.
51
55
  always reads stdin. Under an agent harness that stdin is a socket, and `--body` now
52
56
  refuses rather than blocking on one; the refusal names this exact heredoc form. Omit
53
57
  `--body` entirely and the commit carries the `plumbbob finish` marker subject only.
54
- 3. **Point at the next goal**: `/plumbbob:plan` to frame the next one.
58
+ 3. **Point at the next goal.** Relay `plumbbob finish`'s output verbatim, blank lines
59
+ included: its lead line, which names the branch the tracked folder now rides into the
60
+ PR, any advisory beneath it, and `**Next Up**: Nothing planned - /plumbbob:plan`. That
61
+ is the orientation tier's close (the
62
+ [turn anatomy](https://github.com/robmclarty/plumbbob/blob/main/docs/presentation.md)):
63
+ the lead line, then the forward pointer. `finish` renders that pointer itself rather
64
+ than leaving it to `plumbbob handoff`, because finish has just cleared the session
65
+ handoff would read one from. Relay the block and write nothing after it.
55
66
 
56
67
  ## The hard contracts
57
68
 
@@ -27,12 +27,26 @@ is fine; capture is always available, which is the whole point of parking.
27
27
  Take the idea, problem, or "ooh what if" the human just had and **compose it into one
28
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
- harvest triages it cold. Then:
30
+ harvest triages it cold. **The tag rides the tail, in brackets**, so the line spends its
31
+ one colon on the `parked:` prefix and reads the same in the chat as in the ledger:
32
+
33
+ ```text
34
+ should /password-reset get the same throttle? (tangent)
35
+ ```
36
+
37
+ Then:
31
38
 
32
39
  1. **Show the composed line to the human** and wait for **in-turn approval**: they
33
40
  confirm it as-is or edit the wording.
34
41
  2. **Only after** that approval, capture it by running `plumbbob park "<the
35
42
  approved line>"` via Bash.
43
+ 3. **Relay the block, then get back to the step.** `plumbbob park` prints its whole
44
+ ending: `**Parked**: <text> (tag)`, a blank line, and the pointer back at the step in
45
+ flight (`**Next Up**: Back to Step N`). Relay that output verbatim and run no second
46
+ command. Park is a driver turn (the [turn anatomy](https://github.com/robmclarty/plumbbob/blob/main/docs/presentation.md)):
47
+ the capture plus that one pointer are the whole turn, and both are the CLI's to render,
48
+ never yours to compose from the dashboard. The capture is a one-beat interruption; the
49
+ step keeps its focus.
36
50
 
37
51
  ## The one hard contract
38
52
 
@@ -3,7 +3,7 @@ name: plan
3
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
- allowed-tools: Read, Edit, Write, Bash(plumbbob status:*), 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 agent list:*)
7
7
  ---
8
8
 
9
9
  # PlumbBob: plan a goal (the whole-goal move)
@@ -144,6 +144,14 @@ an agent can follow with `/plumbbob:build`. The argument only seeds how you get
144
144
  baseline → plan → steps. Pass a proportional `--body` (the single-quoted stdin
145
145
  heredoc) when the rationale is worth carrying; skip it for a small plan. Do this
146
146
  only on the human's approval; the plan is their convergence.
147
+ - **The plan pause is a decision turn.** Present the framed plan for the human's call,
148
+ then relay `plumbbob handoff --plan`'s plan-pause card: the CLI renders the your-call
149
+ block with the two moves that apply before anything is recorded (the decision tier of
150
+ the [turn anatomy](https://github.com/robmclarty/plumbbob/blob/main/docs/presentation.md)),
151
+ so the moves are relayed, never hand-composed. *looks good* marks the plan decided and
152
+ starts `/plumbbob:build` at the first undone step; *needs work* sends you back to sharpen
153
+ it, which is cheap now, before any code. The revert move vanishes there on its own:
154
+ nothing has landed to wind back.
147
155
  - **The plan commit is latched too.** Once the turn ledger exists, `checkpoint
148
156
  --plan` refuses to land in the same turn `start` stamped it: present the plan,
149
157
  **end the turn**, and the human's approving message is the tick that lets it
@@ -152,6 +160,11 @@ an agent can follow with `/plumbbob:build`. The argument only seeds how you get
152
160
  session runs `start` *before* the turn hook has ever ticked, so that single
153
161
  commit predates the ledger and stays guidance-governed; it lands without a
154
162
  refusal.)
163
+ - **The plan commit prints its own close.** `plumbbob checkpoint --plan` emits the
164
+ whole boundary ending: `**Plan**: committed (<sha>)`, any advisory, and the pointer at
165
+ the step the build starts on. Relay that block whole and run no second command; the
166
+ plan-pause card above is the one place `handoff` is still called, because no verb has
167
+ run yet there.
155
168
  - **Say what the commit publishes.** The close-out line names the tracked folder:
156
169
  `.plumbbob/builds/<slug>/` now rides this branch into the PR, so teammates will
157
170
  see the plan and build record in review. In the same breath, offer the way out:
@@ -4,14 +4,14 @@ description: "Human-triggered driver for `plumbbob recover`; reconcile the contr
4
4
  argument-hint: "[--fix]"
5
5
  disable-model-invocation: true
6
6
  model: haiku
7
- allowed-tools: Bash(plumbbob status:*), Bash(plumbbob recover:*)
7
+ allowed-tools: Bash(plumbbob status:*), Bash(plumbbob recover:*), Bash(plumbbob handoff:*)
8
8
  ---
9
9
 
10
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**; it shells the verb, relays its output verbatim (including any refusal), and closes on `plumbbob handoff`'s next-up pointer for the turn. 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
 
@@ -20,6 +20,7 @@ Reach for it when the dashboard and reality disagree: `status` shows a build you
20
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
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
+ 4. Close on `plumbbob handoff --driver`'s next-up line (the driver tier of the [turn anatomy](https://github.com/robmclarty/plumbbob/blob/main/docs/presentation.md)): a readout that just told the human their state was off ends on one pointer to reorient them, back at the open step when one survives and forward from the boundary otherwise.
23
24
 
24
25
  ## What it will not do for you
25
26
 
@@ -11,10 +11,11 @@ allowed-tools: Bash(plumbbob status:*), Bash(plumbbob revert:*)
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**; it shells the verb and relays its output verbatim, refusal included. A successful transition prints its whole ending, pointer and all, so one command is the whole turn. 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
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
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
20
  3. Report the verb's output verbatim: which checkpoint it reset to, or any refusal.
21
+ 4. A successful revert prints its own ending (the driver tier of the [turn anatomy](https://github.com/robmclarty/plumbbob/blob/main/docs/presentation.md)): the lead line, a blank line, and the pointer forward from the boundary, since the in-flight step is wound back. Relay that block whole and run no second command. A refusal is not a transition; it carries no pointer, so relay it and stop.
@@ -11,13 +11,14 @@ allowed-tools: Bash(plumbbob status:*), Bash(plumbbob spike:*)
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 spike` 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 spike` 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**; it shells the verb and relays its output verbatim, refusal included. A successful transition prints its whole ending, pointer and all, so one command is the whole turn. 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
18
  1. Read the spike target from the way you were invoked: a slug to open one (for example `/plumbbob:spike redis-cache`), `report <slug>` to scaffold a report without worktrees (`/plumbbob:spike report auth-store`), or the literal `done` to tear the current spike down (`/plumbbob:spike done`). If none is present, ask which and run nothing.
19
19
  2. Run `plumbbob spike "<slug>"`, `plumbbob spike report "<slug>"`, or `plumbbob spike done` via Bash.
20
- 3. Report the verb's output verbatim: the worktree it created or removed, the spike report it scaffolded, or any refusal. When the verb names a `spike-NN-<slug>.md` report, point the human at it; when `spike done` nudges that a verdict is unrecorded, relay that nudge verbatim.
20
+ 3. Report the verb's output verbatim: the worktree it created or removed, the spike report it scaffolded, or any refusal. When the verb names a `spike-NN-<slug>.md` report, point the human at it; when `spike done` nudges that a verdict is unrecorded, that nudge is already inside the block, so relay it there rather than restating it.
21
+ 4. A successful transition prints its own ending (the driver tier of the [turn anatomy](https://github.com/robmclarty/plumbbob/blob/main/docs/presentation.md)): the lead line, any nudge, and the pointer, which names closing the spike while one is live and points forward from the boundary once `spike done` closes it. Relay that block whole and run no second command. A refusal is not a transition; it carries no pointer, so relay it and stop.
21
22
 
22
23
  ## The spike report ([D70 (spike-reports)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d70))
23
24
 
@@ -16,11 +16,19 @@ inferred next move. Report it verbatim and point the human at that next move. Th
16
16
  skill carries **no Edit and no Write tool**: the CLI is the source of truth, so
17
17
  **never retry**, and never edit a file to change what the orientation says.
18
18
 
19
+ Status is an orientation turn (the
20
+ [turn anatomy](https://github.com/robmclarty/plumbbob/blob/main/docs/presentation.md)):
21
+ the dashboard is the whole output, relayed verbatim. Everything the human needs is
22
+ already in those bytes: the step in flight, the next step's done-when, seam, and `model:`
23
+ recommendation, the counts, and the one next move. You relay it; you do not re-compose or
24
+ annotate it.
25
+
19
26
  ## What it does
20
27
 
21
- 1. Surface the injected `status` output: the dashboard and its suggested next move.
22
- 2. If the next step's detail carries a `model:` line, point it out: it is the
23
- plan's recommendation of the smallest model that can carry that step, so the human
24
- can switch (for example `/model sonnet`) before firing `/plumbbob:build`, or ignore it. Guidance,
25
- never a gate.
28
+ 1. Surface the injected `status` output verbatim: the dashboard and its suggested next move.
29
+ 2. The dashboard already prints the next step's `model:` recommendation in its detail
30
+ rows when the plan set one: the smallest model that can carry that step, so the human
31
+ can switch (for example `/model sonnet`) before firing `/plumbbob:build`, or ignore it.
32
+ Guidance, never a gate. You relay that line; you do not re-state it on top of the
33
+ verbatim dashboard.
26
34
  3. If it reads `NO ACTIVE SESSION`, tell the human to `/plumbbob:plan` to frame a goal.
@@ -2,7 +2,7 @@
2
2
  name: verify
3
3
  description: "The verify tick: run the check, self-review the diff against intent, validate the step's done-when, pause for your approval, then checkpoint. Executor-agnostic: it reads the diff, not who wrote it."
4
4
  disable-model-invocation: true
5
- allowed-tools: Read, Bash(plumbbob status:*), Bash(plumbbob handoff:*), Bash(plumbbob check:*), Bash(plumbbob checkpoint:*), Bash(plumbbob agent:*), Bash(git diff:*), Bash(git status:*)
5
+ allowed-tools: Read, Write, Bash(plumbbob status:*), Bash(plumbbob handoff:*), Bash(plumbbob check:*), Bash(plumbbob checkpoint:*), Bash(plumbbob agent:*), Bash(git diff:*), Bash(git status:*)
6
6
  ---
7
7
 
8
8
  # PlumbBob: verify a step (the tick)
@@ -40,20 +40,109 @@ this skill verifies it the same way: **it reads the diff, not the author**
40
40
  - the **Decisions**: does anything contradict a settled call?
41
41
  - the **Constraints**: are any violated?
42
42
  - any **`after`-agent findings** from step 2: advisory, weigh them, don't defer to them.
43
- Surface every mismatch plainly, and when you cite a Decision or Constraint, carry its
44
- slug from `intent.md` (`C1 (no-new-deps)`, never a bare `C1`) so each finding reads
45
- on its own. You are reviewing, not building; do not fix anything.
46
- 4. **Validate.** State, yes or no, whether the step's done-when is met, with the evidence.
47
- 5. **PAUSE.** Present the check result, the self-review (with any `after`-agent
48
- findings), and the validation, then
49
- **stop and wait for the human's explicit approval.** This is the convergence beat;
50
- the human is the clock. Never checkpoint without it.
43
+ A mismatch surfaces in exactly two places: as the failing word in its recap row, and
44
+ as one highlight with its full story in a detail section, never as a freeform
45
+ paragraph. When you cite a Decision or Constraint, carry its slug from `intent.md`
46
+ (`C1 (no-new-deps)`, never a bare `C1`) so each finding reads on its own. You are
47
+ reviewing, not building; do not fix anything.
48
+ 4. **Validate.** Decide, yes or no, whether the step's done-when is met. That verdict and
49
+ its evidence become the recap's `done-when` row, stated there and nowhere else.
50
+ 5. **PAUSE.** Write the file, run handoff, paste, then **stop and wait for the human's
51
+ explicit approval**. This is the convergence beat; the human is the clock. Never
52
+ checkpoint without it. A verify pause is a decision turn, and the
53
+ [turn anatomy](https://github.com/robmclarty/plumbbob/blob/main/docs/presentation.md)
54
+ fixes it as one block. You author none of it in the chat. Your judgment goes into
55
+ `.plumbbob/detail.md`; `plumbbob handoff` renders the whole turn from that file and its
56
+ own measurements; you paste its output and write nothing before or after it. The rule
57
+ is positional on purpose: with the relay as the turn's whole text, no line is left for
58
+ "here is the pause", for reading the check verdict back in prose, or for a closing
59
+ courtesy. Each fact appears once, in its part.
60
+
61
+ *Write the detail file.* Before you call `plumbbob handoff`, overwrite
62
+ `.plumbbob/detail.md`. It is the wire handoff parses, and it is the only path by which
63
+ the judgment you formed in steps 2 through 4 reaches the turn:
64
+
65
+ ```markdown
66
+ # Detail · Step <N> · <the step title>
67
+
68
+ ── recap · step <N> of <M> ──
69
+ done-when met
70
+ decisions honored: D1 (some-slug), D2 (another-slug)
71
+ constraints all honored
72
+
73
+ ## Summary
74
+
75
+ <what the diff does, not the activity: one sentence when one will do, a
76
+ short paragraph when the step needs explaining>
77
+
78
+ ## 1 <the first highlight: one sentence, one move>
79
+ <the full story: what moved, why, what was tried and dropped>
80
+
81
+ ## 2 ...
82
+
83
+ ## Recommendation
84
+
85
+ <The move.> <The reason, one or two sentences.>
86
+ ```
87
+
88
+ The three rows under the header rule are yours, and only those three; `check`, `seam`,
89
+ `diff`, and `spent` are measured by the CLI, and a row you wrote for them would be
90
+ overwritten. Keep the rows contiguous (the first blank line ends them). Each opens with
91
+ a verdict word from the closed set in the turn anatomy (`met`, `not met`, `drift`;
92
+ `honored`, `none exercised`, `bent`, `drift`; `all honored`, `bent`, `drift`); a cited
93
+ decision or constraint carries its slug (`C1 (no-new-deps)`, never a bare `C1`); a row
94
+ that cannot apply vanishes. A green row collapses to its word or its count and a red one
95
+ names the one offender in a short clause, which is what keeps the whole row inside the
96
+ fence's 80 columns (13 of label, 67 of value); two or more items break onto indented
97
+ continuation lines opening with `-`, and a red row's evidence onto an indented `→` line.
98
+
99
+ The `## Summary` lead and the `## <n>` section titles are the turn's opening block:
100
+ handoff prints the lead behind the `**Summary**:` label, appends the `(details: …)`
101
+ bracket, and renders the titles as the numbered highlights, so you type neither the path
102
+ nor the list. Five highlights at most, each one move in plain English, drawn from the
103
+ self-review. The numbers are handles: "expand 2" opens `## 2`, so every highlight has a
104
+ section behind it. A judgment or a flag (a stray the seam row will name, a decision the
105
+ diff bent, a doubt about the done-when) is one of those highlights, never a paragraph of
106
+ its own. The recommendation is the last section: the move you would take as its own
107
+ sentence, closed by a period, then the reason as a capitalized sentence or two. The lead
108
+ and the recommendation are flowing prose and handoff unwraps both to the renderer's
109
+ width, so never hard-wrap them; handoff also prepends the bold `**Recommendation**:`
110
+ label, which you never type. This is the **one** file `/plumbbob:verify` writes, and it
111
+ is turn presentation, never the diff under review; the author-blind contract below still
112
+ holds. `checkpoint` folds this file into the commit body and then truncates it (the
113
+ detail plane in the
114
+ [turn anatomy](https://github.com/robmclarty/plumbbob/blob/main/docs/presentation.md)).
115
+
116
+ *Paste the turn.* Run `plumbbob handoff` and paste its output whole, verbatim, at top
117
+ level, trailing blank line included, then end the turn. Never nest it inside a fence of
118
+ your own; it carries fences of its own and they cannot nest. It prints the Summary and
119
+ its highlights, the Readout fence (its measured `check`, `seam`, `diff`, and `spent`
120
+ rows folded with your three), a `diff` fence when the change is 20 lines or fewer, the
121
+ Verdict folded worst-of from the same rows, Next Up, Your Call, and your recommendation
122
+ last. At the pause the check row reads green, since a red one stopped you back at step
123
+ 1. The gate verdict's one home is that row: no standalone verdict line exists, and you
124
+ never restate the verdict in prose. A narrowed run names the slots it skipped there
125
+ (`· without test`), and that named narrowing is the whole disclosure. The notice
126
+ checkride's Stop hook appends after your turn is not yours to relay or repeat; the
127
+ trailing blank line you kept is what lands it on its own line. Relayed CLI strings keep
128
+ their em-dashes; your own lines never use one, the write-versus-relay line of
129
+ [D78 (em-dash-ban)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d78).
130
+
131
+ *Then read the reply as an ask or a direction.* A message that **asks** ("expand 2",
132
+ "what does that mean?", "why did the seam row flag that?") is an expand: answer it from the detail file, from
133
+ `git diff`, or from `git show`, never from recall, then run `plumbbob handoff` again and
134
+ paste it. The step is still in flight, so it renders the same pause, and the Your Call
135
+ block stays the CLI's to render rather than yours to retype. A message that **directs**
136
+ is needs-work: take it as what to change, and nothing lands until the human says
137
+ `looks good`.
138
+
51
139
  - **Reconcile a drifted subject here, in the open.** The planned title *is* the
52
140
  checkpoint subject ([D68 (conventional-subjects)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d68)). If the diff drifted from it (the
53
141
  step landed something the title no longer describes), the body pass may propose a
54
- corrected subject, but it **presents** it at this pause for explicit approval: show
55
- `planned title → proposed subject`, one line, as part of what the human OKs. This is
56
- the exception, not the default: with **nothing presented**, the deterministic
142
+ corrected subject, but it **presents** it at this pause for explicit approval: one
143
+ highlight reading `planned title → proposed subject`, part of what the human OKs.
144
+ That highlight is a `## <n>` section title in the detail file like any other.
145
+ This is the exception, not the default: with **nothing presented**, the deterministic
57
146
  title-derived subject lands untouched. A silent `-m` swap is exactly the
58
147
  agent-authored subject [D68 (conventional-subjects)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d68) refuses, so a reconcile is
59
148
  *only ever* the visible, approved kind.
@@ -67,7 +156,7 @@ this skill verifies it the same way: **it reads the diff, not the author**
67
156
 
68
157
  ```bash
69
158
  plumbbob checkpoint <n> --body <<'BODY'
70
- <your proportional body — what changed and why, no ceremony>
159
+ <your proportional body: what changed and why, no ceremony>
71
160
  BODY
72
161
  ```
73
162
 
@@ -84,22 +173,26 @@ this skill verifies it the same way: **it reads the diff, not the author**
84
173
  overriding the title-derived default for this one commit; unpresented, the CLI's
85
174
  deterministic subject stands.
86
175
  7. **Hand off with the next model** *(once the checkpoint lands)*. `plumbbob checkpoint`
87
- returns to DESIGN; then run `plumbbob handoff` and relay its boundary block. With the
88
- step gone from in-flight it renders `step N checkpointed — back at the boundary` and
89
- points at the **next undone step**, carrying that step's `- model:` recommendation (the
90
- plan's smallest-model-that-fits call) so the human knows which `/model` to select before
91
- running `/plumbbob:build` again. This matters most across a context boundary: a fresh window
92
- inherits the *session's* model, not the plan's suggestion, so this line is what carries
93
- the recommendation over. The CLI owns the block, so it can't drift from what `plumbbob
94
- status` reports; no `- model:` line means any model will do. Guidance, never a gate.
176
+ returns to DESIGN and prints the whole boundary ending itself: `**Checkpoint**: Step N
177
+ complete (<sha>)`, the Verdict the step earned, any advisory (a staged path outside the
178
+ seam is the common one), and Next Up. Relay that block whole, run no second command,
179
+ and write nothing around it. It is the orientation tier (no Your Call block, no
180
+ recommendation), and it points at the **next undone step**, carrying that step's
181
+ `- model:` recommendation (the plan's smallest-model-that-fits call) so the human knows
182
+ which `/model` to select before running `/plumbbob:build` again. This matters most across a
183
+ context boundary: a fresh window inherits the *session's* model, not the plan's
184
+ suggestion, so this line is what carries the recommendation over. The CLI owns the
185
+ block, so it can't drift from what `plumbbob status` reports; no `- model:` line means
186
+ any model will do. Guidance, never a gate.
95
187
 
96
188
  ## The latch makes the pause real
97
189
 
98
190
  When this session runs under plumbbob's turn hook, `plumbbob checkpoint` **refuses to
99
191
  land a step in the same turn it was entered**, and that refusal **is** this pause, not
100
192
  an error to route around. If the checkpoint prints `checkpoint refused — no human turn
101
- since this step began`, you have reached the pause the hard way: present the diff and
102
- the self-review, **end the turn**, and the human's next message is the tick that lets
193
+ since this step began`, you have reached the pause the hard way: write the file, run
194
+ `plumbbob handoff`, paste its block as step 5 says, **end the turn there**, and the
195
+ human's next message is the tick that lets
103
196
  the checkpoint land when you run it again. **Never reach for a raw `git commit` to force the
104
197
  land**; that forges the very record the latch exists to keep honest, and the
105
198
  commit-ask hook asks the human about it anyway. The refusal is a healthy latch doing its
@@ -118,15 +211,18 @@ instead.**
118
211
  - **Red means stop, not pause.** A failing check is not an approval decision; report
119
212
  it and end your turn.
120
213
  - **You review; you do not build.** If the self-review finds a problem, surface it
121
- and stop; fixing is a new build beat, not part of verify.
214
+ and stop; fixing is a new build beat, not part of verify. The one file the tick writes
215
+ is `.plumbbob/detail.md`, the turn's presentation; it never edits the diff under review.
122
216
  - **`after`-agents advise; they never gate**. Their output feeds the
123
217
  self-review; checkride gates, the human approves. `blocked` → unblock and re-run;
124
218
  `drift` → `/plumbbob:refine` before checkpointing. No code path makes them blocking.
125
219
  - **A refused checkpoint is the pause, never a workaround.** Under the turn
126
- hook a same-turn checkpoint is refused *by design*: present the diff, **end the
127
- turn**, and let the human's next message re-tick it. Never route around it with a raw
128
- `git commit`; the latch guards the record, not the work.
129
- - **Close with the next model.** After the checkpoint lands, run `plumbbob handoff` and
130
- relay its block; it cites the completed step and the next undone step, and surfaces that
131
- next step's `- model:` recommendation when it has one, which is what a fresh context
132
- window needs to pick the right `/model`. Guidance, never a gate.
220
+ hook a same-turn checkpoint is refused *by design*: write the file, run `plumbbob
221
+ handoff`, paste its block, **end the turn there**, and let the human's next message
222
+ re-tick it. Never route around it with a
223
+ raw `git commit`; the latch guards the record, not the work.
224
+ - **Close with the next model.** When the checkpoint lands it prints the whole boundary
225
+ ending; relay it with nothing written around it and no second command. It cites the
226
+ completed step and the next undone step, and surfaces that next step's `- model:`
227
+ recommendation when it has one, which is what a fresh context window needs to pick the
228
+ right `/model`. Guidance, never a gate.