@windyroad/itil 0.61.1 → 0.61.2

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 (171) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/package.json +7 -2
  3. package/agents/test/fixtures/proceed-new-genuinely-new.md +0 -43
  4. package/agents/test/fixtures/proceed-new-subtle-sibling.md +0 -47
  5. package/agents/test/fixtures/regression-p347-vs-p346.md +0 -54
  6. package/agents/test/hang-off-check.bats +0 -225
  7. package/hooks/test/block-list.bats +0 -153
  8. package/hooks/test/command-detect.bats +0 -181
  9. package/hooks/test/itil-assistant-output-gate.bats +0 -114
  10. package/hooks/test/itil-assistant-output-review.bats +0 -224
  11. package/hooks/test/itil-bash-polling-antipattern-detect.bats +0 -154
  12. package/hooks/test/itil-changeset-discipline.bats +0 -603
  13. package/hooks/test/itil-claude-space-protection.bats +0 -294
  14. package/hooks/test/itil-commit-trailer-transition-advisory.bats +0 -80
  15. package/hooks/test/itil-correction-detect.bats +0 -189
  16. package/hooks/test/itil-deferral-cadence-gate.bats +0 -187
  17. package/hooks/test/itil-fictional-defer-detect.bats +0 -292
  18. package/hooks/test/itil-fix-title-lifecycle-advisory.bats +0 -129
  19. package/hooks/test/itil-mid-loop-ask-detect.bats +0 -220
  20. package/hooks/test/itil-no-implement-draft-gate.bats +0 -210
  21. package/hooks/test/itil-pending-questions-surface.bats +0 -307
  22. package/hooks/test/itil-readme-refresh-discipline.bats +0 -642
  23. package/hooks/test/itil-rfc-oversight-nudge.bats +0 -83
  24. package/hooks/test/itil-rfc-trailer-advisory.bats +0 -375
  25. package/hooks/test/itil-story-mirror-migration-nudge.bats +0 -122
  26. package/hooks/test/manage-problem-enforce-create.bats +0 -424
  27. package/hooks/test/p057-staging-trap-detect.bats +0 -231
  28. package/hooks/test/pre-publish-intake-gate.bats +0 -144
  29. package/hooks/test/runtime-sid-marker.bats +0 -90
  30. package/hooks/test/session-id.bats +0 -370
  31. package/scripts/migrate-problems-add-type.sh +0 -116
  32. package/scripts/test/catchup-scan.bats +0 -274
  33. package/scripts/test/check-afk-accept-eligible.bats +0 -310
  34. package/scripts/test/check-fail-soft-skip-discipline.bats +0 -172
  35. package/scripts/test/check-fix-rfc-trace.bats +0 -164
  36. package/scripts/test/check-locale-discipline.bats +0 -291
  37. package/scripts/test/check-problems-readme-budget.bats +0 -192
  38. package/scripts/test/check-rfc-has-stories.bats +0 -69
  39. package/scripts/test/check-rfc-rejected-alternatives.bats +0 -108
  40. package/scripts/test/check-rfc-stories-ratified.bats +0 -82
  41. package/scripts/test/check-upstream-responses.bats +0 -503
  42. package/scripts/test/classify-readme-drift.bats +0 -392
  43. package/scripts/test/derive-first-dispatch.bats +0 -274
  44. package/scripts/test/derive-release-vehicle.bats +0 -454
  45. package/scripts/test/detect-unratified-stories-maps.bats +0 -60
  46. package/scripts/test/dual-tolerant-glob-rfc-002-t2.bats +0 -309
  47. package/scripts/test/effort-tally.bats +0 -170
  48. package/scripts/test/evaluate-relevance.bats +0 -773
  49. package/scripts/test/kind-a-commands.bats +0 -46
  50. package/scripts/test/mark-create-gate.bats +0 -59
  51. package/scripts/test/mark-story-oversight-confirmed.bats +0 -53
  52. package/scripts/test/migrate-problems-add-type.bats +0 -280
  53. package/scripts/test/migrate-story-status-mirror.bats +0 -167
  54. package/scripts/test/no-type-regression-guard.bats +0 -74
  55. package/scripts/test/oversight-mirror-corpus-lint.bats +0 -150
  56. package/scripts/test/plugin-exercise-index.bats +0 -386
  57. package/scripts/test/plugin-maturity-doc-lint.bats +0 -470
  58. package/scripts/test/plugin-maturity-populate.bats +0 -631
  59. package/scripts/test/plugin-maturity-render.bats +0 -469
  60. package/scripts/test/plugin-validate-ci-gate.bats +0 -208
  61. package/scripts/test/reconcile-readme.bats +0 -1007
  62. package/scripts/test/reconcile-rfcs.bats +0 -496
  63. package/scripts/test/reconcile-stories.bats +0 -173
  64. package/scripts/test/reconcile-story-maps.bats +0 -74
  65. package/scripts/test/release-watch-poll-loop.bats +0 -180
  66. package/scripts/test/resolve-governance-plugin-dirs.bats +0 -78
  67. package/scripts/test/rfc-stories-extension.bats +0 -175
  68. package/scripts/test/skill-invocations.bats +0 -535
  69. package/scripts/test/skill-md-dual-tolerant-coverage-rfc-002-t3.bats +0 -374
  70. package/scripts/test/story-oversight-lib.bats +0 -190
  71. package/scripts/test/update-jtbd-references-related-problems.bats +0 -178
  72. package/scripts/test/update-problem-references-section.bats +0 -242
  73. package/scripts/test/update-problem-rfcs-section.bats +0 -242
  74. package/scripts/test/update-references-section-sibling-helpers.bats +0 -80
  75. package/scripts/test/update-rfc-commits-section.bats +0 -77
  76. package/scripts/test/verify-iter-summary.bats +0 -196
  77. package/scripts/test/working-the-problem-traversal.bats +0 -116
  78. package/skills/capture-problem/test/capture-problem-step-1-5b-jtbd-trace.bats +0 -398
  79. package/skills/capture-problem/test/capture-problem.bats +0 -389
  80. package/skills/capture-story/test/capture-story-behavioural.bats +0 -317
  81. package/skills/capture-story-map/test/capture-story-map-behavioural.bats +0 -98
  82. package/skills/close-incident/test/close-incident-contract.bats +0 -146
  83. package/skills/link-incident/test/link-incident-contract.bats +0 -125
  84. package/skills/list-incidents/test/list-incidents-contract.bats +0 -115
  85. package/skills/list-problems/test/list-problems-contract.bats +0 -100
  86. package/skills/list-stories/test/list-stories-contract.bats +0 -127
  87. package/skills/list-story-maps/test/list-story-maps-contract.bats +0 -46
  88. package/skills/manage-incident/test/manage-incident-adr-044-contract.bats +0 -206
  89. package/skills/manage-incident/test/manage-incident-close-forwarder.bats +0 -67
  90. package/skills/manage-incident/test/manage-incident-link-forwarder.bats +0 -67
  91. package/skills/manage-incident/test/manage-incident-list-forwarder.bats +0 -68
  92. package/skills/manage-incident/test/manage-incident-mitigate-forwarder.bats +0 -66
  93. package/skills/manage-incident/test/manage-incident-restore-forwarder.bats +0 -66
  94. package/skills/manage-incident/test/manage-incident.bats +0 -171
  95. package/skills/manage-problem/test/manage-problem-adr-044-step4-derive-first.bats +0 -151
  96. package/skills/manage-problem/test/manage-problem-auto-migrate-step.bats +0 -53
  97. package/skills/manage-problem/test/manage-problem-concern-boundary.bats +0 -64
  98. package/skills/manage-problem/test/manage-problem-effort-buckets.bats +0 -56
  99. package/skills/manage-problem/test/manage-problem-external-root-cause-detection.bats +0 -119
  100. package/skills/manage-problem/test/manage-problem-first-run-intake-prompt.bats +0 -43
  101. package/skills/manage-problem/test/manage-problem-git-mv-restage-reminder.bats +0 -48
  102. package/skills/manage-problem/test/manage-problem-id-collision-guard.bats +0 -39
  103. package/skills/manage-problem/test/manage-problem-list-forwarder.bats +0 -66
  104. package/skills/manage-problem/test/manage-problem-next-id-origin-lookup.bats +0 -50
  105. package/skills/manage-problem/test/manage-problem-no-prose-options.bats +0 -74
  106. package/skills/manage-problem/test/manage-problem-output-formatting.bats +0 -30
  107. package/skills/manage-problem/test/manage-problem-parked-and-cache.bats +0 -73
  108. package/skills/manage-problem/test/manage-problem-readme-refresh-on-transition.bats +0 -62
  109. package/skills/manage-problem/test/manage-problem-readme-tie-break-order.bats +0 -318
  110. package/skills/manage-problem/test/manage-problem-readme-vq-sort-order.bats +0 -206
  111. package/skills/manage-problem/test/manage-problem-release-vehicle-seed.bats +0 -83
  112. package/skills/manage-problem/test/manage-problem-review-forwarder.bats +0 -71
  113. package/skills/manage-problem/test/manage-problem-step-9d-recovery-path.bats +0 -97
  114. package/skills/manage-problem/test/manage-problem-transition-forwarder.bats +0 -96
  115. package/skills/manage-problem/test/manage-problem-transitive-dependencies.bats +0 -365
  116. package/skills/manage-problem/test/manage-problem-verification-detection.bats +0 -64
  117. package/skills/manage-problem/test/manage-problem-verification-pending.bats +0 -114
  118. package/skills/manage-problem/test/manage-problem-work-forwarder.bats +0 -88
  119. package/skills/manage-story/test/manage-story-contract.bats +0 -174
  120. package/skills/manage-story-map/test/manage-story-map-contract.bats +0 -63
  121. package/skills/mitigate-incident/test/mitigate-incident-contract.bats +0 -258
  122. package/skills/reconcile-readme/test/reconcile-readme-contract.bats +0 -201
  123. package/skills/report-upstream/test/report-upstream-contract.bats +0 -394
  124. package/skills/restore-incident/test/restore-incident-contract.bats +0 -170
  125. package/skills/review-problems/test/inbound-channels-cache-shape.bats +0 -127
  126. package/skills/review-problems/test/inbound-discovery-contract.bats +0 -383
  127. package/skills/review-problems/test/jtbd-301-verdict-shape-contract.bats +0 -225
  128. package/skills/review-problems/test/review-problems-contract.bats +0 -235
  129. package/skills/review-problems/test/review-problems-likely-verified-cell-shape.bats +0 -229
  130. package/skills/scaffold-intake/test/scaffold-intake-contract.bats +0 -126
  131. package/skills/scaffold-intake/test/scaffold-intake-fixture.bats +0 -164
  132. package/skills/scaffold-intake/test/scaffold-intake-secrets-absent.bats +0 -87
  133. package/skills/transition-problem/test/transition-problem-contract.bats +0 -285
  134. package/skills/transition-problems/test/transition-problems-contract.bats +0 -331
  135. package/skills/update-upstream/test/update-upstream-contract.bats +0 -375
  136. package/skills/work-problem/test/work-problem-contract.bats +0 -294
  137. package/skills/work-problems/test/work-problems-above-appetite-remediation.bats +0 -139
  138. package/skills/work-problems/test/work-problems-adr-013-rule-6-p352-amendment.bats +0 -166
  139. package/skills/work-problems/test/work-problems-auto-migrate-step.bats +0 -57
  140. package/skills/work-problems/test/work-problems-cost-logging.bats +0 -109
  141. package/skills/work-problems/test/work-problems-deviation-candidate-shape.bats +0 -121
  142. package/skills/work-problems/test/work-problems-first-run-intake-prompt.bats +0 -36
  143. package/skills/work-problems/test/work-problems-inter-iteration-verify.bats +0 -59
  144. package/skills/work-problems/test/work-problems-mid-loop-userpromptsubmit-handler.bats +0 -69
  145. package/skills/work-problems/test/work-problems-no-mid-loop-asking.bats +0 -192
  146. package/skills/work-problems/test/work-problems-p341-pre-all-done-gate.bats +0 -122
  147. package/skills/work-problems/test/work-problems-p342-r007-derive-then-pass-flags.bats +0 -170
  148. package/skills/work-problems/test/work-problems-p342-retro-auto-ticket-carveout.bats +0 -120
  149. package/skills/work-problems/test/work-problems-preflight-failure-handling.bats +0 -248
  150. package/skills/work-problems/test/work-problems-preflight-session-continuity.bats +0 -139
  151. package/skills/work-problems/test/work-problems-preflight.bats +0 -69
  152. package/skills/work-problems/test/work-problems-release-cadence.bats +0 -63
  153. package/skills/work-problems/test/work-problems-step-0-iter-error-staleness.bats +0 -93
  154. package/skills/work-problems/test/work-problems-step-0b-cache-staleness-behavioural.bats +0 -138
  155. package/skills/work-problems/test/work-problems-step-0c-deferred-placeholder-staleness-behavioural.bats +0 -238
  156. package/skills/work-problems/test/work-problems-step-0d-outbound-responses-staleness-behavioural.bats +0 -174
  157. package/skills/work-problems/test/work-problems-step-2-5-routing.bats +0 -80
  158. package/skills/work-problems/test/work-problems-step-2-5b-cross-halt-routing.bats +0 -149
  159. package/skills/work-problems/test/work-problems-step-3-5-jtbd-ratification-predicate.bats +0 -191
  160. package/skills/work-problems/test/work-problems-step-5-bats-polling-discipline.bats +0 -91
  161. package/skills/work-problems/test/work-problems-step-5-delegation.bats +0 -333
  162. package/skills/work-problems/test/work-problems-step-5-idle-timeout-sigterm.bats +0 -421
  163. package/skills/work-problems/test/work-problems-step-5-is-error-transient-halt.bats +0 -278
  164. package/skills/work-problems/test/work-problems-step-5-iter-changeset-required.bats +0 -95
  165. package/skills/work-problems/test/work-problems-step-5-prompt-body-re-grounding.bats +0 -128
  166. package/skills/work-problems/test/work-problems-step-5-stream-timeout-salvage.bats +0 -251
  167. package/skills/work-problems/test/work-problems-step-6-5-always-drain.bats +0 -203
  168. package/skills/work-problems/test/work-problems-step-6-5-cache-refresh-chain.bats +0 -174
  169. package/skills/work-problems/test/work-problems-step-6-5-fix-and-continue.bats +0 -254
  170. package/skills/work-problems/test/work-problems-step-6-5-postrelease-kv-callback.bats +0 -209
  171. package/skills/work-problems/test/work-problems-stop-condition-questions.bats +0 -85
