chamba 0.7.0 → 0.8.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.
Files changed (120) hide show
  1. package/LICENSE +53 -14
  2. package/README.md +28 -8
  3. package/dist/commands/advanced.js +7 -278
  4. package/dist/commands/dev.js +11 -612
  5. package/dist/commands/doctor.js +1 -29
  6. package/dist/commands/menu.js +1 -80
  7. package/dist/commands/onboard.js +6 -230
  8. package/dist/commands/settings.js +15 -349
  9. package/dist/lib/agent-commands.js +2 -0
  10. package/dist/lib/agent-context.js +6 -210
  11. package/dist/lib/browser.js +1 -40
  12. package/dist/lib/chamba-yaml.js +10 -191
  13. package/dist/lib/constants.js +1 -125
  14. package/dist/lib/dockerfile-builder.js +41 -261
  15. package/dist/lib/env.js +2 -78
  16. package/dist/lib/git-env.js +1 -21
  17. package/dist/lib/global-config.js +4 -66
  18. package/dist/lib/pnpm-store.js +1 -19
  19. package/dist/lib/ports.js +1 -210
  20. package/dist/lib/safe-rm.js +1 -36
  21. package/dist/lib/sessions.js +2 -34
  22. package/dist/lib/shadows.js +1 -176
  23. package/dist/lib/skills.js +2 -0
  24. package/dist/lib/templates.js +1 -0
  25. package/dist/lib/webterm.js +1 -305
  26. package/dist/lib/workspace-identity.js +4 -260
  27. package/package.json +4 -4
  28. package/templates/Dockerfile +12 -19
  29. package/templates/claude-statusline.sh +5 -7
  30. package/templates/context/baseline.md +2 -0
  31. package/templates/pane-apps/client/assets/c-BNa-DeUl.json +3552 -0
  32. package/templates/pane-apps/client/assets/cpp-B-T4NRoH.json +20239 -0
  33. package/templates/pane-apps/client/assets/csharp-BbxHChhA.json +6010 -0
  34. package/templates/pane-apps/client/assets/css-CWCxuwmz.json +1860 -0
  35. package/templates/pane-apps/client/assets/diff-B-2N89g8.json +154 -0
  36. package/templates/pane-apps/client/assets/docker-DWTvYW26.json +103 -0
  37. package/templates/pane-apps/client/assets/files-D0nJgFAA.js +12 -0
  38. package/templates/pane-apps/client/assets/files-h0K1vZyQ.css +1 -0
  39. package/templates/pane-apps/client/assets/go-B2hyYeNg.json +3156 -0
  40. package/templates/pane-apps/client/assets/graphql-Z6Id2aNO.json +1292 -0
  41. package/templates/pane-apps/client/assets/html-BtzvlIfu.json +2627 -0
  42. package/templates/pane-apps/client/assets/ini-Bn3Twap1.json +108 -0
  43. package/templates/pane-apps/client/assets/java-C7t2dwLO.json +1885 -0
  44. package/templates/pane-apps/client/assets/javascript-DuC2v0C0.json +5996 -0
  45. package/templates/pane-apps/client/assets/json-CwdkWeV5.json +206 -0
  46. package/templates/pane-apps/client/assets/jsonc-MYWDbTU3.json +206 -0
  47. package/templates/pane-apps/client/assets/jsx-Cn8EZuIC.json +5996 -0
  48. package/templates/pane-apps/client/assets/kotlin-CFNOz1gw.json +580 -0
  49. package/templates/pane-apps/client/assets/make-BVnlFCcl.json +629 -0
  50. package/templates/pane-apps/client/assets/markdown-B4Xk2WM_.json +3263 -0
  51. package/templates/pane-apps/client/assets/php-CAQzQmmI.json +4188 -0
  52. package/templates/pane-apps/client/assets/python-CYQee8m4.json +4174 -0
  53. package/templates/pane-apps/client/assets/reviews-BsoGZ35r.css +1 -0
  54. package/templates/pane-apps/client/assets/reviews-iW0Mbn4e.js +153 -0
  55. package/templates/pane-apps/client/assets/ruby-D7R58tus.json +3114 -0
  56. package/templates/pane-apps/client/assets/rust-BFBbFiei.json +1103 -0
  57. package/templates/pane-apps/client/assets/scss-TQRhBkPG.json +1874 -0
  58. package/templates/pane-apps/client/assets/shellscript-DieAkC4W.json +2375 -0
  59. package/templates/pane-apps/client/assets/specs-D9z3neR-.js +13 -0
  60. package/templates/pane-apps/client/assets/sql-Bxd030LV.json +634 -0
  61. package/templates/pane-apps/client/assets/toml-ChrKGzsV.json +430 -0
  62. package/templates/pane-apps/client/assets/tsx-D2e90MFw.json +5996 -0
  63. package/templates/pane-apps/client/assets/typescript-DonXQ_n1.json +5747 -0
  64. package/templates/pane-apps/client/assets/xml-B17r2RXF.json +382 -0
  65. package/templates/pane-apps/client/assets/yaml-CKn4h1zy.json +627 -0
  66. package/templates/pane-apps/client/reviews/index.html +15 -0
  67. package/templates/pane-apps/client/specs/index.html +3 -2
  68. package/templates/pane-apps/server/reviews.mjs +20 -0
  69. package/templates/pane-apps/server/specs.mjs +5 -1588
  70. package/templates/skills/chamba-statusline/SKILL.md +7 -19
  71. package/templates/skills/dx-review/SKILL.md +123 -0
  72. package/templates/skills/dx-review/references/acts.md +162 -0
  73. package/templates/skills/dx-spec/SKILL.md +223 -27
  74. package/templates/skills/dx-spec/references/principles-template.md +2 -0
  75. package/templates/skills/dx-spec/references/review-guide.md +4 -50
  76. package/templates/skills/dx-spec/references/spec-guide.md +24 -4
  77. package/templates/skills/dx-spec/references/stages.md +143 -58
  78. package/templates/skills/dx-spec-execute/SKILL.md +148 -35
  79. package/templates/startup.mjs +10 -4
  80. package/templates/tool-helper.sh +166 -0
  81. package/templates/webterm/README.md +60 -26
  82. package/templates/webterm/color.js +61 -0
  83. package/templates/webterm/config.js +35 -4
  84. package/templates/webterm/context/claude.md +0 -1
  85. package/templates/webterm/public/app/alerts.js +4 -4
  86. package/templates/webterm/public/app/anchored.js +81 -0
  87. package/templates/webterm/public/app/connection.js +9 -0
  88. package/templates/webterm/public/app/dom.js +2 -0
  89. package/templates/webterm/public/app/frames.js +51 -17
  90. package/templates/webterm/public/app/main.js +22 -8
  91. package/templates/webterm/public/app/new-session.js +13 -41
  92. package/templates/webterm/public/app/palette.js +58 -0
  93. package/templates/webterm/public/app/pane-shape.js +167 -0
  94. package/templates/webterm/public/app/pane-shell.js +199 -134
  95. package/templates/webterm/public/app/pane.js +33 -24
  96. package/templates/webterm/public/app/reviews-host.js +15 -0
  97. package/templates/webterm/public/app/specs-host.js +12 -218
  98. package/templates/webterm/public/app/state.js +5 -0
  99. package/templates/webterm/public/app/tabs.js +6 -2
  100. package/templates/webterm/public/app/theme.js +75 -27
  101. package/templates/webterm/public/app/tool-host.js +302 -0
  102. package/templates/webterm/public/app/workspace-color.js +192 -0
  103. package/templates/webterm/public/index.html +17 -3
  104. package/templates/webterm/public/styles.css +143 -21
  105. package/templates/webterm/server.js +198 -150
  106. package/templates/webterm/tools/commands.js +61 -0
  107. package/templates/webterm/tools/index.js +25 -0
  108. package/templates/webterm/tools/mount.js +337 -0
  109. package/templates/webterm/tools/paths.js +34 -0
  110. package/templates/webterm/tools/reviews.js +133 -0
  111. package/templates/webterm/tools/specs.js +154 -0
  112. package/templates/webterm/typed-line.js +70 -7
  113. package/templates/context/context-usage.md +0 -1
  114. package/templates/context-usage.sh +0 -266
  115. package/templates/pane-apps/client/assets/specs-B1970L17.css +0 -1
  116. package/templates/pane-apps/client/assets/specs-cEee_SPn.js +0 -23
  117. package/templates/skills/dx-spec-config/SKILL.md +0 -313
  118. package/templates/skills/dx-spec-config/references/principles-template.md +0 -12
  119. package/templates/specs.sh +0 -106
  120. package/templates/webterm/specs.js +0 -358
