@pmelab/gtd 32.1.0 → 34.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 (36) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +66 -53
  3. package/dist/chunks/{reserved-2fV0mj14.mjs → reserved-BcJgt5_R.mjs} +79 -12
  4. package/dist/chunks/{tail-BynhCfuv.mjs → tail-CM_fa93v.mjs} +1 -1
  5. package/dist/testkit.mjs +2 -2
  6. package/dist/workflows/cleanup.mjs +2 -2
  7. package/dist/workflows/feature.mjs +174 -40
  8. package/dist/workflows/fix.mjs +2 -2
  9. package/dist/workflows/review.mjs +2 -2
  10. package/dist/workflows/rollout.mjs +1 -1
  11. package/dist/workflows.mjs +249 -48
  12. package/package.json +1 -1
  13. package/skills/authoring/SKILL.md +2 -2
  14. package/src/testkit/steps.ts +4 -0
  15. package/src/workflows/feature/acceptance-criteria.feature +8 -0
  16. package/src/workflows/feature/fast-path.feature +11 -35
  17. package/src/workflows/feature/feature.test.ts +9 -100
  18. package/src/workflows/feature/feature.ts +29 -16
  19. package/src/workflows/feature/flag-mode.feature +2 -91
  20. package/src/workflows/feature/naive-acceptance.feature +140 -0
  21. package/src/workflows/feature/one-step-land.feature +11 -34
  22. package/src/workflows/feature/quality-unresolved.feature +96 -0
  23. package/src/workflows/feature/refactor-absorbs.feature +17 -25
  24. package/src/workflows/feature/refactor-first.feature +11 -35
  25. package/src/workflows/feature/refactor-lens-models.feature +6 -1
  26. package/src/workflows/feature/refactor-review.feature +67 -360
  27. package/src/workflows/feature/refactor.ts +4 -3
  28. package/src/workflows/feature/risk-tier.feature +10 -0
  29. package/src/workflows/feature/seam-rejection.feature +20 -37
  30. package/src/workflows/feature/seam.feature +66 -113
  31. package/src/workflows/feature/seam.test.ts +173 -3
  32. package/src/workflows/feature/seam.ts +196 -31
  33. package/src/workflows/review/review-door.feature +108 -0
  34. package/src/workflows/shared/tail.ts +2 -2
  35. package/src/workflows/shared/text.test.ts +40 -0
  36. package/src/workflows/shared/text.ts +110 -16
@@ -3,8 +3,8 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
3
3
 
4
4
  After a refactor-first judgment the refactor is built, quality-lapped and
5
5
  reviewed in its own slice. Review edits re-run the refactor, never the design;
6
- the feature review that follows covers only what came after the refactor's
7
- sign-off. The flags are pinned so the per-flag test runs never move it off
6
+ the feature slice that follows is quality-lapped from the refactor's
7
+ sign-off, with no feature review. The flags are pinned so the per-flag test runs never move it off
8
8
  its path.
9
9
 
10
10
  Background:
@@ -52,6 +52,11 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
52
52
  - AC-1: the change behaves as described.
53
53
  """
54
54
  And step "design.gate.answer" changes nothing
55
+ And step "seam.check" changes nothing
56
+ And step "seam.naive" writes "src/acceptance.test.ts" with:
57
+ """
58
+ it("[AC-1] holds", () => {})
59
+ """
55
60
  And step "seam.naive" writes "src/calc.ts" with:
56
61
  """
57
62
  export const add = (a: number, b: number) => a + b
@@ -136,6 +141,11 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
136
141
  - AC-1: the change behaves as described.
137
142
  """
138
143
  And step "design.gate.answer" changes nothing
144
+ And step "seam.check" changes nothing
145
+ And step "seam.naive" writes "src/acceptance.test.ts" with:
146
+ """
147
+ it("[AC-1] holds", () => {})
148
+ """
139
149
  And step "seam.naive" writes "src/calc.ts" with:
140
150
  """
141
151
  export const add = (a: number, b: number) => a + b
@@ -219,6 +229,11 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
219
229
  - AC-1: the change behaves as described.