@@ -1,333 +0,0 @@
1
- #!/usr/bin/env bats
2
- # Doc-lint guard: work-problems SKILL.md Step 5 must delegate each iteration
3
- # by shelling out to a `claude -p` subprocess. Subagents spawned via the Agent
4
- # tool cannot themselves call Agent (platform restriction — P084 confirmed by
5
- # three-source evidence 2026-04-21: ToolSearch probe, Claude Code docs at
6
- # code.claude.com/docs/en/subagents.md, empirical invocation runtime error).
7
- # So architect + JTBD + risk-scorer gate markers cannot be set from inside an
8
- # Agent-tool-spawned iteration worker. The subprocess variant has Agent in its
9
- # surface (empirically verified), so governance review runs at full depth and
10
- # the commit gate unlocks natively.
11
- #
12
- # Structural assertion — Permitted Exception to the source-grep ban under
13
- # ADR-005 + ADR-037 (SKILL.md is explicitly a contract document; doc-lint
14
- # contract assertion is the named permitted pattern). Behavioural tests for
15
- # the subprocess integration path would need a full Claude Code session
16
- # harness, which is out of scope for the skill-level contract layer.
17
- #
18
- # @problem P084
19
- # @problem P077
20
- # @problem P086
21
- # @jtbd JTBD-006
22
- # @jtbd JTBD-001
23
- # @jtbd JTBD-101
24
- #
25
- # Cross-reference:
26
- # P084 (iteration worker has no Agent tool) — driver for the subprocess swap
27
- # P077 (Step 5 does not delegate to subagent) — prior amendment; subprocess
28
- # is the refinement of the same AFK iteration-isolation wrapper intent
29
- # ADR-015 (on-demand assessment skills — Agent-vs-Skill tool precedent)
30
- # ADR-032 (governance skill invocation patterns — AFK iteration-isolation
31
- # wrapper sub-pattern; amended with subprocess-boundary variant for P084)
32
- # ADR-037 (skill testing strategy — contract-assertion pattern)
33
- # JTBD-006 (Progress the Backlog While I'm Away)
34
- # JTBD-001 (Enforce Governance Without Slowing Down)
35
-
36
- setup() {
37
- SKILL_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
38
- SKILL_FILE="${SKILL_DIR}/SKILL.md"
39
- }
40
-
41
- @test "SKILL.md cites P084 (subprocess dispatch driver)" {
42
- run grep -n "P084" "$SKILL_FILE"
43
- [ "$status" -eq 0 ]
44
- }
45
-
46
- @test "SKILL.md cites P077 (prior Step 5 delegation amendment)" {
47
- run grep -n "P077" "$SKILL_FILE"
48
- [ "$status" -eq 0 ]
49
- }
50
-
51
- @test "SKILL.md Step 5 names claude -p as the dispatch mechanism" {
52
- # The subprocess boundary is how Step 5 achieves iteration isolation post-P084.
53
- # Bare 'delegate via Agent tool' would re-introduce the tool-surface gap that
54
- # P084 proved unshippable.
55
- run grep -nE "claude -p|claude --print" "$SKILL_FILE"
56
- [ "$status" -eq 0 ]
57
- }
58
-
59
- @test "SKILL.md Step 5 specifies --permission-mode bypassPermissions" {
60
- # Non-interactive permission handling for AFK subprocess (verified by Probe 4).
61
- # Without this flag, subprocess Bash/Edit/Write calls halt on prompts.
62
- run grep -nE "permission-mode[[:space:]]+bypassPermissions|--permission-mode[[:space:]]+bypassPermissions" "$SKILL_FILE"
63
- [ "$status" -eq 0 ]
64
- }
65
-
66
- @test "SKILL.md Step 5 specifies --output-format json for deterministic parsing" {
67
- # JSON .result field is the stable parse shape for ITERATION_SUMMARY extraction.
68
- run grep -nE "output-format[[:space:]]+json|--output-format[[:space:]]+json" "$SKILL_FILE"
69
- [ "$status" -eq 0 ]
70
- }
71
-
72
- @test "SKILL.md Step 5 does NOT invoke --max-budget-usd in the dispatch command (user direction 2026-04-21)" {
73
- # Explicit no-cap decision: quota exhaustion is the natural stop, not an
74
- # arbitrary per-iteration dollar cap. A cap would halt iterations before
75
- # quota runs out, leaving remaining backlog unprocessed. The assertion is
76
- # negative to catch regressions that re-introduce a cap by default.
77
- # Narrowed to the "used-form" pattern (flag followed by a value or envvar);
78
- # mentions of --max-budget-usd in explanatory prose are allowed because
79
- # the SKILL.md documents WHY the flag is omitted.
80
- run grep -nE '\-\-max-budget-usd[[:space:]]+("?\$|"[0-9])' "$SKILL_FILE"
81
- [ "$status" -ne 0 ]
82
- }
83
-
84
- @test "SKILL.md Step 5 does NOT reference WR_ITERATION_BUDGET_USD envvar (cap removed)" {
85
- # The envvar was part of the earlier cap design that user directed away
86
- # from. Assertion catches regression that re-introduces the envvar.
87
- run grep -nE "WR_ITERATION_BUDGET_USD" "$SKILL_FILE"
88
- [ "$status" -ne 0 ]
89
- }
90
-
91
- @test "SKILL.md Step 5 documents quota as the natural stop condition" {
92
- # User direction 2026-04-21: AFK loop runs until quota exhausted, not until
93
- # an artificial cap hits. SKILL.md must state this explicitly so future
94
- # contributors don't re-add a cap "for safety".
95
- run grep -niE "quota.{0,40}natural|natural.{0,40}quota|quota.{0,60}stop|stop.{0,60}quota|quota exhaust" "$SKILL_FILE"
96
- [ "$status" -eq 0 ]
97
- }
98
-
99
- @test "SKILL.md Step 5 does NOT name subagent_type general-purpose (migrated away)" {
100
- # Post-P084 the Agent-tool dispatch is removed; Agent-tool-spawned general-purpose
101
- # subagents cannot satisfy gate markers (no nested Agent). The assertion is
102
- # negative on purpose: it catches accidental regression to the old dispatch.
103
- run grep -nE "subagent_type.{0,20}general-purpose" "$SKILL_FILE"
104
- [ "$status" -ne 0 ]
105
- }
106
-
107
- @test "SKILL.md Step 5 specifies a return-summary contract" {
108
- # Contract preserved verbatim from P077. Orchestrator reads ITERATION_SUMMARY
109
- # from subprocess stdout (JSON .result) instead of Agent-tool return value.
110
- run grep -niE "return.{0,30}summary|iteration summary|summary shape|summary contract|ITERATION_SUMMARY" "$SKILL_FILE"
111
- [ "$status" -eq 0 ]
112
- }
113
-
114
- @test "SKILL.md Step 5 return-summary contract carries commit state (Step 6.75 dependency)" {
115
- # Architect R2 (P077): Step 6.75 inter-iteration verification needs the iteration
116
- # to report committed / commit_sha / reason so the Dirty-for-known-reason branch
117
- # stays evaluable. Preserved under subprocess swap.
118
- run grep -niE "commit_sha|committed.*true|committed.*false|commit state" "$SKILL_FILE"
119
- [ "$status" -eq 0 ]
120
- }
121
-
122
- @test "SKILL.md Step 5 return-summary contract carries skip-reason category (Step 2.5 dependency)" {
123
- # JTBD review (P077): skip_reason_category is what Step 2.5 reads deterministically.
124
- # Preserved under subprocess swap.
125
- run grep -niE "skip_reason_category|skip-reason category" "$SKILL_FILE"
126
- [ "$status" -eq 0 ]
127
- }
128
-
129
- @test "SKILL.md allowed-tools frontmatter includes Bash (for subprocess shell-out)" {
130
- # Bash is required to invoke `claude -p` from Step 5.
131
- run grep -nE "^allowed-tools:.*Bash" "$SKILL_FILE"
132
- [ "$status" -eq 0 ]
133
- }
134
-
135
- @test "SKILL.md allowed-tools frontmatter includes Agent (for Step 6.5 risk-scorer)" {
136
- # Step 6.5 delegates to wr-risk-scorer:pipeline via the Agent tool (orchestrator's
137
- # main turn, separate from the iteration subprocess). Still required.
138
- run grep -nE "^allowed-tools:.*Agent" "$SKILL_FILE"
139
- [ "$status" -eq 0 ]
140
- }
141
-
142
- @test "SKILL.md Non-Interactive Decision Making table covers iteration delegation" {
143
- # The non-interactive defaults table must include the iteration dispatch row,
144
- # updated to name claude -p subprocess (not the legacy Agent-tool path).
145
- run grep -niE "iteration delegation|delegate.*iteration|iteration.*subprocess|claude -p.*iteration|iteration.*claude -p" "$SKILL_FILE"
146
- [ "$status" -eq 0 ]
147
- }
148
-
149
- @test "SKILL.md Related section cites ADR-032 (iteration-isolation wrapper)" {
150
- # ADR-032 is amended with the subprocess-boundary sub-pattern for P084.
151
- run grep -nE "ADR-032" "$SKILL_FILE"
152
- [ "$status" -eq 0 ]
153
- }
154
-
155
- @test "SKILL.md Step 5 preserves inter-iteration continuity (Steps 6.5 / 6.75 stay in orchestrator)" {
156
- # Architect + JTBD review confirmation: Step 6.5 (release cadence) and Step 6.75
157
- # (inter-iteration verification) stay in the main orchestrator's turn. The
158
- # iteration subprocess does NOT run push:watch/release:watch.
159
- run grep -niE "orchestrator.{0,80}Step 6\\.5|Step 6\\.5.{0,80}orchestrator|Step 6\\.75.{0,80}orchestrator|orchestrator.{0,80}Step 6\\.75|main orchestrator|orchestrator.{0,40}main turn|main.turn.{0,40}orchestrator" "$SKILL_FILE"
160
- [ "$status" -eq 0 ]
161
- }
162
-
163
- @test "SKILL.md Step 5 documents hook session-id isolation for subprocess" {
164
- # Architect advisory (2026-04-21): subprocess has its own $CLAUDE_SESSION_ID,
165
- # so markers in /tmp/architect-reviewed-<ID> are scoped to subprocess hooks.
166
- # Intended behaviour, but must be explicitly documented to prevent future
167
- # contributors from wiring cross-process marker sharing.
168
- run grep -niE "CLAUDE_SESSION_ID|session.?id isolation|session-id isolation|marker.{0,40}isolated|subprocess.{0,40}SESSION_ID" "$SKILL_FILE"
169
- [ "$status" -eq 0 ]
170
- }
171
-
172
- @test "SKILL.md Step 5 iteration prompt names /wr-retrospective:run-retro (P086 retro-on-exit)" {
173
- # P086 (2026-04-21): iteration subprocesses exit without running retro, so
174
- # per-iteration friction, hook misbehaviour, repeat-workaround patterns, and
175
- # pipeline-instability observations evaporate on exit. The iteration prompt
176
- # body MUST name /wr-retrospective:run-retro as a closing step so the retro
177
- # skill's Step 2b pipeline-instability scan fires inside the subprocess's
178
- # full tool-call history. Retro commits its own work per ADR-014; orchestrator
179
- # picks up retro-created tickets on the next Step 1 scan naturally.
180
- run grep -nE "/wr-retrospective:run-retro" "$SKILL_FILE"
181
- [ "$status" -eq 0 ]
182
- }
183
-
184
- @test "SKILL.md Step 5 orders retro BEFORE ITERATION_SUMMARY emission (P086)" {
185
- # The retro-on-exit clause must fire BEFORE the ITERATION_SUMMARY block so
186
- # any tickets retro creates ride into either the iteration's own commit or
187
- # a retro-owned follow-up commit — and the orchestrator sees them on the
188
- # next Step 1 scan. Emitting ITERATION_SUMMARY first and running retro after
189
- # would leave retro tickets uncommitted when the subprocess exits.
190
- #
191
- # The assertion: the first mention of "run-retro" must appear BEFORE a
192
- # phrase that explicitly names the ordering (e.g. "before emitting
193
- # ITERATION_SUMMARY" or similar).
194
- run grep -niE "before.{0,40}emit.{0,40}ITERATION_SUMMARY|before.{0,20}ITERATION_SUMMARY.{0,40}(emission|emit)|prior to.{0,40}ITERATION_SUMMARY" "$SKILL_FILE"
195
- [ "$status" -eq 0 ]
196
- }
197
-
198
- @test "SKILL.md Step 5 names retro as non-blocking closing step (P086)" {
199
- # Retro findings MUST NOT block ITERATION_SUMMARY emission — if retro fails
200
- # or surfaces findings, the iteration still returns to the orchestrator with
201
- # a summary. Otherwise a flaky retro run could silently halt the AFK loop.
202
- # The SKILL.md prompt body must state that the subprocess proceeds to
203
- # ITERATION_SUMMARY regardless of retro findings.
204
- run grep -niE "do not block on retro|regardless of retro|retro.{0,40}non-blocking|proceed.{0,40}regardless.{0,40}retro|non-blocking.{0,40}retro" "$SKILL_FILE"
205
- [ "$status" -eq 0 ]
206
- }
207
-
208
- @test "SKILL.md Step 5 cites ADR-014 for retro commit ownership (P086)" {
209
- # Retro-created tickets ride into the iteration's commit OR a retro follow-up
210
- # commit per run-retro's ADR-014 contract. The iteration prompt body must
211
- # name ADR-014 so contributors do not accidentally wire iteration-side commit
212
- # of retro artefacts — retro owns its own commits.
213
- run grep -nE "ADR-014" "$SKILL_FILE"
214
- [ "$status" -eq 0 ]
215
- }
216
-
217
- # @problem P083
218
- # @jtbd JTBD-006
219
- # @jtbd JTBD-001
220
- # @jtbd JTBD-101
221
- # @jtbd JTBD-201
222
- #
223
- # STRUCTURAL: tests the SKILL.md content contract per ADR-037's Permitted
224
- # Exception (doc-lint contract assertion against the contract document itself)
225
- # — same rationale already covered by the file-header block above. Behavioural
226
- # alternative would require simulating a `claude -p` iteration subprocess with
227
- # a large task and observing tool-call traces for absence of ScheduleWakeup;
228
- # that harness is not yet available at the skill layer (see P081 retrofit path).
229
- @test "SKILL.md Step 5 iteration prompt forbids ScheduleWakeup (P083 — synchronous-handoff contract)" {
230
- # P083 (2026-04-21): AFK iter 5 observed an iteration worker call ScheduleWakeup
231
- # mid-task, abandoning the synchronous-handoff contract (no ITERATION_SUMMARY
232
- # returned; uncommitted work left in tree; Step 6.75 halted the loop on
233
- # dirty-for-unknown-reason). The Step 5 iteration prompt body MUST explicitly
234
- # forbid ScheduleWakeup so LLM-driven workers do not reach for time-deferring
235
- # primitives — iteration workers are synchronous by contract (ADR-032 AFK
236
- # iteration-isolation wrapper). Regression guard for the 260768f clause.
237
- run grep -niE "Do NOT use .?ScheduleWakeup|ScheduleWakeup.{0,80}(must not|not.{0,10}self-reschedule)|not.{0,10}self-reschedule" "$SKILL_FILE"
238
- [ "$status" -eq 0 ]
239
- }
240
-
241
- @test "SKILL.md Step 5 ScheduleWakeup forbidding clause cites P083" {
242
- # The forbidding clause must cite P083 inline so the contract document is
243
- # self-documenting — a future contributor removing the clause reads the
244
- # P083 reference and understands why it exists before deleting it.
245
- run grep -nE "ScheduleWakeup.{0,120}P083|P083.{0,120}ScheduleWakeup" "$SKILL_FILE"
246
- [ "$status" -eq 0 ]
247
- }
248
-
249
- # @problem P089
250
- # @jtbd JTBD-006
251
- #
252
- # STRUCTURAL: tests the SKILL.md content contract per ADR-037's Permitted
253
- # Exception (doc-lint contract assertion against the contract document
254
- # itself). Behavioural alternative would require spawning a real `claude -p`
255
- # subprocess from a non-TTY context, observing that the JSON response parses
256
- # cleanly, and asserting `jq` does not error on a stderr-merged capture —
257
- # that harness sits outside the skill layer and depends on the Anthropic
258
- # CLI binary. Contract assertion is the named permitted pattern.
259
- @test "SKILL.md Step 5 dispatch command redirects stdin (< /dev/null) to suppress stdin warning (P089 Gap 1)" {
260
- # P089 Gap 1 (2026-04-21, AFK-iter-7 iter 1): the shipped dispatch command
261
- # without an explicit stdin redirect causes `claude -p` to emit
262
- # `Warning: no stdin data received in 3s, proceeding without it...` to
263
- # stderr after a 3s wait. When the orchestrator captures the subprocess
264
- # with `2>&1` (required for structured parse), that warning prepends to
265
- # stdout and corrupts `jq` / `json.load` / `JSON.parse` extraction of
266
- # `.result` and cost metadata. The `claude -p` CLI help explicitly
267
- # suggests `< /dev/null` as the workaround. Regression guard ensures the
268
- # redirect stays in the canonical dispatch block adopters copy.
269
- run grep -nE '< /dev/null|< ?/dev/null' "$SKILL_FILE"
270
- [ "$status" -eq 0 ]
271
- }
272
-
273
- @test "SKILL.md Step 5 explains stdin warning is on stderr (becomes stdout problem under 2>&1 capture)" {
274
- # Architect advisory (2026-04-22): the prose around the `< /dev/null`
275
- # redirect must state that the warning is emitted to stderr (not stdout)
276
- # so adopters who capture stderr separately understand they do not need
277
- # the redirect. This prevents cargo-culting the redirect in environments
278
- # where stdout and stderr are consumed independently.
279
- run grep -niE "stderr.{0,120}(2>&1|merge|capture)|warning.{0,60}stderr|stderr.{0,60}warning" "$SKILL_FILE"
280
- [ "$status" -eq 0 ]
281
- }
282
-
283
- # @problem P089
284
- # @jtbd JTBD-006
285
- #
286
- # STRUCTURAL: same Permitted Exception rationale — behavioural alternative
287
- # would require a subprocess that internally spawns a background task,
288
- # receives its completion notification, and returns a final-turn ack;
289
- # the observation is a runtime contract of the Anthropic CLI and harness
290
- # instrumentation sits outside the skill layer.
291
- @test "SKILL.md Per-iteration cost metadata block names total_cost_usd as authoritative (P089 Gap 2)" {
292
- # P089 Gap 2 (2026-04-21, AFK-iter-7 iter 5): subprocess ran 1071s wall-clock
293
- # with 60+ tool uses; JSON returned `duration_ms: 8546, num_turns: 1,
294
- # usage.* = ~137K tokens, total_cost_usd: 6.08`. Cost was cumulative-
295
- # authoritative; usage.* reflected only the final-turn ack after a
296
- # background-task completion notification. The SKILL.md must name the
297
- # authority hierarchy explicitly so Session Cost consumers treat
298
- # total_cost_usd as the trusted dollar signal and usage.* as best-effort
299
- # approximate.
300
- run grep -niE "total_cost_usd.{0,80}authoritative|authoritative.{0,80}total_cost_usd|total_cost_usd.{0,40}cumulative" "$SKILL_FILE"
301
- [ "$status" -eq 0 ]
302
- }
303
-
304
- @test "SKILL.md Per-iteration cost metadata block flags usage.* as best-effort under early-ack anomaly (P089 Gap 2)" {
305
- # The asymmetry between cumulative total_cost_usd and per-turn usage.*
306
- # must be documented so contributors do not assume summing usage fields
307
- # yields a total-tokens number matching real cost. Detection criterion
308
- # (1-turn-short + duration_ms << wall-clock) is stated descriptively per
309
- # architect option-b (keeps num_turns off the extracted field list).
310
- run grep -niE "usage\\.\\*.{0,120}(best.?effort|approximate|final.?turn|under.?count|partial)|best.?effort.{0,120}usage|final.?turn.{0,120}usage" "$SKILL_FILE"
311
- [ "$status" -eq 0 ]
312
- }
313
-
314
- @test "SKILL.md Session Cost output section notes tokens are best-effort under the early-ack anomaly (P089 Gap 2)" {
315
- # The Session Cost table renders to the user on every ALL_DONE. If token
316
- # columns silently undercount when a subprocess exits via background-task
317
- # ack, the user's cost envelope is wrong without any caveat. The output
318
- # section must carry a short note that the token totals are best-effort
319
- # while total-cost is authoritative — this is the observability contract
320
- # visible to the end user, not just an internal implementation detail.
321
- # The note can live inline in the table footer or in the prose around
322
- # the table.
323
- run grep -niE "tokens.{0,120}(best.?effort|approximate|undercount|may reflect)|total.?cost.{0,120}authoritative" "$SKILL_FILE"
324
- [ "$status" -eq 0 ]
325
- }
326
-
327
- @test "SKILL.md Related section cites P089 (Step 5 dispatch robustness)" {
328
- # P089 documents the two gaps fixed by the < /dev/null redirect and the
329
- # authority hierarchy paragraph. The Related section must cite it so the
330
- # contract document remains self-documenting.
331
- run grep -nE "P089" "$SKILL_FILE"
332
- [ "$status" -eq 0 ]
333
- }