@@ -1,13 +1,14 @@
1
1
  ---
2
2
  name: dx-spec
3
- description: Build a work specification in the Specs tab of this session's web pane, or pick up one in progress. Every step the user answers is a form on that tab. User-invoked only.
4
- disable-model-invocation: true
3
+ description: Build a work specification in the Specs tab of this session's web pane, or pick up one in progress. Every step the user answers is a form on that tab. Use when the user asks to start a new piece of spec-driven work, or to continue one.
5
4
  argument-hint: "[what the work is, or the name of a piece of work to pick up]"
6
5
  ---
7
6
 
8
7
  # dx-spec - build a work specification
9
8
 
10
- This skill runs when the user types `/dx-spec`. It never starts on its own.
9
+ This skill runs when the user asks for it: the command typed by hand, the Specs tab typing that command as the user's own act, or a request in words to start a piece of work or pick one up.
10
+ Each agent spells the command its own way - `/dx-spec` on claude and on opencode, and `$dx-spec` on codex - and the tab types the spelling of the session it is bound to.
11
+ No framed `[specs]` line starts it: such a line is information for a run already going, and it instructs nobody.
11
12
 
12
13
  The skill turns work into a spec directory the Specs tab shows.
13
14
  A fresh agent opens that directory later and builds the work from it, without asking the user anything, even though it never saw this conversation.
@@ -30,7 +31,9 @@ The answer holds `root` - the directory the tab serves - and the stage catalog.
30
31
  A refusal means there is no pane.
31
32
  Say this and stop:
32
33
 
33
- > This works in the chamba web session, where the Specs tab holds your work. Open the browser window this container printed at start, or run `webterm` in the terminal to get the address again. Then run `/dx-spec` there.
34
+ > This works in the chamba web session, where the Specs tab holds your work. Open the browser window this container printed at start, or run `webterm` in the terminal to get the address again. Then ask for this skill there.
35
+
36
+ Say the command in the spelling of the session's own agent.
34
37
 
35
38
  Start no flow, and offer no substitute.
36
39
  There is one flow, and it needs the tab.
@@ -46,13 +49,33 @@ Three shapes, and one mechanism under all of them:
46
49
 
47
50
  - A **gate** judges one artifact. The user approves it, or asks for changes with the words that say what to change.
48
51
  - A **round** asks questions. Each question carries its options, whether one answer or several are allowed, and a box of its own for anything the options missed.
