@pmelab/gtd 51.0.1 → 52.0.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 (62) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +41 -38
  3. package/dist/chunks/{reserved-CUkk9XgL.mjs → reserved-D0MKVFFa.mjs} +28 -34
  4. package/dist/chunks/{review-BaCXlIT2.mjs → review-ZzUQH1KZ.mjs} +11 -9
  5. package/dist/chunks/{steering-DtUVUz9l.mjs → steering-CLhu8C7q.mjs} +262 -52
  6. package/dist/chunks/{tail-CX6Pdsql.mjs → tail-I1-vVq0P.mjs} +1 -1
  7. package/dist/gtd.bundle.mjs +198 -43
  8. package/dist/steering.mjs +2 -2
  9. package/dist/testkit.mjs +1 -1
  10. package/dist/web/main.css +1 -1
  11. package/dist/web/main.js +510 -147
  12. package/dist/workflow-kit.mjs +1 -1
  13. package/dist/workflows/cleanup.mjs +2 -2
  14. package/dist/workflows/feature.mjs +181 -222
  15. package/dist/workflows/fix.mjs +3 -3
  16. package/dist/workflows/review.mjs +3 -3
  17. package/dist/workflows/rollout.mjs +1 -1
  18. package/dist/workflows.mjs +478 -313
  19. package/package.json +1 -1
  20. package/src/steering/FORMATS.md +4 -1
  21. package/src/steering/SteeringFormat.ts +7 -1
  22. package/src/steering/contract.test.ts +2 -1
  23. package/src/steering/fixtures/review/sectioned.md +31 -0
  24. package/src/steering/fixtures/review/sectioned.read.json +119 -0
  25. package/src/steering/index.ts +4 -0
  26. package/src/steering/qa.ts +1 -1
  27. package/src/steering/review.test.ts +270 -4
  28. package/src/steering/review.ts +328 -69
  29. package/src/workflows/feature/criteria.test.ts +39 -1
  30. package/src/workflows/feature/criteria.ts +21 -7
  31. package/src/workflows/feature/fast-path.feature +1 -6
  32. package/src/workflows/feature/feature.ts +1 -2
  33. package/src/workflows/feature/flag-mode.feature +1 -6
  34. package/src/workflows/feature/green.ts +22 -0
  35. package/src/workflows/feature/hands-on-skip.feature +344 -0
  36. package/src/workflows/feature/lens-models.feature +0 -4
  37. package/src/workflows/feature/lens-review.feature +6 -8
  38. package/src/workflows/feature/one-step-land.feature +1 -6
  39. package/src/workflows/feature/prototype-rounds.feature +1 -1
  40. package/src/workflows/feature/prototype.feature +10 -9
  41. package/src/workflows/feature/prototype.ts +48 -17
  42. package/src/workflows/feature/refactor-absorbs.feature +3 -8
  43. package/src/workflows/feature/refactor-first.feature +3 -8
  44. package/src/workflows/feature/refactor-rebuild.feature +7 -12
  45. package/src/workflows/feature/refactor-review.feature +52 -72
  46. package/src/workflows/feature/review-answers.feature +90 -5
  47. package/src/workflows/feature/review-gate.feature +11 -53
  48. package/src/workflows/feature/reviewer-walkthrough.feature +29 -12
  49. package/src/workflows/feature/seam-rejection.feature +1 -6
  50. package/src/workflows/feature/seam.feature +1 -6
  51. package/src/workflows/feature/seam.test.ts +1 -1
  52. package/src/workflows/feature/seam.ts +2 -3
  53. package/src/workflows/feature/severity-budget.feature +7 -7
  54. package/src/workflows/feature/severity-sorted-review.feature +50 -54
  55. package/src/workflows/feature/slice-findings.feature +5 -15
  56. package/src/workflows/feature/slicing.feature +4 -24
  57. package/src/workflows/feature/standards.feature +0 -4
  58. package/src/workflows/shared/review.ts +26 -6
  59. package/src/workflows/shared/text.test.ts +45 -11
  60. package/src/workflows/shared/text.ts +45 -38
  61. package/src/workflows/feature/coverage.feature +0 -165
  62. package/src/workflows/feature/coverage.ts +0 -120
@@ -54,10 +54,6 @@ Feature: every note in the review is answered with one tick
54
54
  And step "implement.applying" runs its script