220
230
  """
221
231
  And step "design.gate.answer" changes nothing
232
+ And step "seam.check" changes nothing
233
+ And step "seam.naive" writes "src/acceptance.test.ts" with:
234
+ """
235
+ it("[AC-1] holds", () => {})
236
+ """
222
237
  And step "seam.naive" writes "src/calc.ts" with:
223
238
  """
224
239
  export const add = (a: number, b: number) => a + b
@@ -322,7 +337,7 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
322
337
  gtd(agent): refactor.build.review.reviewing → refactor.build.review.await-review
323
338
  """
324
339
 
325
- Scenario: the refactor review says the whole refactor on its second round, the feature's feedback review only what is new
340
+ Scenario: the refactor review says the whole refactor on its second round
326
341
  Given step "refactor.build.review.reviewing" is prompted with "it covers the whole refactor since it started, on every round"
327
342
  And step "implement.building" writes "src/calc.ts" with:
328
343
  """
@@ -332,17 +347,6 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
332
347
  """
333
348
  And step "implement.health.check" changes nothing
334
349
  And step "implement.closing" runs its script
335
- And step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
336
- """
337
- # Review: abc1234
338
-
339
- <!-- base: 0000000 -->
340
-
341
- ## calc
342
-
343
- - [ ] ./src/calc.ts#1-3
344
- subtract built on the shared op
345
- """
346
350
  When the process is driven
347
351
  Then the process rests at "refactor.build.review.await-review"
348
352
  Given a file ".gtd/REVIEW.md" with:
@@ -404,79 +408,7 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
404
408
  Then the process rests at "refactor.build.review.await-review"
405
409
  When gtd lands
406
410
  And the process is driven
407
- Then the process rests at "build.review.await-review"
408
- Given a file ".gtd/REVIEW.md" with:
409
- """
410
- # Review: abc1234
411
-
412
- <!-- base: 0000000 -->
413
-
414
- ## calc
415
-
416
- - [ ] ./src/calc.ts#1-3
417
- subtract built on the shared op[^m]
418
-
419
- [^m]:
420
- - H: also export multiply
421
- """
422
- And step "build.review.collecting" writes ".gtd/REQUIREMENTS.md" with:
423
- """
424
- # Requirements
425
-
426
- - multiply
427
- """
428
- And step "build.review.collecting" writes ".gtd/REVIEW.md" with:
429
- """
430
- # Review: abc1234
431
-
432
- <!-- base: 0000000 -->
433
-
434
- ## calc
435
-
436
- - [ ] ./src/calc.ts#1-3
437
- subtract built on the shared op[^m]
438
-
439
- [^m]:
440
- - H: also export multiply
441
- - A: noted.
442
- """
443
- When gtd lands
444
- And the process is driven
445
- Then the process rests at "build.review.await-review"
446
- Given a file ".gtd/REVIEW.md" with:
447
- """
448
- # Review: abc1234
449
-
450
- <!-- base: 0000000 -->
451
-
452
- ## calc
453
-
454
- - [ ] ./src/calc.ts#1-3
455
- subtract built on the shared op
456
- """
457
- And step "build.review.closing" runs its script
458
- And step "re-unwind" runs its script
459
- And step "design.triage" writes ".gtd/REQUIREMENTS.md" with:
460
- """
461
- # Requirements
462
-
463
- - multiply, designed
464
-
465
- ## Acceptance Criteria
466
-
467
- - AC-1: the change behaves as described.
468
- """
469
- And step "implement.building" writes "src/calc.ts" with:
470
- """
471
- export const op = (a: number, b: number, sign: number) => a + sign * b
472
- export const add = (a: number, b: number) => op(a, b, 1)
473
- export const subtract = (a: number, b: number) => op(a, b, -1)
474
- export const multiply = (a: number, b: number) => a * b
475
- """
476
- And step "build.review.reviewing" is prompted with "it covers only what is new since the previous review"
477
- When gtd lands
478
- And the process is driven
479
- Then the process rests at "build.review.await-review"
411
+ Then the process rests at "idle"
480
412
 
481
413
  Scenario: a question answered at the refactor review reaches the re-derived package as ### Answered Questions
482
414
  When the process is driven
@@ -704,17 +636,6 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
704
636
  """