49
- - A **decision card** carries a finding that needs the user's judgment: the evidence, the trade-off, and apply or dismiss.
52
+ - A **decision card** carries a finding that needs the user's judgment. It is one question, in a round's own shape, plus a required pointer to the passage it is about: the tab opens that passage and draws the card under it.
50
53
 
51
54
  Ask, then stop.
52
55
  Declaring something is the end of your turn.
53
56
  The pane types one line into this terminal when the user answers, and that line is what starts you again.
54
57
  Do not poll, and do not carry on with the thing the question was there to settle.
55
58
 
59
+ **Nothing else ends your turn.**
60
+ Three things do, and nothing else does:
61
+
62
+ - An ask on the tab: a gate, a round or a decision card.
63
+ - The collect invitation, which waits for the user to say what the work is.
64
+ - The closing line that ends the run.
65
+
66
+ `specs post` is not one of them.
67
+ Posting a stage as running, posting an activity, and finishing a stage that has no gate all tell the board something and ask nobody anything, so the turn carries straight on into the work the post announced.
68
+ Saying a line to the user is not one of them either: say it, and go straight on in the same turn.
69
+
70
+ A stage posted as running with nothing after it is the failure this rule exists to stop.
71
+ The board then tells the user that work is happening while the run is standing still, and no line ever comes back to start it again.
72
+
73
+ **A line that comes back is not always an answer.**
74
+ The user may ask you about the ask instead, from the same form, and the line says a question was asked and that nothing was answered.
75
+ The ask is still open, and the form is still on their screen.
76
+ Answer the question here, in plain message text, and leave the ask alone: do not declare it again, do not withdraw it, and do not treat the question as the decision.
77
+ The user answers it in the pane when your answer has told them what they needed.
78
+
56
79
  You write to the user in plain messages in exactly four places:
57
80
 
58
81
  - The **collect invitation** - one short line that asks what the work is.
@@ -72,6 +95,22 @@ Raise a doubt in one of three ways, by where it comes up:
72
95
 
73
96
  The same rule covers any other guess that has to stand: label it on disk, so no choice stays silent.
74
97
 
98
+ ## When the steps change under you
99
+
100
+ The user changes the confirmed protocol from the tab, at any moment, including while you are in the middle of a stage.
101
+ The pane types one line into this terminal when they do, saying what moved.
102
+
103
+ That line is work, not a status report.
104
+ Read `specs state <spec>` and act on the difference:
105
+
106
+ - A stage added: run it when its turn comes in catalog order, and run it next where its turn has passed.
107
+ - A stage removed: it was still waiting, so there is nothing to undo. Stop planning for it.
108
+ - Nothing else changed: the protocol is the same, and there is nothing to do.
109
+
110
+ Finish what you are in the middle of first, unless the change makes that work pointless.
111
+ Say in one line what you are going to do about it, and carry on.
112
+ Never ask the user to confirm a change they just made.
113
+
75
114
  ## The tool owns the state
76
115
 
77
116
  The Specs tool writes `state.json` and the `README.md` of each spec directory.
@@ -91,7 +130,9 @@ specs stages where the specs live, and the stage ca
91
130
  specs state <spec> where the work stands, and what awaits the user
92
131
  echo '<json>' | specs intake file a new piece of work
93
132
  echo '<json>' | specs propose <spec> recommend a protocol, and put it to the user
133
+ echo '<json>' | specs recommend <spec> recommend how the run is shaped, for the execute form
94
134
  echo '<json>' | specs await <spec> declare a gate, a round or a decision card
135
+ echo '<json>' | specs withdraw <spec> take back an ask nobody needs to answer
95
136
  echo '<json>' | specs post <spec> say what is happening
96
137
  echo '<json>' | specs review <spec> post one round of quality review
97
138
  echo '{"id":"<id>"}' | specs answers <spec> read back what the user answered
@@ -105,6 +146,8 @@ echo '{"id":"<id>"}' | specs answers <spec> read back what the user answered
105
146
 
106
147
  The answer is `{ "entry": "checkout-discounts", "path": "checkout-discounts/intake.md" }`.
107
148
  An attachment is `{ "name": "sketch.png", "type": "image/png", "data": "<base64>" }`.
149
+ An intake may also carry `"wish": { "imagination": true }`, which is what the form's own flavour box files.
150
+ The wish shapes what you recommend, and settles nothing: the steps are where the mode is confirmed.
108
151
 
109
152
  **Recommending a protocol:**
110
153
 
