plumbbob 0.13.4 → 0.13.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,7 @@
2
2
  name: harvest
3
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, Write, Bash(plumbbob status:*), Bash(plumbbob order:*), Bash(plumbbob harvest:*)
5
+ allowed-tools: Read, Edit, Write, Bash(plumbbob status:*), Bash(plumbbob order:*), Bash(plumbbob handoff:*), Bash(plumbbob harvest:*)
6
6
  ---
7
7
 
8
8
  # PlumbBob: harvest the park list
@@ -54,24 +54,37 @@ the call on each one theirs. The detail file you write first is the proposal; re
54
54
  **only after** that reply confirms them:
55
55
 
56
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
57
+ header, one proposal per open item in a `## Harvest` section, with two lines indented
58
+ beneath it:
59
+
60
+ ```markdown
61
+ - P6 → tangent: <the reason, one clause>
62
+ - title: <two to five words naming the park>
63
+ - why: <why it matters, one clause>
64
+ ```
65
+
66
+ The class is written `blocker`, `tangent`, or `pivot` (for a pivot signal). A park's
67
+ handle is `P` and its place in the Park list, counting the harvested lines too (the
68
+ count the state table's Parked row sizes as `3 of 8 open`), and it is the one name the
69
+ detail file, the turn, and the human's reply all use
63
70
  ([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.
71
+ Then run `plumbbob handoff --harvest` and paste its output whole, verbatim, and end the
72
+ turn there: it prints the lean table, one row per open park with its handle and your
73
+ title, the park's text as the list holds it, your why, and your lean, then the moves that
74
+ settle it
75
+ ([D112 (lean-table)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d112)).
76
+ Write nothing before or after it; the park's text is the CLI's to quote, never yours.
77
+ - A reply that changes a proposal (`make P7 a tangent`) is the human's call and your
78
+ reply: rewrite that line, say in your own words which lean moved, and end the turn
79
+ without printing the table again; the human who wants to see it asks, and
80
+ `plumbbob handoff --harvest` prints it. A reply that confirms them (`looks good`) is what
81
+ lets you write.
69
82
  - On that confirmation, run `plumbbob harvest`
70
83
  ([D104 (harvest-records)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d104)).
71
84
  It flips each settled item from `- [ ]` to `- [x]` in the Park list, so
72
85
  `/plumbbob:status` stops counting it as open, and records each confirmed class under
73
86
  `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`
87
+ and the state table beneath it. It refuses a proposal naming a handle the list lacks (`P9`
75
88
  with eight parked) or a class other than blocker, tangent, or pivot; fix the line it
76
89
  names and run it again.
77
90
  - A confirmed **blocker** also folds its decision into `intent.md`, slugged at birth
@@ -163,8 +163,8 @@ The argument only seeds how you get there.
163
163
 
164
164
  **The card names the run, not the item.** The item's command is the range's
165
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
166
+ `/plumbbob:run` in the Range row beneath Next Up for the range holding the next step,
167
+ with the steps it will land beside it, and `/plumbbob:run 3` runs range 3 by its item number
168
168
  ([D95 (run-verb)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d95)).
169
169
  A range grants nothing until the human types the run that names it, and then the turn
170
170
  hook mints the grant from the plan as it stands
@@ -205,8 +205,9 @@ The argument only seeds how you get there.
205
205
  its build ranges with it (each range's command and its stop, since a stop is where
206
206
  the human will be asked, and moving one is cheapest now), then give it the cold
207
207
  read (**§ The cold read**), write the result into `.plumbbob/detail.md`, and relay `plumbbob handoff --plan`'s block whole: the CLI
208
- renders the your-call block with the moves that apply before anything is recorded and
209
- prints your recommendation last (the decision tier of the
208
+ renders the your-call block with the moves that apply before anything is recorded,
209
+ the state table headed by Next Up, your recommendation, and a `more details` link to
210
+ the cold read (the decision tier of the
210
211
  [turn anatomy](https://github.com/robmclarty/plumbbob/blob/main/docs/presentation.md)),
211
212
  so the moves are relayed, never hand-composed. *looks good* marks the plan decided, and
212
213
  its row names the move the human types next: `/plumbbob:run` for the range holding
@@ -224,9 +225,9 @@ The argument only seeds how you get there.
224
225
  commit predates the ledger and stays guidance-governed; it lands without a
225
226
  refusal.)
226
227
  - **The plan commit prints its own close.** `plumbbob checkpoint --plan` emits the
227
- whole boundary ending: `**Plan**: committed (<sha>)`, any advisory, and the pointer at
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
228
+ 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
230
+ run that lands that step's range when the plan declares ranges. Relay that block whole and run no second command; the
230
231
  plan-pause card above is the one place `handoff` is still called, because no verb has
231
232
  run yet there.
232
233
  - **Say what the commit publishes.** The close-out line names the tracked folder:
@@ -282,8 +283,8 @@ read checked and found sound. A plan with a hole gets `Sharpen <the one worst ho
282
283
  and why it matters; when the read found more than one, say how many sit behind `expand`
283
284
  and name `/plumbbob:refine` as the move that writes them up as Open questions, with their
284
285
  plain and lean sub-lines, for the human to settle. Three findings at most; the rest is
285
- refine's. `plumbbob handoff --plan` prints the label and your recommendation as the turn's
286
- last text, "expand 2" opens `## 2`, and `checkpoint --plan` records the read beneath the
286
+ refine's. `plumbbob handoff --plan` prints the label and your recommendation beneath the
287
+ state table, then the `more details` link to the file, "expand 2" opens `## 2`, and `checkpoint --plan` records the read beneath the
287
288
  plan's line in the build-log's `## Log`, the build's first entry. The cold read is the tip of refine: it makes the
288
289
  full attack discoverable at the moment it would pay, and lets a sound plan skip it. Refine
289
290
  is where the real adversary looks; this is an estimate, and it says so by staying short.
@@ -111,7 +111,7 @@ ends there: relay the checkpoint's block whole and end the turn. A run whose lan
111
111
  that step completed ends on the stop card, below, even when the paused step was the range's
112
112
  last. Otherwise carry on through what is left, below. A halt the human approves with
113
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
114
+ (its checkpoint block's table carries the `Stop` row for it), the run ends on the stop card
115
115
  too.
116
116
 
117
117
  **A range that lands its steps.** Walk it exactly as the build skill walks a typed 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 part (`**Stop**: Range 3 of 5 landed - <its stop>`); relay none of it, and end
125
+ with the Stop row (`| Stop | Range 3 of 5 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
@@ -161,6 +161,8 @@ constraints all honored
161
161
  ## Harvest
162
162
 
163
163
  - P<handle> → <blocker, tangent, or pivot>: <the reason, one clause>
164
+ - title: <two to five words naming the park>
165
+ - why: <why it matters, one clause>
164
166
 
165
167
  ## Recommendation
166
168
 
@@ -170,22 +172,28 @@ constraints all honored
170
172
  The header names the range by its item number, and that is how `checkpoint` and
171
173
  `plumbbob harvest` tell the file from a step's. The three rows judge the whole range: every
172
174
  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
175
+ numbered sections are the range's, not its last step's, and you draw them from the range's
174
176
  checkpoint bodies (`git log` over its commits) and their entries in the build-log's `## Log`,
175
177
  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.
178
+ early steps. A step that landed a hair off comes first among the sections; five at most. The
179
+ card prints the Summary and links the rest
180
+ ([D113 (short-card)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d113)).
177
181
 
178
- The `## Harvest` section carries one line for every open park in the build-log's
182
+ The `## Harvest` section carries one proposal for every open park in the build-log's
179
183
  `## 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`
184
+ lines too, which is the count the table's Parked row sizes as `3 of 8 open`: the third line
185
+ ever parked is `P3` whether or not the two above it are flipped, and the card, the detail
186
+ file, and the human's reply all name it `P3`
183
187
  ([D105 (park-handles)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d105)).
184
188
  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
+ with the reason in one clause, and beneath it two indented lines: a title of two to five
190
+ words that names the park, and why it matters in one clause. The card prints each park as a
191
+ row of the lean table: its handle and your title, the park's text as the list holds it, your
192
+ why, and the lean (`tangent: <the reason>`)
193
+ ([D112 (lean-table)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d112)),
194
+ so write the class, the reason, the title, and the why alone and leave the table to handoff.
195
+ A park you leave out reads `no lean proposed` on the card and stays open, and a missing why
196
+ reads `not given`. The section vanishes when no park is open, and so does the card's Harvested part
189
197
  ([D100 (stop-card)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d100)).
190
198
  The recommendation speaks to the plan's stop, the header's `stop:` line, and to the
191
199
  proposals: the move you would take on both, then why.
@@ -210,29 +218,32 @@ and the Your Call block names the replies. Read the human's message as one of th
210
218
  own, never into the range this card reviews: that range has landed, its call is the one
211
219
  being made, and the step would reopen it. Relay the record's ending whole and end the
212
220
  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`.
221
+ - **A change** (`make P7 a tangent`, or a change to the review) is direction, and the turn
222
+ that makes it is your reply
223
+ ([D110 (reply-after-the-card)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d110)).
224
+ Rewrite the detail file's line or section, say in your own words what moved, then run
225
+ `plumbbob handoff --stop` and paste the one-line reminder it prints beneath your reply.
226
+ The card does not come back for a change; nothing is recorded until `looks good`, which
227
+ records every lean as the detail file then reads.
216
228
  - **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`.
229
+ the Log, never from recall; then run `plumbbob handoff --stop` and paste the one-line
230
+ reminder it prints beneath your answer. Only `show the stop`, or any wording of it, takes
231
+ `plumbbob handoff --stop --full`, and never to read the card for yourself.
221
232
  - **`/plumbbob:run`** typed at the card confirms everything the way `looks good` does, and
222
233
  runs the next range. Record first: fold the blockers and run `plumbbob harvest`, then read
223
234
  `plumbbob status --run "<the same argument>"` again. When its grant line says
224
235
  `unlike the run`, the record re-cut the range the run would walk (a blocker added or moved a
225
236
  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
237
+ the record's ending whole and end the turn there, where its Range row names the re-cut run
238
+ for the human to type
228
239
  ([D102 (settle-in-one-reply)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d102)).
229
240
  Otherwise relay the record's ending and walk the run from section 4.
230
241
  - **`/plumbbob:finish`** at the plan's last range is the finish skill's to settle: it
231
242
  records the card the way `looks good` would before it writes the report.
232
243
 
233
244
  `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
245
+ parked) and a class outside the three, and it refuses a range no card showed; fix what the
246
+ refusal names, run `plumbbob handoff --stop` again, and end the turn on what it prints. One refusal takes another
236
247
  path: `step 13 joined it after it landed` means a blocker went into the range the card
237
248
  reviews. Move that step to a range still to come, or a bare range of its own, leave
238
249
  `.plumbbob/detail.md` as it is, fold nothing again, and run `plumbbob harvest` once more in
@@ -41,8 +41,8 @@ this skill verifies it the same way: **it reads the diff, not the author**
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
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`
44
+ as a numbered section of the detail file with its full story, which the row's `→`
45
+ line points at, never as a freeform paragraph. When you cite a Decision or Constraint, carry its slug from `intent.md`
46
46
  (`C1 (no-new-deps)`, never a bare `C1`) so each finding reads on its own. You are
47
47
  reviewing, not building; do not fix anything.
48
48
  4. **Validate.** Decide, yes or no, whether the step's done-when is met. That verdict and
@@ -101,14 +101,16 @@ this skill verifies it the same way: **it reads the diff, not the author**
101
101
  fence's 80 columns (13 of label, 67 of value); two or more items break onto indented
102
102
  continuation lines opening with `-`, and a red row's evidence onto an indented `→` line.
103
103
 
104
- The `## Summary` lead and the `## <n>` section titles are the turn's opening block:
105
- handoff prints the lead behind the `**Summary**:` label, appends the `(details: …)`
106
- bracket, and renders the titles as the numbered highlights, so you type neither the path
107
- nor the list. Five highlights at most, each one move in plain English, drawn from the
108
- self-review. The numbers are handles: "expand 2" opens `## 2`, so every highlight has a
109
- section behind it. A judgment or a flag (a stray the seam row will name, a decision the
110
- diff bent, a doubt about the done-when) is one of those highlights, never a paragraph of
111
- its own. The recommendation is the last section: the move you would take as its own
104
+ The `## Summary` lead opens the card: handoff prints it behind the `**Summary**:` label.
105
+ The `## <n>` sections stay in the detail file, where `expand 2` opens `## 2` and the
106
+ build log's record keeps them; the card prints none of them and closes instead on a
107
+ `[more details](…)` link to the file, which handoff writes, so you type no path. Five
108
+ sections at most, each titled with one move in plain English, drawn from the
109
+ self-review. A judgment or a flag (a stray the seam row will name, a decision the diff
110
+ bent, a doubt about the done-when) is one of those sections, and the card carries it
111
+ where it bears on the call: a bent row's `→` line points at it, and your recommendation
112
+ names it when it changes the move. It is never a paragraph of its own. The
113
+ recommendation is the last section: the move you would take as its own
112
114
  sentence, closed by a period, then the reason as a capitalized sentence or two. The lead
113
115
  and the recommendation are flowing prose and handoff unwraps both to the renderer's
114
116
  width, so never hard-wrap them; handoff also prepends the bold `**Recommendation**:`
@@ -123,13 +125,14 @@ this skill verifies it the same way: **it reads the diff, not the author**
123
125
  turn. The number is what lets a diff built outside `/plumbbob:build` reach its pause:
124
126
  nothing is in flight for that diff, and a bare `handoff` would read the moment as a
125
127
  boundary and render no Your Call block. Never nest it inside a fence of
126
- your own; it carries fences of its own and they cannot nest. It prints the Now line
127
- naming the step you reviewed, the Summary and its highlights, the Readout fence (its
128
- measured `check`, `seam`, `diff`, and `spent` rows folded with your three), a `diff`
129
- fence when the change is 20 lines or fewer, the Verdict folded worst-of from the same
130
- rows, Next Up, Your Call, and your recommendation last. Run it once: a second run at an
131
- unchanged pause prints the one-line reminder instead of the card, so if that line comes
132
- back where the card belongs (you ran handoff earlier in this turn), run
128
+ your own; it carries fences of its own and they cannot nest. It prints the Summary, the
129
+ Readout fence (its measured `check`, `seam`, `diff`, and `spent` rows folded with your
130
+ three, the changed files listed beneath `diff`), a `diff` fence when the change is 20
131
+ lines or fewer, Your Call, the state table (the Verdict folded worst-of from the same
132
+ rows, the Now row naming the step you reviewed, Next Up, and the rows beneath it), your
133
+ recommendation, and the `more details` link last. Run it once: a second run at the same
134
+ pause prints the one-line reminder instead of the card, so if that line comes back
135
+ where the card belongs (you ran handoff earlier in this turn), run
133
136
  `plumbbob handoff <n> --full` and paste that. At the pause the check row reads green,
134
137
  since a red one stopped you back at step 1. The gate verdict's one home is that row:
135
138
  no standalone verdict line exists, and you never restate the verdict in prose. A
@@ -140,32 +143,34 @@ this skill verifies it the same way: **it reads the diff, not the author**
140
143
  one, the write-versus-relay line of
141
144
  [D78 (em-dash-ban)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d78).
142
145
 
143
- *Then read the reply as an ask or a direction.* A message that **asks** ("expand 2",
144
- "what does that mean?", "why did the seam row flag that?") is an expand: answer it from
145
- the detail file, from `git diff`, or from the build-log's `## Log` for an older step,
146
- never from recall, then run `plumbbob handoff <n>` and paste its output beneath your
147
- answer, whole and verbatim. The turn is your answer, then that output, and nothing after
148
- it. The pause renders its card once
149
- ([D87 (pause-once)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d87)):
150
- while nothing about it has changed, handoff prints one line,
151
- `**Next Up**: Back to Step <N> of <M> - <title>`, in place of the card the human already
152
- read, so your answer stays on screen. The CLI picks the form, never you: paste whichever
153
- one it prints, and never retype the card or reach for `--full` to put it beneath an
154
- answer.
155
-
156
- Two moments bring the whole card back, and in both you run `plumbbob handoff <n> --full`
157
- and paste its output whole, with nothing written around it: the human asks to see the
158
- pause (`show the pause`, or any wording of it), or the card is not in this conversation
159
- (a fresh session, or one after `/clear`, that finds the step still at its pause). A
160
- message that **directs** is needs-work: take it as what to change, and nothing lands
161
- until the human says `looks good`.
146
+ *Then answer the reply in your own words.* The card shows once
147
+ ([D110 (reply-after-the-card)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d110)):
148
+ every later turn at this pause is your reply, closed by one line. A message that
149
+ **asks** ("expand 2", "what does that mean?", "why did the seam row flag that?") is an
150
+ expand: answer it from the detail file, from `git diff`, or from the build-log's
151
+ `## Log` for an older step, never from recall. A message that **directs** is needs-work:
152
+ make the change, run the check, and say what moved and what the check found; when the
153
+ change moves what the card said, write the detail file again so the record matches what
154
+ lands. Nothing lands until the human says `looks good`. Either way, then run
155
+ `plumbbob handoff <n>` and paste its output beneath your reply, whole and verbatim: at a
156
+ pause whose card has shown it prints one line,
157
+ `**Next Up**: Back to Step <N> of <M> - <title>`, whatever changed since, so your reply
158
+ stays on screen. The turn is your reply, then that line, and nothing after it. The CLI
159
+ picks the form, never you: paste whichever one it prints, and never retype the card.
160
+
161
+ The card comes back one way: the human asks to see it (`show the pause`, or any wording
162
+ of it). Then run `plumbbob handoff <n> --full` and paste its output whole, with nothing
163
+ written around it. Never run `--full` to read the card for yourself, after a compaction
164
+ or in a fresh session; what it prints is the turn's ending, and the relay check holds a
165
+ turn that does not close on it. Read the detail file and `plumbbob status` instead.
162
166
 
163
167
  - **Reconcile a drifted subject here, in the open.** The planned title *is* the
164
168
  checkpoint subject ([D68 (conventional-subjects)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d68)). If the diff drifted from it (the
165
169
  step landed something the title no longer describes), the body pass may propose a
166
- corrected subject, but it **presents** it at this pause for explicit approval: one
167
- highlight reading `planned title → proposed subject`, part of what the human OKs.
168
- That highlight is a `## <n>` section title in the detail file like any other.
170
+ corrected subject, but it **presents** it at this pause for explicit approval, in
171
+ the recommendation the card shows (`Approve it, landing it as <proposed subject>.`),
172
+ so it is part of what the human OKs, with the reasoning in a `## <n>` section of the
173
+ detail file titled `planned title → proposed subject`.
169
174
  This is the exception, not the default: with **nothing presented**, the deterministic
170
175
  title-derived subject lands untouched. A silent `-m` swap is exactly the
171
176
  agent-authored subject [D68 (conventional-subjects)](https://github.com/robmclarty/plumbbob/blob/main/docs/decisions.md#d68) refuses, so a reconcile is