705
637
  And step "implement.health.check" changes nothing
706
638
  And step "implement.closing" runs its script
707
- And step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
708
- """
709
- # Review: abc1234
710
-
711
- <!-- base: 0000000 -->
712
-
713
- ## calc
714
-
715
- - [ ] ./src/calc.ts#1-3
716
- subtract built on the shared op
717
- """
718
639
  When the process is driven
719
640
  Then the process rests at "refactor.build.review.await-review"
720
641
  Given a file ".gtd/REVIEW.md" with:
@@ -778,7 +699,8 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
778
699
  """
779
700
  When gtd lands
780
701
  And the process is driven
781
- Then the process rests at "build.review.await-review"
702
+ Then the process rests at "idle"
703
+ And "src/calc.ts" contains "subtract"
782
704
 
783
705
  Scenario: a praise-only one-shot footnote signs off and the feature slice follows
784
706
  Given step "implement.building" writes "src/calc.ts" with:
@@ -789,17 +711,6 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
789
711
  """
790
712
  And step "implement.health.check" changes nothing
791
713
  And step "implement.closing" runs its script
792
- And step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
793
- """
794
- # Review: abc1234
795
-
796
- <!-- base: 0000000 -->
797
-
798
- ## calc
799
-
800
- - [ ] ./src/calc.ts#1-3
801
- subtract built on the shared op
802
- """
803
714
  When the process is driven
804
715
  Then the process rests at "refactor.build.review.await-review"
805
716
  Given a file ".gtd/REVIEW.md" with:
@@ -822,7 +733,8 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
822
733
  """
823
734
  When gtd lands
824
735
  And the process is driven
825
- Then the process rests at "build.review.await-review"
736
+ Then the process rests at "idle"
737
+ And "src/calc.ts" contains "subtract"
826
738
 
827
739
  Scenario: a one-shot footnote judged edit that collecting leaves out refuses naming its anchor
828
740
  When the process is driven
@@ -1061,17 +973,6 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
1061
973
  """
1062
974
  And step "implement.health.check" changes nothing
1063
975
  And step "implement.closing" runs its script
1064
- And step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
1065
- """
1066
- # Review: abc1234
1067
-
1068
- <!-- base: 0000000 -->
1069
-
1070
- ## calc
1071
-
1072
- - [ ] ./src/calc.ts#1-3
1073
- subtract built on the shared op
1074
- """
1075
976
  When the process is driven
1076
977
  Then the process rests at "refactor.build.review.await-review"
1077
978
  Given a file ".gtd/REVIEW.md" with:
@@ -1139,7 +1040,8 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
1139
1040
  """
1140
1041
  When gtd lands
1141
1042
  And the process is driven
1142
- Then the process rests at "build.review.await-review"
1043
+ Then the process rests at "idle"
1044
+ And "src/calc.ts" contains "subtract"
1143
1045
 
1144
1046
  Scenario: a praise-only refactor review still signs off and the feature slice follows
1145
1047
  Given step "implement.building" writes "src/calc.ts" with:
@@ -1150,92 +1052,6 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
1150
1052
  """
1151
1053
  And step "implement.health.check" changes nothing
1152
1054
  And step "implement.closing" runs its script