55
55
  And step "implement.health.check" changes nothing
56
56
  And step "implement.closing" runs its script
57
- And judge step "implement.coverage" answers:
58
- """
59
- [{"id":"AC-1","answer":"yes","p":0.9}]
60
- """
61
57
  And step "build.quality.correctness.reviewing" writes ".gtd/QUALITY.md" with:
62
58
  """
63
59
  # Quality
@@ -125,7 +121,9 @@ Feature: every note in the review is answered with one tick
125
121
  Then the process rests at "build.review.await-review"
126
122
  And ".gtd/REVIEW.md" contains:
127
123
  """
128
- ## AC-1 ignores floating point
124
+ ## Findings
125
+
126
+ ### AC-1 ignores floating point
129
127
 
130
128
  _critical: judge unsure_
131
129
 
@@ -233,3 +231,90 @@ Feature: every note in the review is answered with one tick
233
231
  And the text "- [ ] fix as suggested" in ".gtd/REVIEW.md" is replaced with ""
234
232
  And the text "Tick exactly one:" in ".gtd/REVIEW.md" is replaced with ""
235
233
  Then landing is refused with "its answer boxes were deleted"
234
+
235
+ Scenario: a review still in the flat layout, every chunk a `## `, is answered by its ticks
236
+ Given judge step "build.review.standards.judge" answers:
237
+ """
238
+ [{"id":"standard-1","answer":"no","p":0.9}]
239
+ """
240
+ When the process is driven
241
+ Then the process rests at "build.review.await-review"
242
+ Given a file ".gtd/REVIEW.md" with:
243
+ """
244
+ # Review: abc1234
245
+
246
+ <!-- base: 0000000 -->
247
+
248
+ ## AC-1 ignores floating point
249
+
250
+ _critical: judge unsure_
251
+
252
+ Should subtract round? The criterion does not say.
253
+
254
+ In the code:
255
+
256
+ - [ ] ./src/calc.ts#2-2 — returns the raw difference
257
+
258
+ Tick exactly one:
259
+
260
+ - [ ] fix as suggested
261
+ - [x] won't fix
262
+ - [ ] _your answer_
263
+
264
+ ## Subtract
265
+
266
+ - [ ] ./src/calc.ts#2-2 — subtract(a, b)
267
+ """
268
+ When gtd lands
269
+ And the process is driven
270
+ Then the process rests at "idle"
271
+ And the commit "gtd(human): build.review.await-review → build.review.standards.judge" has a body containing "Gtd-Mark: wontfix=AC-1 ignores floating point"
272
+ And no commit body contains "build.review.triage"
273
+
274
+ Scenario: boxes ticked in the walkthrough answer nothing
275
+ Given judge step "build.review.standards.judge" answers:
276
+ """
277
+ [{"id":"standard-1","answer":"no","p":0.9}]
278
+ """
279
+ When the process is driven
280
+ Then the process rests at "build.review.await-review"
281
+ Given a file ".gtd/REVIEW.md" with:
282
+ """
283
+ # Review: abc1234
284
+
285
+ <!-- base: 0000000 -->
286
+
287
+ ## Findings
288
+
289
+ ### AC-1 ignores floating point
290
+
291
+ _critical: judge unsure_
292
+
293
+ Should subtract round? The criterion does not say.
294
+
295
+ In the code:
296
+
297
+ - [ ] ./src/calc.ts#2-2 — returns the raw difference
298
+
299
+ Tick exactly one:
300
+
301
+ - [ ] fix as suggested
302
+ - [x] won't fix
303
+ - [ ] _your answer_
304
+
305
+ ## Walkthrough
306
+
307
+ ### Subtract
308
+
309
+ - [ ] ./src/calc.ts#2-2 — subtract(a, b)
310
+
311
+ Tick exactly one:
312
+
313
+ - [x] fix as suggested
314
+ - [ ] won't fix
315
+ - [ ] _your answer_
316
+ """
317
+ When gtd lands
318
+ And the process is driven
319
+ Then the process rests at "idle"
320
+ And no commit body contains "build.review.fix.nits.fixing"
@@ -4,8 +4,8 @@ Feature: a feature process ends at the human review
4
4
  After the last slice's quality lap the process rests at the review gate,