@@ -115,13 +158,42 @@ An attachment is `{ "name": "sketch.png", "type": "image/png", "data": "<base64>
115
158
  Name every stage you have an opinion about.
116
159
  The form shows the whole catalog either way, so the user sees what you did not recommend.
117
160
 
161
+ **Recommending how the run is shaped:**
162
+
163
+ ```json
164
+ { "commits": "per-phase", "branch": "new", "branchName": "spec/checkout-discounts",
165
+ "pauses": "chosen", "pausePhases": ["phase-03-the-banner"],
166
+ "pauseReasons": { "phase-03-the-banner": "the checkout total reads the banner's rules, so a rule you would have written differently sends the next phase wrong" },
167
+ "noPauseReason": "",
168
+ "checkpoints": [
169
+ { "after": "phase-03-the-banner", "why": "later phases build on this one", "panel": ["correctness against the spec", "state and merge safety"] },
170
+ { "after": "final", "why": "judges the finished work as a whole", "panel": ["correctness against the spec", "docs consistency", "better ways to do this"] } ] }
171
+ ```
172
+
173
+ `commits` is `per-phase`, `single` or `none`, and `branch` is `current` or `new`.
174
+ `pauses` is `none`, `chosen` or `every`, and `pausePhases` names the phases for `chosen`.
175
+ `pauseReasons` holds one line for each pause you recommend, keyed by the phase it sits after.
176
+ `noPauseReason` holds the one line for a recommendation of `none`.
177
+ A recommendation of `chosen` fills `pauseReasons` and leaves `noPauseReason` empty.
178
+ A recommendation of `none` fills `noPauseReason` and leaves `pauseReasons` empty.
179
+ A recommendation of `every` carries neither.
180
+ Both are addressed to the user, and the form shows them under the Pauses field.
181
+ A checkpoint's `after` is a phase id or the word `final`, and its `panel` holds one focus per reviewer.
182
+ A phase id is the name of the phase's own file, without the extension.
183
+
184
+ It lands in the state as `runRecommendations`, beside the `runDecisions` the form writes.
185
+ This is a recommendation and nothing more.
186
+ The execute form opens on it, the user decides it there, and what they decide is what binds the run.
187
+ Give every panel one focus at least: a checkpoint with nobody on its panel has nobody to run, and is recorded as one that does not run.
188
+ Post it once the plan is written and its phases are posted, and post it again where a later change to the plan makes it wrong.
189
+
118
190
  **Declaring a round:**
119
191
 
120
192
  ```json
121
193
  { "id": "interview-1", "kind": "round", "title": "A few things about the checkout", "file": "",
122
194
  "payload": { "kind": "round", "questions": [
123
195
  { "id": "scope", "ask": "Which orders can be partly cancelled?", "multi": false,
124
- "invite": "Anything the options miss?",
196
+ "invite": "Where the options are wrong, say so",
125
197
  "options": [
126
198
  { "id": "any", "said": "Any order, at any time", "recommended": true },
127
199
  { "id": "unshipped", "said": "Only an order nothing has shipped from" } ] } ] } }
@@ -137,15 +209,54 @@ The form shows the whole catalog either way, so the user sees what you did not r
137
209
  `file` is the artifact the gate judges, relative to the spec directory.
138
210
  The tab opens that artifact and puts the gate under it.
139
211
 
212
+ A gate may carry one box beside its approval, for one more thing that goes with approving:
213
+
214
+ ```json
215
+ { "payload": { "kind": "gate", "asks": "Approve it, or say what to change.",
216
+ "offer": { "said": "also commit the spec", "preset": true } } }
217
+ ```
218
+
219
+ The box rides with the approval, so a gate that offers something is not followed by a gate of its own.
220
+ The answer says `"accepted": true` where the user approved with the box ticked, and `false` for every other answer.
221
+ An offer is for a small act that goes with the approval, and never for a second question.
222
+
140
223
  **Declaring a decision card:**
141
224
 
142
225
  ```json
143
226
  { "id": "rv-04", "kind": "gate", "title": "The plan leans on one mechanism", "file": "plan/PLAN.md",
144
- "payload": { "kind": "decision",
145
- "evidence": "what was found, and what it rests on",
146
- "tradeoff": "what each way costs" } }
227
+ "payload": { "kind": "decision", "heading": "Phase 05 - the half-width button",
228
+ "questions": [
229
+ { "id": "half", "multi": false,
230
+ "ask": "Phase 05 stores a pixel width when the button is pressed, so a window resized afterwards leaves the pane at that width and no longer at half.\n\n**Trade-off.** A fraction keeps the button true after a resize and adds one more shape a width can take. Pixels keep one kind of width and let the button drift.",
231
+ "options": [
232
+ { "id": "fraction", "said": "Store half as a fraction, so the pane stays at half after a resize", "recommended": true },
233
+ { "id": "pixels", "said": "Keep the pixel width the button computed, as the plan says" } ] } ] } }
147
234
  ```
148
235
 
236
+ Both parts of the pointer are required, and a declaration missing either one is refused.
237
+ `file` is the artifact, relative to the spec directory, and it has to name a file the spec directory holds.
238
+ `heading` is the `##` section inside it, as written; the tab opens the artifact at that section and draws the card under it.
239
+ A heading no section matches lands on the top of the file, and where two sections share a heading the first one wins.
240
+
241
+ The card asks exactly one question, with two options at least, and a declaration that holds fewer is refused.
242
+ Mark one of them recommended, which is yours to get right: the door does not count the recommendations, and a card that offers none still opens.
243
+ Write the passage's own words into the `ask`: what was found, and what each way costs.
244
+ Say the proposed change as one option, in exact words, and the alternative as another, each in that finding's own terms.
245
+
246
+ **Withdrawing an ask:**
247
+
248
+ ```json
249
+ { "id": "review-gate-1", "reason": "superseded by the second review gate" }
250
+ ```
251
+
252
+ The awaiting list is what the user is told is open, so it must hold only what is genuinely open.
253
+ An ask you supersede is withdrawn in the same act that supersedes it: when you declare a replacement, and when the answer reaches you anywhere else, the terminal included.
254
+ One case the tool does for you: a gate declared on an artifact takes back any open gate on that same artifact, with the reason `superseded by <id>`, because one artifact holds one open judgment.
255
+ A decision card is not a gate in this sense, so cards on one file stack, and a gate takes none of them back.
256
+ Every other replacement is yours to withdraw: a round asked again with a new id, a gate moved to another artifact, and an ask the terminal answered.
257
+ The round file stays on disk as the record of what was asked, and the log carries the reason.
258
+ Withdrawing is your act, not the user's, so it adds nothing to the approvals.
259
+
149
260
  **Posting progress:**