1153
- And step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
1154
- """
1155
- # Review: abc1234
1156
-
1157
- <!-- base: 0000000 -->
1158
-
1159
- ## calc
1160
-
1161
- - [ ] ./src/calc.ts#1-3
1162
- subtract built on the shared op
1163
- """
1164
- When the process is driven
1165
- Then the process rests at "refactor.build.review.await-review"
1166
- Given a file ".gtd/REVIEW.md" with:
1167
- """
1168
- # Review: abc1234
1169
-
1170
- <!-- base: 0000000 -->
1171
-
1172
- ## calc
1173
-
1174
- - [x] ./src/calc.ts#1-2
1175
- add built on the shared op
1176
- """
1177
- When gtd lands
1178
- And the process is driven
1179
- Then the process rests at "build.review.await-review"
1180
-
1181
- Scenario: the feature review after a refactor covers only the commits since the refactor's sign-off
1182
- Given step "implement.building" writes "src/calc.ts" with:
1183
- """
1184
- export const op = (a: number, b: number, sign: number) => a + sign * b
1185
- export const add = (a: number, b: number) => op(a, b, 1)
1186
- export const subtract = (a: number, b: number) => op(a, b, -1)
1187
- """
1188
- And step "implement.health.check" changes nothing
1189
- And step "implement.closing" runs its script
1190
- And step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
1191
- """
1192
- # Review: abc1234
1193
-
1194
- <!-- base: 0000000 -->
1195
-
1196
- ## calc
1197
-
1198
- - [ ] ./src/calc.ts#1-3
1199
- subtract built on the shared op
1200
- """
1201
- When the process is driven
1202
- Then the process rests at "refactor.build.review.await-review"
1203
- Given a file ".gtd/REVIEW.md" with:
1204
- """
1205
- # Review: abc1234
1206
-
1207
- <!-- base: 0000000 -->
1208
-
1209
- ## calc
1210
-
1211
- - [x] ./src/calc.ts#1-2
1212
- add built on the shared op
1213
- """
1214
- When gtd lands
1215
- And the process is driven
1216
- Then the process rests at "build.review.await-review"
1217
- And the resting step's content contains the hash of the commit "gtd(check): refactor.build.review.closing → implement.building"
1218
-
1219
- Scenario: feature feedback after a refactor re-plans design and implement, never the seam phase
1220
- Given step "implement.building" writes "src/calc.ts" with:
1221
- """
1222
- export const op = (a: number, b: number, sign: number) => a + sign * b
1223
- export const add = (a: number, b: number) => op(a, b, 1)
1224
- export const subtract = (a: number, b: number) => op(a, b, -1)
1225
- """
1226
- And step "implement.health.check" changes nothing
1227
- And step "implement.closing" runs its script
1228
- And step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
1229
- """
1230
- # Review: abc1234
1231
-
1232
- <!-- base: 0000000 -->
1233
-
1234
- ## calc
1235
-
1236
- - [ ] ./src/calc.ts#1-3
1237
- subtract built on the shared op
1238
- """
1239
1055
  When the process is driven
1240
1056
  Then the process rests at "refactor.build.review.await-review"
1241
1057
  Given a file ".gtd/REVIEW.md" with:
@@ -1251,72 +1067,8 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
1251
1067
  """
1252
1068
  When gtd lands
1253
1069
  And the process is driven
1254
- Then the process rests at "build.review.await-review"
1255
- Given a file ".gtd/REVIEW.md" with:
1256
- """
1257
- # Review: abc1234
1258
-
1259
- <!-- base: 0000000 -->
1260
-
1261
- ## calc
1262
-
1263
- - [ ] ./src/calc.ts#1-3
1264
- subtract built on the shared op[^why]
1265
-
1266
- [^why]:
1267
- - H: also export multiply
1268
- """
1269
- And step "build.review.collecting" writes ".gtd/REQUIREMENTS.md" with:
1270
- """
1271
- # Requirements
1272
-
1273
- ## Concerns
1274
-
1275
- ### Multiply
1276
-
1277
- - Export `multiply()`.
1278
- """
1279
- And step "build.review.collecting" writes ".gtd/REVIEW.md" with:
1280
- """
1281
- # Review: abc1234
1282
-
1283
- <!-- base: 0000000 -->
1284
-
1285
- ## calc
1286
-
1287
- - [ ] ./src/calc.ts#1-3
1288
- subtract built on the shared op[^why]
1289
-
1290
- [^why]:
1291
- - H: also export multiply
1292
- - A: noted in the requirements.
1293
- """
1294
- When gtd lands
1295
- And the process is driven
1296
- Then the process rests at "build.review.await-review"
1297
- Given a file ".gtd/REVIEW.md" with:
1298
- """
1299
- # Review: abc1234
1300
-
1301
- <!-- base: 0000000 -->
1302
-
1303
- ## calc
1304
-
1305
- - [ ] ./src/calc.ts#1-3
1306
- subtract built on the shared op
1307
- """
1308
- And step "build.review.closing" runs its script
1309
- And step "re-unwind" runs its script
1310
- When gtd lands
1311
- And the process is driven
1312
- Then the process rests at "implement.building"
1313
- And the commit subjects end with:
1314
- """
1315
- gtd(check): re-unwind → design.triage
1316
- gtd(agent): design.triage → design.gate.answer
1317
- gtd(human): design.gate.answer → implement.building
1318
- gtd(agent): implement.building
1319
- """
1070
+ Then the process rests at "idle"
1071
+ And "src/calc.ts" contains "subtract"
1320
1072
 
1321
1073
  Scenario: a nit fix in the refactor slice that changes a non-stray is refused, though a glob stray widens the write access
1322
1074
  Given step "seam.naive" writes "src/*.ts" with:
@@ -1426,6 +1178,11 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
1426
1178
  - AC-1: the change behaves as described.
1427
1179
  """