5
5
  `.gtd/REVIEW.md`. A sign-off ends the process. A note asking for a change in
6
6
  behaviour starts a feedback lap — design, then implement with no new naive
7
- pass or seam judge, the coverage judge over every criterion, the quality lap
8
- — and the review again. Its design keeps a built criterion's ID and numbers
7
+ pass or seam judge, the hands-on test, the quality lap — and the review
8
+ again. Its design keeps a built criterion's ID and numbers
9
9
  new behaviour above every ID handed out.
10
10
 
11
11
  Background:
@@ -54,10 +54,6 @@ Feature: a feature process ends at the human review
54
54
  And step "implement.applying" runs its script
55
55
  And step "implement.health.check" changes nothing
56
56
  And step "implement.closing" runs its script
57
- And judge step "implement.coverage" answers:
58
- """
59
- [{"id":"AC-1","answer":"yes","p":0.9}]
60
- """
61
57
  And step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
62
58
  """
63
59
  # Review: abc1234
@@ -83,7 +79,7 @@ Feature: a feature process ends at the human review
83
79
  And the resting step's content contains the hash of the commit "feat: add calculator"
84
80
  And the commit subjects end with:
85
81
  """
86
- gtd(judge): implement.coverage → implement.closing
82
+ gtd(check): implement.health.check → implement.closing
87
83
  gtd(check): implement.closing → build.review.reviewing
88
84
  gtd(agent): build.review.reviewing → build.review.ranking
89
85
  gtd(judge): build.review.ranking → build.review.carrying
@@ -99,9 +95,9 @@ Feature: a feature process ends at the human review
99
95
 
100
96
  <!-- base: 0000000 -->
101
97
 
102
- ## calc
98
+ ## Walkthrough
103
99
 
104
- _critical: judge unsure_
100
+ ### calc
105
101
 
106
102
  - [x] ./src/calc.ts#2-2
107
103
  new subtract function
@@ -156,9 +152,9 @@ Feature: a feature process ends at the human review
156
152
 
157
153
  <!-- base: 0000000 -->
158
154
 
159
- ## calc
155
+ ## Walkthrough
160
156
 
161
- _critical: judge unsure_
157
+ ### calc
162
158
 
163
159
  - [ ] ./src/calc.ts#2-2
164
160
  new subtract function[^why]
@@ -176,15 +172,15 @@ Feature: a feature process ends at the human review
176
172
 
177
173
  <!-- base: 0000000 -->
178
174
 
179
- ## calc
175
+ ## Walkthrough
180
176
 
181
- _critical: judge unsure_
177
+ ### calc
182
178
 
183
179
  - [ ] ./src/calc.ts#2-2
184
180
  new subtract function
185
181
  """
186
182
 
187
- Scenario: the lap keeps AC-1, adds AC-2, and covers both before the next review
183
+ Scenario: the lap keeps AC-1, adds AC-2, and builds both before the next review
188
184
  Given step "design.triage" from now on changes nothing
189
185
  And step "design.triage" writes ".gtd/REQUIREMENTS.md" with:
190
186
  """
@@ -211,15 +207,10 @@ Feature: a feature process ends at the human review
211
207
  """
212
208
  it("[AC-2] multiplies", () => {})
213
209
  """
214
- And judge step "implement.coverage" answers:
215
- """
216
- [{"id":"AC-1","answer":"yes","p":0.9},{"id":"AC-2","answer":"yes","p":0.9}]
217
- """
218
210
  When gtd lands
219
211
  And the process is driven
220
212
  Then the process rests at "build.review.await-review"
221
213
  And ".gtd/REQUIREMENTS.md" does not exist
222
- And the commit "gtd(judge): implement.coverage → implement.closing" has a body containing "Gtd-Mark: covers=AC-1"
223
214
  And the commit subjects end with:
224
215
  """
225
216
  gtd(human): build.review.await-review → build.review.closing
@@ -228,8 +219,7 @@ Feature: a feature process ends at the human review
228
219
  gtd(agent): design.triage → design.gate.answer
229
220
  gtd(human): design.gate.answer → implement.building
230
221
  gtd(agent): implement.building → implement.health.check
231
- gtd(check): implement.health.check → implement.coverage
232
- gtd(judge): implement.coverage → implement.closing
222
+ gtd(check): implement.health.check → implement.closing
233
223
  gtd(check): implement.closing → build.review.reviewing
234
224
  gtd(agent): build.review.reviewing → build.review.ranking
235
225
  gtd(judge): build.review.ranking → build.review.carrying
@@ -255,35 +245,3 @@ Feature: a feature process ends at the human review
255
245
  """