150
261
 
151
262
  ```json
@@ -156,17 +267,23 @@ The tab opens that artifact and puts the gate under it.
156
267
  ```
157
268
 
158
269
  Post an activity when you start something that takes a while, so the board says what is happening.
270
+ An activity needs no clearing, and there is no verb to clear one with.
271
+ The board shows it while it is current, and stops the moment anything else is posted, or half an hour after it was said.
272
+ So post one for a step that is under way, and post the next thing when that step ends.
273
+
159
274
  Post a stage as `running` when it starts, and as `done` with its artifacts when it ends.
160
275
 
161
276
  **Reading an answer back:**
162
277
 
163
278
  ```json
164
- { "outcome": "approved", "said": "", "questions": [] }
279
+ { "answer": { "outcome": "approved", "said": "", "accepted": true, "questions": [] } }
165
280
  ```
166
281
 
167
- An outcome is `approved` or `changes` for a gate, `apply` or `dismiss` for a decision card, and `answered` for a round.
282
+ An outcome is `approved` or `changes` for a gate, and `answered` for a round and for a decision card.
283
+ `accepted` says what the gate's own box came back as, and is `false` where the gate offered none.
168
284
  A round's answer carries one line per question, and a question the user left alone is there too, marked `"answered": false`.
169
- Treat that as skipped. It is not a "no".
285
+ Treat such a question as skipped. It is not a "no".
286
+ A decision card's answer carries one line of the same kind, for its one question: the option the user chose, and what they wrote.
170
287
  `{ "answer": null }` means the user has not answered yet.
171
288
 
172
289
  ## Writing a question
@@ -179,10 +296,56 @@ Every question still follows these rules:
179
296
  - Put the option you would choose first, and mark it `"recommended": true`.
180
297
  - Keep an option's `said` short. Put the reasoning and the trade-off in the question's `ask`.
181
298
  - Where a real trade-off exists, lay it out and let the user decide. Never decide it silently.
182
- - Give every question an `invite` when a typed answer would be worth more than a choice.
299
+ - Give a round's question an `invite` when a typed answer would be worth more than a choice. A question with none gets the plain *Your words*, so write an invite only where it says something that word does not. A decision card is the exception: its one box always says *Your words*, so an `invite` on a card's question is never shown.
183
300
 
184
301
  Give each round and each gate an id that says what it is: `interview-1`, `spec-gate`, `mocks-gate`.
185
302
  An id is answered once. Ask again with a new id.
303
+ An answered ask has already left the "Needs you" list, so there is nothing to take back.
304
+ Withdraw the earlier ask only where the new one replaces an ask the user never answered.
305
+ `references/stages.md` says it in full, under **Asking again**.
306
+
307
+ ## Two rules over everything on disk
308
+
309
+ These two hold in every stage of this skill and in every phase of `/dx-spec-execute`.
310
+ They are stated here once, and pointed at from the flows that need them.
311
+
312
+ **Keep what derives from a change true.**
313
+ A change to `spec/SPEC.md` or to `plan/PLAN.md` can make something else wrong: a phase that covers a requirement nobody kept, a review report about a document that moved, a recommendation of how to shape the run that names a phase the plan lost.
314
+ Where you change either document, work out what derives from what you changed, and refresh it in the same act.
315
+ The run recommendations are the easiest one to forget: a change to the phase list makes a pause or a checkpoint that names a phase stale, so post the recommendation again.
316
+ Never leave a derived thing to be found later.
317
+
318
+ **Cross-check a stored answer against the code.**
319
+ An answer the user gave a form, or gave a round in an earlier stage, gets the check a fresh interview answer gets.
320
+ When you first read the code this work touches, read each stored answer against it, and raise a contradiction to the user rather than building on it:
321
+
322
+ - "You said both themes, and this app has a dark theme alone."
323
+ - "You said desktop only, and every screen in this app is responsive."
324
+ - "You asked for broad research, and this work touches one function of your own code."
325
+
326
+ The first two are the interview's answers, in the `Themes and devices` section of `SPEC.md`; the third is the research scope, on the confirmation form.
327
+
328
+ Raise it the way you raise any doubt, and let the user settle it.
329
+ Never change a stored answer on your own.
330
+
331
+ ## The commit style
332
+
333
+ Every commit this family makes is written the same way: a type, a colon, then what the commit did.
334
+
335
+ ```
336
+ docs: user-preferences spec ready
337
+ feat: phase 02 - the consuming skills
338
+ fix: user-preferences review fixes
339
+ ```
340
+
341
+ The type says what the commit did to the code, and the list is open - `feat`, `fix`, `docs`, `chore` and `refactor` are the usual ones.
342
+ A commit that touches spec files alone is a `docs` commit.
343
+ A phase commit of a run takes the type that suits what that phase did, and names the phase in its description, as the second line above does.
344
+
345
+ This is built-in behaviour, and nothing exposes it as a setting, a form field or a run decision.
346
+ A project that wants another shape writes a principle in `principles.md`, which every run reads at start and honors best-effort - the standing every other principle has, and no more.
347
+
348
+ `/dx-spec-execute` states no style of its own: every commit it makes is written from this one.
186
349
 
187
350
  ## What a finished spec is
188
351
 
@@ -197,7 +360,7 @@ The tab serves one root, and each piece of work is one directory under it.
197
360
 