1428
1180
  And step "design.gate.answer" changes nothing
1181
+ And step "seam.check" changes nothing
1182
+ And step "seam.naive" writes "src/acceptance.test.ts" with:
1183
+ """
1184
+ it("[AC-1] holds", () => {})
1185
+ """
1429
1186
  And step "seam.naive" writes "src/calc.ts" with:
1430
1187
  """
1431
1188
  export const add = (a: number, b: number) => a + b
@@ -1456,7 +1213,7 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
1456
1213
  """
1457
1214
  And step "refactor.build.review.closing" runs its script
1458
1215
 
1459
- Scenario: each slice's quality lap reviews from that slice's base, before and after a feature feedback lap
1216
+ Scenario: each slice's quality lap reviews from that slice's base
1460
1217
  When the process is driven
1461
1218
  Then the process rests at "refactor.build.quality.correctness.reviewing"
1462
1219
  And the resting step's content contains the hash of the commit "gtd(judge): seam.judge → refactor.deriving"
@@ -1487,88 +1244,13 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
1487
1244
  Then the process rests at "build.quality.correctness.reviewing"
1488
1245
  And the resting step's content contains the hash of the commit "gtd(check): refactor.build.review.closing → implement.building"
1489
1246
  Given step "build.quality.correctness.reviewing" changes nothing
1490
- And step "build.review.reviewing" writes ".gtd/REVIEW.md" with:
1491
- """
1492
- # Review: abc1234
1493
-
1494
- <!-- base: 0000000 -->
1495
-
1496
- ## calc
1497
-
1498
- - [ ] ./src/calc.ts#1-3
1499
- subtract built on the shared op
1500
- """
1501
1247
  When the process is driven
1502
- Then the process rests at "build.review.await-review"
1503
- Given a file ".gtd/REVIEW.md" with:
1504
- """
1505
- # Review: abc1234
1506
-
1507
- <!-- base: 0000000 -->
1508
-
1509
- ## calc
1510
-
1511
- - [ ] ./src/calc.ts#1-3
1512
- subtract built on the shared op[^why]
1513
-
1514
- [^why]:
1515
- - H: also export multiply
1516
- """
1517
- And step "build.review.collecting" writes ".gtd/REQUIREMENTS.md" with:
1518
- """
1519
- # Requirements
1520
-
1521
- ## Concerns
1522
-
1523
- ### Multiply
1524
-
1525
- - Export `multiply()`.
1526
- """
1527
- And step "build.review.collecting" writes ".gtd/REVIEW.md" with:
1528
- """
1529
- # Review: abc1234
1530
-
1531
- <!-- base: 0000000 -->
1532
-
1533
- ## calc
1534
-
1535
- - [ ] ./src/calc.ts#1-3
1536
- subtract built on the shared op[^why]
1537
-
1538
- [^why]:
1539
- - H: also export multiply
1540
- - A: noted in the requirements.
1541
- """
1542
- When gtd lands
1543
- And the process is driven
1544
- Then the process rests at "build.review.await-review"
1545
- Given a file ".gtd/REVIEW.md" with:
1546
- """
1547
- # Review: abc1234
1548
-
1549
- <!-- base: 0000000 -->
1550
-
1551
- ## calc
1552
-
1553
- - [ ] ./src/calc.ts#1-3
1554
- subtract built on the shared op
1555
- """
1556
- And step "build.review.closing" runs its script
1557
- And step "re-unwind" runs its script
1558
- And step "build.quality.correctness.reviewing" is no longer scripted
1559
- And step "implement.building" writes "src/calc.ts" with:
1248
+ Then the process rests at "idle"
1249
+ And the commit subjects end with:
1560
1250
  """
1561
- export const op = (a: number, b: number, sign: number) => a + sign * b
1562
- export const add = (a: number, b: number) => op(a, b, 1)
1563
- export const subtract = (a: number, b: number) => op(a, b, -1)
1564
- export const multiply = (a: number, b: number) => a * b
1251
+ gtd(check): implement.closing → build.quality.correctness.reviewing
1252
+ gtd(agent): build.quality.correctness.reviewing → idle
1565
1253
  """