256
246
  When gtd lands
257
247
  Then driving the process is refused with "criteria-ids"
258
-
259
- Scenario: the lap holds a new criterion to coverage
260
- Given step "design.triage" from now on changes nothing
261
- And step "design.triage" writes ".gtd/REQUIREMENTS.md" with:
262
- """
263
- # Requirements
264
-
265
- ## Concerns
266
-
267
- ### Multiply
268
-
269
- - `multiply(a, b)` returns `a * b`.
270
-
271
- ## Acceptance Criteria
272
-
273
- - AC-1: subtract(a, b) returns a - b.
274
- - AC-2: multiply(a, b) returns a * b.
275
- """
276
- And step "implement.building" writes "src/calc.ts" with:
277
- """
278
- export const add = (a: number, b: number) => a + b
279
- export const subtract = (a: number, b: number) => a - b
280
- export const multiply = (a: number, b: number) => a * b
281
- """
282
- And judge step "implement.coverage" answers:
283
- """
284
- [{"id":"AC-1","answer":"yes","p":0.9},{"id":"AC-2","answer":"no","p":0.9}]
285
- """
286
- When gtd lands
287
- And the process is driven
288
- Then the process rests at "implement.covering"
289
- And the resting step's content contains "AC-2"
@@ -49,10 +49,6 @@ Feature: a reviewer walks the human through the feature's code
49
49
  And step "implement.applying" runs its script
50
50
  And step "implement.health.check" changes nothing
51
51
  And step "implement.closing" runs its script
52
- And judge step "implement.coverage" answers:
53
- """
54
- [{"id":"AC-1","answer":"yes","p":0.9}]
55
- """
56
52
  And step "build.quality.correctness.reviewing" writes ".gtd/QUALITY.md" with:
57
53
  """
58
54
  # Quality
@@ -96,15 +92,9 @@ Feature: a reviewer walks the human through the feature's code
96
92
  Then the process rests at "build.review.await-review"
97
93
  And ".gtd/REVIEW.md" contains:
98
94
  """
99
- ## Subtract
100
-
101
- _critical: judge unsure_
102
-
103
- The new export.
95
+ ## Findings
104
96
 
105
- - [ ] ./src/calc.ts#2-2 — subtract(a, b)
106
-
107
- ## AC-1 ignores floating point
97
+ ### AC-1 ignores floating point
108
98
 
109
99
  _critical: judge unsure_
110
100
 
@@ -119,6 +109,14 @@ Feature: a reviewer walks the human through the feature's code
119
109
  - [ ] fix as suggested
120
110
  - [ ] won't fix
121
111
  - [ ] _your answer_
112
+
113
+ ## Walkthrough
114
+
115
+ ### Subtract
116
+
117
+ The new export.
118
+
119
+ - [ ] ./src/calc.ts#2-2 — subtract(a, b)
122
120
  """
123
121
  And no commit body contains "build.review.composing"
124
122
  And the commit subjects end with:
@@ -145,6 +143,25 @@ Feature: a reviewer walks the human through the feature's code
145
143
  """
146
144
  Then driving the process is refused with "Subtract — points at no code"
147
145
 
146
+ Scenario: a review the reviewer sorts into sections itself is refused
147
+ Given step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
148
+ """
149
+ # Review: abc1234
150
+
151
+ <!-- base: 0000000 -->
152
+
153
+ ## Walkthrough
154
+
155
+ ### Subtract
156
+
157
+ - [ ] ./src/calc.ts#2-2 — subtract(a, b)
158
+
159
+ ### AC-1 ignores floating point
160
+
161
+ - [ ] ./src/calc.ts#2-2 — returns the raw difference
162
+ """
163
+ Then driving the process is refused with "Walkthrough — gtd sorts the chunks into sections; write `## ` chunks only"
164
+
148
165
  Scenario: a finding the reviewer left out is refused
149
166
  Given step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
150
167
  """
@@ -53,10 +53,6 @@ Feature: rejected naive passes walk one fixed path through the steer gate to the
53
53
  """