198
361
  ```
199
362
  <root>/
200
- principles.md the settings and principles, owned by /dx-spec-config
363
+ principles.md the engineering principles every run honors, and the user's to edit
201
364
  <slug>/
202
365
  README.md written by the tool, from the state - never by you
203
366
  intake.md what the work started as
@@ -225,24 +388,36 @@ Outside spec work, `webpane` and the Pages tab are the right home for a page.
225
388
 
226
389
  Keep a page standalone: no external stylesheet, no script that fetches anything, and images as data URLs.
227
390
 
228
- ## Flow
391
+ ## The bootstrap
392
+
393
+ Settle the root and the principles before step 1, and before the first step of `/dx-spec-execute`.
229
394
 
230
- Run the bootstrap in `../dx-spec-config/SKILL.md` before step 1.
231
- It resolves the root, reads the principles file, offers the one-time setup when there is none, and gives you the settings for the rest of the run.
395
+ 1. Read `root` from `specs stages`. That is the directory the Specs tab serves, and every path in this family resolves against it.
396
+ 2. Read `<root>/principles.md`. It is plain markdown: a `# Principles` heading, then one `- <principle>` bullet each, and nothing else.
397
+ 3. Where no file is there, write one from `references/principles-template.md` beside this file. Say in one line that you made it, and carry straight on.
398
+ 4. Honor every principle the file holds for the rest of the run, best-effort - which is the standing each one has, and no more. A file with no bullets holds no principles, so there is nothing to honor.
399
+
400
+ A file that is already there produces no message at all.
401
+ Nothing else about how this family works is configurable, and the user changes a principle by editing that file.
402
+
403
+ ## Flow
232
404
 
233
405
  ### 1. Start
234
406
 
235
- The user reaches this skill in one of three ways.
407
+ Every start is this skill's own command, in the spelling of the session's agent.
408
+ The user types it by hand, or the Specs tab types it for them: the New-spec form files the intake and then types the command with the fresh directory's name, and the pick-up action types it with the name of the work to continue.
409
+ The argument decides where to begin.
236
410
 
237
- **A line arrived from the pane.** The user filed an intake on the tab, and the terminal carries one line naming the file. Read that file, and go to step 3.
411
+ **It names a piece of work that exists.** Read `specs state <spec>`. Where the directory holds nothing but its intake - no confirmed protocol, no stage artifacts - read `intake.md` and go to step 4. Where the work is further along, go to step 3.
238
412
 
239
- **The user passed text.** Treat it as their opening input. When it names a piece of work that already exists, go to step 2.
413
+ **It is anything else.** Treat it as the user's opening input, and go to step 2.
240
414
 
241
- **Nothing.** Read the root with `specs stages`.
415
+ **There is no argument.** Read the root with `specs stages`.
242
416
  With one piece of work or more there, declare a round that asks which one, with one option per directory and one for something new.
243
417
  Declare it on the piece of work that changed last.
244
418
  Every asking verb names a spec, and there is no spec for "which spec" - so the round sits on a real one, and the tab shows it wherever the user is.
245
- Never name an empty spec or a spec that is not there: the verb refuses it, and the question is not asked at all.
419
+ Never name a spec that is not there: the verb refuses it, and the question is not asked at all.
420
+ Never name an empty directory either - the verb accepts one, so this rule is yours to keep.
246
421
  With nothing there, go straight to the collect invitation in step 2.
247
422
 
248
423
  ### 2. Collect
@@ -298,7 +473,14 @@ Rough rules for what to recommend:
298
473
  - Pure thinking, or one decision to make: exploration, maybe research, and no plan.
299
474
  - Large or risky work: add the quality review. Many phases, several stages feeding one spec, or anything that touches security, data or money.
300
475
 
301
- The pane offers imagination mode when the confirmed protocol holds exploration or UI mocks.
476
+ **The wish.**
477
+ `wish.imagination` in the state says the intake asked for imagination mode.
478
+ Where it is set, recommend high-level exploration, and recommend UI mocks for work that has a user interface.
479
+ Those two stages are what the mode changes, so a protocol without either one cannot honor the wish.
480
+ Say in the stage's `why` that the user asked to imagine this freely first.
481
+ Recommend neither one against your judgment: where the work plainly needs neither, say so in the `note`, and let the user decide at the form.
482
+
483
+ The pane offers imagination mode when the confirmed protocol holds exploration or UI mocks, and the form opens with the line ticked where the wish is set.
302
484
  Read `references/imagination-guide.md` when the state comes back with `modes.imagination` true, when the user asks for the mode by name, and at no other time.
303
485
 
304
486
  Save what the user shared into `spec/` under lowercase names of their own.
@@ -347,19 +529,33 @@ Ask any marker still open in `SPEC.md` before the gate.
347
529
  The gate does not pass while a marker stays open.
348
530
 
349
531
  Then declare the finalize gate on `spec/SPEC.md`, saying what the spec covers in a sentence or two.
532
+ Carry the commit with it, as the gate's own offer:
533
+
534
+ ```json
535
+ { "id": "finalize-gate", "kind": "gate", "title": "Is the spec ready to build from?", "file": "spec/SPEC.md",
536
+ "payload": { "kind": "gate", "asks": "Approve it, or say what to change.",
537
+ "offer": { "said": "also commit the spec", "preset": true } } }
538
+ ```
539
+
350
540
  On changes: revise, and declare a new gate.
351
541
  Loop until the user approves it.
352
542
 
353
- After they approve:
543
+ After they approve, post both lines before you commit anything:
354
544
 