1566
- And step "implement.health.check" changes nothing
1567
- And step "implement.closing" runs its script
1568
- When gtd lands
1569
- And the process is driven
1570
- Then the process rests at "build.quality.correctness.reviewing"
1571
- And the resting step's content contains the hash of the commit "gtd(check): refactor.build.review.closing → implement.building"
1572
1254
 
1573
1255
  Rule: a refactor package never carries a test file, and demoted headings stop at ######
1574
1256
 
@@ -1614,7 +1296,12 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
1614
1296
  """
1615
1297
 
1616
1298
  Scenario: a test-file stray is dropped from the derived refactor package
1617
- Given step "seam.naive" writes "src/calc.ts" with:
1299
+ Given step "seam.check" changes nothing
1300
+ And step "seam.naive" writes "src/acceptance.test.ts" with:
1301
+ """
1302
+ it("[AC-1] holds", () => {})
1303
+ """
1304
+ And step "seam.naive" writes "src/calc.ts" with:
1618
1305
  """
1619
1306
  export const add = (a: number, b: number) => a + b
1620
1307
  export const subtract = (a: number, b: number) => a - b
@@ -1631,7 +1318,12 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
1631
1318
  And ".gtd/REFACTOR.md" does not contain "src/calc.test.ts"
1632
1319
 
1633
1320
  Scenario: the refactor updates an existing test's call sites to the seam's new shape
1634
- Given step "seam.naive" writes "src/calc.ts" with:
1321
+ Given step "seam.check" changes nothing
1322
+ And step "seam.naive" writes "src/acceptance.test.ts" with:
1323
+ """
1324
+ it("[AC-1] holds", () => {})
1325
+ """
1326
+ And step "seam.naive" writes "src/calc.ts" with:
1635
1327
  """
1636
1328
  export const add = ({ a, b }: { a: number; b: number }) => a + b
1637
1329
  export const subtract = ({ a, b }: { a: number; b: number }) => a - b
@@ -1651,7 +1343,12 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
1651
1343
  Then the process rests at "refactor.health.check"
1652
1344
 
1653
1345
  Scenario: the refactor may not drop an assertion from an existing test
1654
- Given step "seam.naive" writes "src/calc.ts" with:
1346
+ Given step "seam.check" changes nothing
1347
+ And step "seam.naive" writes "src/acceptance.test.ts" with:
1348
+ """
1349
+ it("[AC-1] holds", () => {})
1350
+ """
1351
+ And step "seam.naive" writes "src/calc.ts" with:
1655
1352
  """
1656
1353
  export const add = (a: number, b: number) => a + b
1657
1354
  export const subtract = (a: number, b: number) => a - b
@@ -1665,7 +1362,12 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
1665
1362
  Then driving the process is refused with "refactor-tests"
1666
1363
 
1667
1364
  Scenario: a refactor-first whose strays are all test files goes straight to implement