54
54
  And step "implement.health.check" changes nothing
55
55
  And step "implement.closing" runs its script
56
- And judge step "implement.coverage" answers:
57
- """
58
- [{"id":"AC-1","answer":"yes","p":0.9}]
59
- """
60
56
  When the process is driven
61
57
  Then the process rests at "seam.judge"
62
58
 
@@ -123,8 +119,7 @@ Feature: rejected naive passes walk one fixed path through the steer gate to the
123
119
  gtd(check): seam.check → seam.judge
124
120
  gtd(judge): seam.judge → implement.applying
125
121
  gtd(check): implement.applying → implement.health.check
126
- gtd(check): implement.health.check → implement.coverage
127
- gtd(judge): implement.coverage → implement.closing
122
+ gtd(check): implement.health.check → implement.closing
128
123
  gtd(check): implement.closing → build.review.reviewing
129
124
  """
130
125
  And the commit "gtd(human): idle → unwind" has a body containing "Gtd-Var: flag_risk_tier=0"
@@ -148,10 +148,6 @@ Feature: the naive pass and seam judge decide how a feature is built
148
148
  And step "implement.applying" runs its script
149
149
  And step "implement.health.check" changes nothing
150
150
  And step "implement.closing" runs its script
151
- And judge step "implement.coverage" answers:
152
- """
153
- [{"id":"AC-1","answer":"yes","p":0.9}]
154
- """
155
151
  When the process is driven
156
152
  Then the process rests at "build.review.reviewing"
157
153
  And "src/calc.ts" contains "subtract"
@@ -159,8 +155,7 @@ Feature: the naive pass and seam judge decide how a feature is built
159
155
  """
160
156
  gtd(judge): seam.judge → implement.applying
161
157
  gtd(check): implement.applying → implement.health.check
162
- gtd(check): implement.health.check → implement.coverage
163
- gtd(judge): implement.coverage → implement.closing
158
+ gtd(check): implement.health.check → implement.closing
164
159
  gtd(check): implement.closing → build.review.reviewing
165
160
  """
166
161
  And ".gtd/REQUIREMENTS.md" does not exist
@@ -500,7 +500,7 @@ describe("implement", () => {
500
500
  lastOptions = undefined
501
501
  installContext(
502
502
  fixtureContext(
503
- // The hands-on test after coverage has its own scenarios.
503
+ // The hands-on test has its own scenarios.
504
504
  { vars: { prototypeRounds: "0" } },
505
505
  {
506
506
  step: (request: StepRequest) => {
@@ -37,7 +37,7 @@ import {
37
37
  } from "../shared/steps.js"
38
38
  import * as t from "../shared/text.js"
39
39
  import { defaults } from "../shared/vars.js"
40
- import { green, requireCoverage } from "./coverage.js"
40
+ import { green } from "./green.js"
41
41
  import { prototypeTest } from "./prototype.js"
42
42
  import {
43
43
  criterionIds,
@@ -289,7 +289,7 @@ export interface ImplementOptions {
289
289
  readonly rebuild?: t.Rebuild | undefined
290
290
  /** The criteria this slice builds, when the change has more than one slice. */
291
291
  readonly slice?: CriteriaSlice | undefined
292
- /** Where the slice began: the coverage judge reads only the tests changed since. */
292
+ /** @deprecated Ignored since the coverage judge is gone. */
293
293
  readonly base?: string | undefined
294
294
  /** Not the last slice: `.gtd/REQUIREMENTS.md` and `.gtd/SLICES.md` stay for the next one. */
295
295
  readonly more?: boolean | (() => boolean) | undefined
@@ -385,7 +385,6 @@ export const implementing = (options: ImplementOptions): Promise<readonly string
385
385
  const keepsTests =
386
386
  built && acceptance !== undefined ? () => requireAcceptanceKept(acceptance) : undefined
387
387
  await green(keepsTests)
388
- await requireCoverage(options.base, options.slice)
389
388
  await prototypeTest(options.slice, keepsTests)
390
389
  const ids = criterionIds(read(REQUIREMENTS) ?? "")
391
390
  await closing(moreToBuild(options.more))
@@ -46,10 +46,6 @@ Feature: the review's ranking is batched to the judge's budget
46
46
  And step "implement.applying" runs its script
47
47
  And step "implement.health.check" changes nothing
48
48
  And step "implement.closing" runs its script
49
- And judge step "implement.coverage" answers:
50
- """
51
- [{"id":"AC-1","answer":"yes","p":0.9}]
52
- """
53
49
  And step "build.quality.correctness.reviewing" writes ".gtd/QUALITY.md" with:
54
50
  """