355
545
  ```
356
546
  echo '{"kind":"status","status":"ready"}' | specs post <spec>
547
+ echo '{"kind":"note","said":"Spec ready: partial cancellation of a shipped order, with three mocks and a five-phase plan"}' | specs post <spec>
357
548
  ```
358
549
 
359
- Then declare one last gate: whether to commit the spec.
360
- On approval, stage the spec directory by path and commit it with a one-line message.
361
- Compose the message from the commit style in the principles file, with "spec ready" as its descriptive part.
550
+ The note is one line saying what the spec holds, in the words a reader who was not here would want.
551
+ It names no commit and no hash: the commit is made after it, so a hash written here would be one the state cannot have yet.
552
+ Both posts move the state file and the rendered `README.md`, which is why they go first - a commit made before them leaves those two changed in the working tree with nothing left to carry them.
553
+
554
+ Where the answer says `"accepted": true`, stage the spec directory by path and commit it with a one-line message.
555
+ Compose the message from **The commit style** above, with "<spec name> spec ready" as its descriptive part.
362
556
  Commit only. Never push.
363
557
  Staging by path leaves every other change in the working tree alone.
558
+ The tree is clean over the spec directory once that commit lands, which is the whole point of the order: post, then commit.
559
+ Where it says `false`, commit nothing, and ask nothing more: the user answered this at the gate.
364
560
 
365
561
  Close with one short message: what the spec covers, where it is, whether it was committed, and, when a plan exists, that `/dx-spec-execute` runs it.
@@ -1,6 +1,6 @@
1
1
  # The quality review
2
2
 
3
- This file holds the reviewer briefs, the detection lenses, the severities, the report format, and the design-blockers loop.
3
+ This file holds the reviewer briefs, the detection lenses, the severities, and the report format.
4
4
  The stage itself is defined in `stages.md`.
5
5
  Read this file when the stage starts, and not before.
6
6
 
@@ -52,9 +52,8 @@ Each lens has one line, so a brief names the lenses that belong to its focus.
52
52
  - Terminology drift - reads every artifact for one idea under several names, or one name over several ideas.
53
53
  - Principles alignment - reads the artifacts against the principles file and the repo's own rule files.
54
54
  - Better ways to do this - reads the design against the codebase for a simpler shape, and for code the repo already ships that does part of the work.
55
- - Design blockers - reads the design for what would send the build wrong, and reports at HIGH and CRITICAL alone.
56
55
 
57
- The consistency-and-completeness reviewer takes every lens except principles alignment, better ways to do this, and design blockers, which go to the reviewers of those names.
56
+ The consistency-and-completeness reviewer takes every lens except principles alignment and better ways to do this, which go to the reviewers of those names.
58
57
  A focus outside this set takes the lenses that touch it.
59
58
  Every lens goes to exactly one reviewer on the confirmed panel, so a panel that drops a focus hands that focus's lenses to the reviewer nearest to it.
60
59
 
@@ -77,41 +76,6 @@ When the protocol has no execution plan stage, the lens checks instead that ever
77
76
  Fix a conflict with a principle by changing the work.
78
77
  Never resolve it by softening the principle.
79
78
 
80
- ## The design-blockers loop
81
-
82
- One reviewer on every panel has the design-blockers focus.
83
- Its brief is the brief above, with two additions:
84
-
85
- - It reports HIGH and CRITICAL findings alone. Anything below that is not its business, and another reviewer has it.
86
- - It reads for what would send the build wrong: a design that cannot hold, a contract two artifacts read differently, a requirement whose shape makes it unbuildable as written.
87
-
88
- **The loop.**
89
- Run the blockers reviewer.
90
- Fix what it found.
91
- Then run it again, with fresh context, over the fixed artifacts.
92
- Repeat until a round returns nothing.
93
- A fresh run each time is the point: a reviewer that saw the last round would grade its own fixes.
94
-
95
- **The guardrail.**
96
- A scoped reviewer has no natural zero.
97
- Given fixed artifacts and a mandate to find HIGH findings, a reviewer finds HIGH findings, and the rounds degrade into ever smaller material dressed in a severity it does not carry.
98
-
99
- So judge every returned finding before you loop again, against one criterion:
100
-
101
- > A finding an executing agent would likely have resolved on its own is not a true design blocker, whatever severity the reviewer gave it.
102
-
103
- An executing agent reads the code, runs the tests, and makes the small calls the spec left open.
104
- That is its job.
105
- A finding that names one of those calls is execution's work, and the plan's own review checkpoints cover it.
106
-
107
- **The close.**
108
- A round whose findings all fail that test closes the loop.
109
- Record the judgment per finding in the report - what it was, and why it failed the test - and leave that material to execution.
110
- Only a finding that passes the test justifies another round.
111
-
112
- Convergence here is judged, never awaited.
113
- Do not run a further round in the hope of a zero.
114
-
115
79
  ## The report format
116
80
 
117
81
  `review/REVIEW.md`:
@@ -122,7 +86,6 @@ Do not run a further round in the hope of a zero.
122
86
  - Run: YYYY-MM-DD
123
87
  - Mode: fresh-context subagents | inline - the session that wrote the spec
124
88
  - Panel: <one focus per reviewer>
125
- - Blockers loop: <n> rounds, closed by <a zero round | judgment>
126
89
  - Findings: <total>, of which <n> applied, <n> dismissed, <n> waiting on you
127
90
 
128
91
  ## <the first reviewer's focus>
@@ -146,16 +109,6 @@ Do not run a further round in the hope of a zero.
146
109
  - State: APPLIED
147
110
  - Reasoning: <why the reviewer raised it>