1668
- Given step "seam.naive" writes "src/calc.test.ts" with:
1365
+ Given step "seam.check" changes nothing
1366
+ And step "seam.naive" writes "src/acceptance.test.ts" with:
1367
+ """
1368
+ it("[AC-1] holds", () => {})
1369
+ """
1370
+ And step "seam.naive" writes "src/calc.test.ts" with:
1669
1371
  """
1670
1372
  import { expect, it } from "vitest"
1671
1373
  it("subtracts", () => expect(3 - 1).toBe(2))
@@ -1675,7 +1377,12 @@ Feature: the refactor slice is reviewed on its own before the feature is impleme
1675
1377
  And ".gtd/REFACTOR.md" does not exist
1676
1378
 
1677
1379
  Scenario: collected review headings re-derive at ### with the deepest capped at ######
1678
- Given step "seam.naive" writes "src/calc.ts" with:
1380
+ Given step "seam.check" changes nothing
1381
+ And step "seam.naive" writes "src/acceptance.test.ts" with:
1382
+ """
1383
+ it("[AC-1] holds", () => {})
1384
+ """
1385
+ And step "seam.naive" writes "src/calc.ts" with:
1679
1386
  """
1680
1387
  export const add = (a: number, b: number) => a + b
1681
1388
  export const subtract = (a: number, b: number) => a - b
@@ -42,7 +42,8 @@ export const requireWithin = (allowed: readonly string[]): void => {
42
42
  }
43
43
 
44
44
  // A fixed list, not `seamAllow`: narrowing that setting must not let a test file through.
45
- const isTestFile = (path: string): boolean => testFileGlobs.some((glob) => matches(path, glob))
45
+ export const isTestFile = (path: string): boolean =>
46
+ testFileGlobs.some((glob) => matches(path, glob))
46
47
 
47
48
  // The bundled refactor uses `requireTestCallSitesOnly`; this stays a public export.
48
49
  export const requireNoTestFiles = (): void => {
@@ -56,11 +57,11 @@ export const requireNoTestFiles = (): void => {
56
57
  }
57
58
 
58
59
  // Call sites live in code: a `.feature` file or a snapshot holds only expectations.
59
- const holdsCallSites = (path: string): boolean =>
60
+ export const holdsCallSites = (path: string): boolean =>
60
61
  !path.endsWith(".feature") && !path.endsWith(".snap")
61
62
 
62
63
  // `//` after a `:` (a URL) and `/*` after `*` or `/` (a glob) sit in strings, not comments.
63
- const COMMENT = /(?<![*/])\/\*[\s\S]*?\*\/|(?<!:)\/\/.*$/gm
64
+ export const COMMENT = /(?<![*/])\/\*[\s\S]*?\*\/|(?<!:)\/\/.*$/gm
64
65
  const ASSERTION = /\b(?:expect|assert\w*)\s*[.(]/g
65
66
  const TEST_CASE = /(?<![.\w])x?(?:it|test|describe)\s*[.(]/g
66
67
  const MODIFIER =
@@ -146,6 +146,11 @@ Feature: the risk tier is proposed at triage and recorded behind GTD_FLAG_RISK_T
146
146
 
147
147
  - AC-1: the change behaves as described.
148
148
  """
149
+ And step "seam.check" changes nothing
150
+ And step "seam.naive" writes "src/acceptance.test.ts" with:
151
+ """
152
+ it("[AC-1] holds", () => {})
153
+ """
149
154
  And step "seam.naive" writes "src/calc.ts" with:
150
155
  """
151
156
  export const add = (a: number, b: number) => a + b
@@ -254,6 +259,11 @@ Feature: the risk tier is proposed at triage and recorded behind GTD_FLAG_RISK_T
254
259
  - AC-1: the change behaves as described.
255
260
  """
256
261
  And step "design.gate.answer" changes nothing
262
+ And step "seam.check" changes nothing
263
+ And step "seam.naive" writes "src/acceptance.test.ts" with:
264
+ """
265
+ it("[AC-1] holds", () => {})
266
+ """
257
267
  And step "seam.naive" writes "src/calc.ts" with:
258
268
  """
259
269
  export const add = (a: number, b: number) => a + b