55
51
  # Quality
@@ -93,15 +89,19 @@ Feature: the review's ranking is batched to the judge's budget
93
89
  Then the process rests at "build.review.await-review"
94
90
  And ".gtd/REVIEW.md" contains:
95
91
  """
96
- ## AC-1 ignores floating point
92
+ ## Findings
93
+
94
+ ### AC-1 ignores floating point
97
95
 
98
96
  _critical: judge unsure_
99
97
  """
100
98
  And ".gtd/REVIEW.md" contains:
101
99
  """
102
- ## Subtract
100
+ ## Walkthrough
101
+
102
+ ### Subtract
103
103
 
104
- _could_
104
+ - [ ] ./src/calc.ts#2-2 — subtract(a, b)
105
105
  """
106
106
  And the commit subjects end with:
107
107
  """
@@ -1,12 +1,13 @@
1
1
  @inmem
2
- Feature: the final review lists what matters most first
2
+ Feature: the final review lists the findings that matter most first
3
3
 
4
- Before the review rests, the judge rates every chunk the reviewer wrote — a
5
- walkthrough chunk or a carried quality finding — on the same four questions
6
- as a human's note (`build.review.ranking`): critical (security, or a one-way
7
- door), should (a contract, or a new concept), could. The review lists them
8
- in that order, security before one-way doors, each led by its tier and
9
- reason. A chunk the judge cannot rate is critical, so it is shown first.
4
+ Before the review rests, the judge rates every chunk the reviewer wrote on
5
+ the same four questions as a human's note (`build.review.ranking`): critical
6
+ (security, or a one-way door), should (a contract, or a new concept), could.
7
+ The quality findings go under `## Findings` in that order, security before
8
+ one-way doors, each led by its tier and reason; a finding the judge cannot
9
+ rate is critical. The walkthrough goes under `## Walkthrough` in the
10
+ reviewer's order, with no tier.
10
11
 
11
12
  Background:
12
13
  Given the shipped workflows, as gtd install scaffolds them
@@ -48,10 +49,6 @@ Feature: the final review lists what matters most first
48
49
  And step "implement.applying" runs its script
49
50
  And step "implement.health.check" changes nothing
50
51
  And step "implement.closing" runs its script
51
- And judge step "implement.coverage" answers:
52
- """
53
- [{"id":"AC-1","answer":"yes","p":0.9}]
54
- """
55
52
  And step "build.quality.correctness.reviewing" writes ".gtd/QUALITY.md" with:
56
53
  """
57
54
  # Quality
@@ -59,16 +56,20 @@ Feature: the final review lists what matters most first
59
56
  ## AC-1 ignores floating point
60
57
 
61
58
  Should subtract round? The criterion does not say.
59
+
60
+ ## Token in logs
61
+
62
+ The caller's token reaches the log.
62
63
  """
63
64
  And judge step "build.quality.triage" answers:
64
65
  """
65
- [{"id":"Q1","answer":"design","p":0.9}]
66
+ [{"id":"Q1","answer":"design","p":0.9},{"id":"Q2","answer":"design","p":0.9}]
66
67
  """
67
68
  And step "build.quality.sorting" runs its script
68
69
  And step "build.quality.closing" runs its script
69
70
  And step "build.review.carrying" runs its script
70
71
 
71
- Scenario: security and one-way doors come first, a carried finding sorted among the rest
72
+ Scenario: findings are sorted by tier, the walkthrough kept in the reviewer's order
72
73
  Given step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
73
74
  """
74
75
  # Review: abc1234
@@ -81,39 +82,41 @@ Feature: the final review lists what matters most first
81
82
 
82
83
  - [ ] ./src/calc.ts#2-2 — subtract(a, b)
83
84
 
84
- ## Session token
85
-
86
- - [ ] ./src/calc.ts#1-1 — reads the caller's token
87
-
88
85
  ## AC-1 ignores floating point
89
86
 
90
87
  - [ ] ./src/calc.ts#2-2 — returns the raw difference