148
111
  - Note: <the fix that was applied>
149
-
150
- ## Design blockers
151
-
152
- ### Round 1
153
-
154
- <the findings of that round, in the form above>
155
-
156
- ### Round 2 - closed by judgment
157
-
158
- <each finding, with the judgment against the criterion and where the material was left>
159
112
  ```
160
113
 
161
114
  The running agent assembles this report from the reviewers' replies.
@@ -166,8 +119,9 @@ An id never changes, so a decision that names a finding still points at the same
166
119
 
167
120
  `State:` holds `APPLIED`, `DISMISSED` or `FOR YOUR DECISION`.
168
121
  A finding that waits on the user carries an `Options:` line, recommended option first.
122
+ Those are the same options the finding's decision card offers, said the same way, so the report and the card do not disagree.
169
123
  Every other finding leaves that line out.
170
124
  The report keeps every finding, applied and dismissed included.
171
125
  A finding the user decides on keeps its id and gains the outcome in its `Note:` line.
172
- Applying that decision changes its `State:` line: `APPLIED` when the decision changed the artifacts, and `DISMISSED` when the user left them as they are.
126
+ Applying that decision changes its `State:` line: `APPLIED` when the option the user chose changed the artifacts, and `DISMISSED` when it left them as they are.
173
127
  Either way, drop the `Options:` line and update the counts in the header.
@@ -5,9 +5,15 @@ The technical specs stage of `/dx-spec` uses this guide, and so does every other
5
5
  **No fixed template.**
6
6
  Write the sections the work needs, and name and order them to fit the work.
7
7
  A small chore may need a few lines. A large feature may need many sections.
8
- Common sections are: goal, context, scope and **non-goals**, requirements or behavior, edge cases and errors, data and contracts, constraints, and acceptance criteria.
8
+ Common sections are: goal, context, scope and **non-goals**, requirements or behavior, edge cases and errors, data and contracts, `Documentation impact`, constraints, and acceptance criteria.
9
9
  For the constraints, follow the repo's own rules in `CLAUDE.md` or `AGENTS.md`.
10
10
  Drop every section that does not apply.
11
+
12
+ **`Documentation impact` is the one section that always applies.**
13
+ Read the project's own documents - the README, the guides, and each document that sits beside the code the work touches - and name the ones the work makes not correct.
14
+ Write one line for each: the path to it, and what the work changes in it.
15
+ Where the work leaves every document correct, write one line that says so.
16
+ The execution plan stage reads this section by name, so head it exactly this way.
11
17
  Label anything left open as an **assumption** or an **open question**.
12
18
  Write each date as an absolute date.
13
19
  Reference code as `path:line`.
@@ -47,6 +53,18 @@ Success criteria carry no IDs.
47
53
  Write one entry per choice: the choice, the reason for it, and the alternatives the work rejected with the reason for each.
48
54
  The research stage produces the comparison behind a decision, and the spec records its outcome.
49
55
 
56
+ **Add a `Themes and devices` section** to every piece of user-facing work.
57
+ It holds the two facts the interview settled about the application the work is in: which themes it draws in - dark, light, or both - and which devices it is laid out for - desktop only, responsive, or mobile-first.
58
+ Write one line each, with what the code gives beside the answer where the two differ.
59
+ The UI mocks stage reads this section by name, so head it exactly this way.
60
+
61
+ ```markdown
62
+ ## Themes and devices
63
+
64
+ - Themes: both - every screen in this application draws in dark and light today.
65
+ - Devices: responsive - one layout from a phone width up.
66
+ ```
67
+
50
68
  **Add a `Mocks` section** when the UI mocks stage runs.
51
69
  Write one line per screen: its id, its title, and the path to its page relative to `SPEC.md`.
52
70
  After the user approves the mocks, add a line `Approved: YYYY-MM-DD`.
@@ -82,8 +100,8 @@ Either way, keep it self-contained: no external image, and no script.
82
100
  1. At the top of the spec, close to as written:
83
101
 
84
102
  > **For the implementing agent - read this first.** This spec was written during planning with limited knowledge of the code.
85
- > Before building anything, review it carefully against the actual codebase and **plan first** (in plan mode, where your environment has one).
86
- > Treat nothing here as settled: if the spec turns out misaligned with the code, or you see a better path, **push back and raise it** rather than building something you can tell is off.
103
+ > Before building anything, review it carefully against the actual codebase and **plan first** (in plan mode, where the agent's environment has one).
104
+ > Treat nothing here as settled: if the spec turns out misaligned with the code, or a better path shows itself, **push back and raise it** rather than building something the agent can tell is off.
87
105
 
88
106
  2. Inside a solution sketch, where the spec has one, close to as written:
89
107
 
@@ -115,7 +133,9 @@ Keep every fact, every requirement ID, every acceptance criterion, and every lab
115
133
  An ID never changes, because a phase and a finding point at it.
116
134
 
117
135
  **One round of review follows every rewrite.**
118
- Run one fresh reviewer, once, scoped to the rewrite alone:
136
+ Run one fresh reviewer, once, scoped to the rewrite alone.
137
+ Where your environment gives you no sub-agent, read the rewrite against the copies yourself, in one pass with nothing else in it, and say in the message after it that the reviewer was you.
138
+ The two points below are what that pass covers either way:
119
139
 
120
140
  - Completeness against the copies in `.rewrite/`, so no meaning was lost. Give the reviewer both paths and let it read them itself. Never summarize the old text for it: a summary of yours is what it is there to check.
121
141
  - The repo's own writing rules.