91
88
 
92
- ## Saved format
89
+ ## Session token
90
+
91
+ - [ ] ./src/calc.ts#1-1 — reads the caller's token
92
+
93
+ ## Token in logs
93
94
 
94
- - [ ] ./src/calc.ts#1-2 — what callers persist
95
+ - [ ] ./src/calc.ts#1-1 — where it is logged
95
96
  """
96
97
  And judge step "build.review.ranking" answers:
97
98
  """
98
- [{"id":"C1.security","answer":"no","p":0.9},{"id":"C1.reversibility","answer":"two-way","p":0.9},{"id":"C1.blastRadius","answer":"local","p":0.9},{"id":"C1.newConcept","answer":"no","p":0.9},{"id":"C2.security","answer":"yes","p":0.9},{"id":"C2.reversibility","answer":"two-way","p":0.9},{"id":"C2.blastRadius","answer":"module","p":0.9},{"id":"C2.newConcept","answer":"no","p":0.9},{"id":"C3.security","answer":"no","p":0.9},{"id":"C3.reversibility","answer":"two-way","p":0.9},{"id":"C3.blastRadius","answer":"contract","p":0.9},{"id":"C3.newConcept","answer":"no","p":0.9},{"id":"C4.security","answer":"no","p":0.9},{"id":"C4.reversibility","answer":"one-way","p":0.9},{"id":"C4.blastRadius","answer":"contract","p":0.9},{"id":"C4.newConcept","answer":"no","p":0.9}]
99
+ [{"id":"C1.security","answer":"no","p":0.9},{"id":"C1.reversibility","answer":"two-way","p":0.9},{"id":"C1.blastRadius","answer":"local","p":0.9},{"id":"C1.newConcept","answer":"no","p":0.9},{"id":"C2.security","answer":"no","p":0.9},{"id":"C2.reversibility","answer":"two-way","p":0.9},{"id":"C2.blastRadius","answer":"contract","p":0.9},{"id":"C2.newConcept","answer":"no","p":0.9},{"id":"C3.security","answer":"yes","p":0.9},{"id":"C3.reversibility","answer":"two-way","p":0.9},{"id":"C3.blastRadius","answer":"module","p":0.9},{"id":"C3.newConcept","answer":"no","p":0.9},{"id":"C4.security","answer":"no","p":0.9},{"id":"C4.reversibility","answer":"one-way","p":0.9},{"id":"C4.blastRadius","answer":"contract","p":0.9},{"id":"C4.newConcept","answer":"no","p":0.9}]
99
100
  """
100
101
  When the process is driven
101
102
  Then the process rests at "build.review.await-review"
102
103
  And ".gtd/REVIEW.md" contains:
103
104
  """
104
- ## Session token
105
-
106
- _critical: security_
105
+ <!-- base: 0000000 -->
107
106
 
108
- - [ ] ./src/calc.ts#1-1 — reads the caller's token
107
+ ## Findings
109
108
 
110
- ## Saved format
109
+ ### Token in logs
111
110
 
112
111
  _critical: one-way door_
113
112
 
114
- - [ ] ./src/calc.ts#1-2 — what callers persist
113
+ The caller's token reaches the log.
114
+ """
115
+ And ".gtd/REVIEW.md" contains:
116
+ """
117
+ - [ ] _your answer_
115
118
 
116
- ## AC-1 ignores floating point
119
+ ### AC-1 ignores floating point
117
120
 
118
121
  _should: contract_
119
122
 
@@ -123,12 +126,19 @@ Feature: the final review lists what matters most first
123
126
  """
124
127
  - [ ] _your answer_
125
128
 
126
- ## Subtract
129
+ ## Walkthrough
127
130
 
128
- _could_
131
+ ### Subtract
129
132
 
130
133
  The new export.
134
+
135
+ - [ ] ./src/calc.ts#2-2 — subtract(a, b)
136
+
137
+ ### Session token
138
+
139
+ - [ ] ./src/calc.ts#1-1 — reads the caller's token
131
140
  """
141
+ And ".gtd/REVIEW.md" does not contain "_critical: security_"
132
142
  And the commit "gtd(judge): build.review.ranking → build.review.carrying" has a body containing "Gtd-Judge:"
133
143
  And the commit subjects end with:
134
144
  """
@@ -137,7 +147,7 @@ Feature: the final review lists what matters most first
137
147
  gtd(check): build.review.carrying → build.review.await-review
138
148
  """
139
149
 
140
- Scenario: a chunk the judge is unsure about is listed as critical
150
+ Scenario: a finding the judge is unsure about is listed as critical
141
151
  Given step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
142
152
  """
143
153
  # Review: abc1234
@@ -150,49 +160,35 @@ Feature: the final review lists what matters most first
150
160
 
151
161
  - [ ] ./src/calc.ts#2-2 — subtract(a, b)
152
162
 
153
- ## Session token
154
-
155
- - [ ] ./src/calc.ts#1-1 — reads the caller's token
156
-
157
163
  ## AC-1 ignores floating point
158
164
 
159
165
  - [ ] ./src/calc.ts#2-2 — returns the raw difference
160
166
 
161
- ## Saved format
167
+ ## Session token
162
168
 
163
- - [ ] ./src/calc.ts#1-2 — what callers persist
169
+ - [ ] ./src/calc.ts#1-1 — reads the caller's token
170
+
171
+ ## Token in logs
172
+
173
+ - [ ] ./src/calc.ts#1-1 — where it is logged
164
174
  """
165
175
  And judge step "build.review.ranking" answers:
166
176
  """
167
- [{"id":"C1.security","answer":"no","p":0.9},{"id":"C1.reversibility","answer":"two-way","p":0.9},{"id":"C1.blastRadius","answer":"local","p":0.9},{"id":"C1.newConcept","answer":"no","p":0.9},{"id":"C2.security","answer":"no","p":0.4},{"id":"C2.reversibility","answer":"two-way","p":0.9},{"id":"C2.blastRadius","answer":"local","p":0.9},{"id":"C2.newConcept","answer":"no","p":0.9},{"id":"C3.security","answer":"no","p":0.9},{"id":"C3.reversibility","answer":"two-way","p":0.9},{"id":"C3.blastRadius","answer":"contract","p":0.9},{"id":"C3.newConcept","answer":"no","p":0.9},{"id":"C4.security","answer":"no","p":0.9},{"id":"C4.reversibility","answer":"two-way","p":0.9},{"id":"C4.blastRadius","answer":"local","p":0.9},{"id":"C4.newConcept","answer":"yes","p":0.9}]
177
+ [{"id":"C1.security","answer":"no","p":0.9},{"id":"C1.reversibility","answer":"two-way","p":0.9},{"id":"C1.blastRadius","answer":"local","p":0.9},{"id":"C1.newConcept","answer":"no","p":0.9},{"id":"C2.security","answer":"no","p":0.4},{"id":"C2.reversibility","answer":"two-way","p":0.9},{"id":"C2.blastRadius","answer":"local","p":0.9},{"id":"C2.newConcept","answer":"no","p":0.9},{"id":"C3.security","answer":"yes","p":0.9},{"id":"C3.reversibility","answer":"two-way","p":0.9},{"id":"C3.blastRadius","answer":"local","p":0.9},{"id":"C3.newConcept","answer":"no","p":0.9},{"id":"C4.security","answer":"no","p":0.9},{"id":"C4.reversibility","answer":"two-way","p":0.9},{"id":"C4.blastRadius","answer":"local","p":0.9},{"id":"C4.newConcept","answer":"yes","p":0.9}]
168
178
  """
169
179
  When the process is driven
170
180
  Then the process rests at "build.review.await-review"
171
181
  And ".gtd/REVIEW.md" contains:
172
182
  """
173
- # Review: abc1234
183
+ ## Findings
174
184
 
175
- <!-- base: 0000000 -->
176
-
177
- ## Session token
185
+ ### AC-1 ignores floating point
178
186
 
179
187
  _critical: judge unsure_
180
188
  """
181
189
  And ".gtd/REVIEW.md" contains:
182
190
  """
183
- ## AC-1 ignores floating point
184
-
185
- _should: contract_
186
- """
187
- And ".gtd/REVIEW.md" contains:
188
- """
189
- ## Saved format
191
+ ### Token in logs
190
192
 
191
193
  _should: new concept_
192
194
  """
193
- And ".gtd/REVIEW.md" contains:
194
- """
195
- ## Subtract
196
-
197
- _could_
198
- """