@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,80 +0,0 @@
1
- #!/usr/bin/env bats
2
-
3
- # P122: work-problems Step 2.5 stop-condition #2 routing must default to
4
- # AskUserQuestion (interactive) and use the table emit only as the
5
- # AskUserQuestion-unavailable fallback. The "non-interactive default for
6
- # this skill" prose was wrong-by-design — JTBD-006 (AFK persona) is served
7
- # by the iteration subprocess workers, not by suppressing AskUserQuestion
8
- # at the orchestrator's main turn (which is interactive by construction).
9
- #
10
- # Doc-lint contract assertions per ADR-037 Permitted Exception (structural
11
- # checks on prose contract, not behavioural coverage).
12
-
13
- setup() {
14
- REPO_ROOT="$(cd "$(dirname "$BATS_TEST_FILENAME")/../../../../.." && pwd)"
15
- SKILL_MD="$REPO_ROOT/packages/itil/skills/work-problems/SKILL.md"
16
- }
17
-
18
- @test "work-problems P122: SKILL.md exists" {
19
- [ -f "$SKILL_MD" ]
20
- }
21
-
22
- @test "work-problems P122: Step 2.5 removes the legacy AFK-as-default prose" {
23
- # The flipped default — the legacy "non-interactive path the default
24
- # for this skill" prose at Step 2.5 must be gone. (Note: Step 0's
25
- # session-continuity AFK branch intentionally retains its own AFK
26
- # default for a different reason; this test is scoped to Step 2.5's
27
- # specific phrasing only.)
28
- run grep -F 'non-interactive path the default for this skill' "$SKILL_MD"
29
- [ "$status" -ne 0 ]
30
- }
31
-
32
- @test "work-problems P122: Step 2.5 explicitly cites AskUserQuestion as the default branch" {
33
- # The new default-selection prose names a "Default branch" that calls
34
- # AskUserQuestion. Match the structural phrase rather than the
35
- # backtick-wrapped tool name to keep the grep portable.
36
- run grep -F 'Default branch' "$SKILL_MD"
37
- [ "$status" -eq 0 ]
38
- }
39
-
40
- @test "work-problems P122: Step 2.5 cites the orchestrator-vs-subprocess principle" {
41
- # The flip's load-bearing reasoning: the orchestrator's main turn is
42
- # interactive by construction; AFK persona is served by the
43
- # subprocess-boundary contract under ADR-032, not by suppressing
44
- # AskUserQuestion at the orchestrator layer. (Architect FLAG —
45
- # cross-skill principle sentence.)
46
- run grep -F 'subprocess-boundary contract' "$SKILL_MD"
47
- [ "$status" -eq 0 ]
48
- run grep -F 'interactive by construction' "$SKILL_MD"
49
- [ "$status" -eq 0 ]
50
- }
51
-
52
- @test "work-problems P122: Step 2.5 preserves the user-answerable skip-reason scoping" {
53
- # P103 anti-pattern boundary: the AskUserQuestion default must NOT
54
- # broaden to architect-design or upstream-blocked skip-reasons. The
55
- # user-answerable scoping from Step 4's classifier remains in force.
56
- run grep -F 'user-answerable' "$SKILL_MD"
57
- [ "$status" -eq 0 ]
58
- }
59
-
60
- @test "work-problems P122: Step 2.5 preserves the 4-question-per-call cap" {
61
- # AskUserQuestion's documented per-call limit; sequential calls when
62
- # the question set exceeds the cap.
63
- run grep -F '4 questions per' "$SKILL_MD"
64
- [ "$status" -eq 0 ]
65
- }
66
-
67
- @test "work-problems P122: Step 2.5 preserves the table-fallback-when-unavailable branch" {
68
- # Rule 6 fail-safe: when AskUserQuestion is unavailable (restricted
69
- # permission mode, etc.), emit the Outstanding Design Questions table.
70
- run grep -F 'Outstanding Design Questions' "$SKILL_MD"
71
- [ "$status" -eq 0 ]
72
- }
73
-
74
- @test "work-problems P122: Decisions Table row for stop-condition #2 names AskUserQuestion as default" {
75
- # The Step 6.5 Decisions Table row at the bottom of the SKILL.md
76
- # must agree with the Step 2.5 prose — the prior "table is the
77
- # default" wording must be flipped here too.
78
- run grep -E '^\| Stop-condition #2 .*AskUserQuestion' "$SKILL_MD"
79
- [ "$status" -eq 0 ]
80
- }
@@ -1,149 +0,0 @@
1
- #!/usr/bin/env bats
2
-
3
- # P126: work-problems halt paths must route accumulated user-answerable
4
- # skips through Step 2.5's surfacing routine before emitting the AFK
5
- # summary. P122 fixed the routing at Step 2.5 stop-condition #2; P126
6
- # extends the same contract to the remaining halt paths (Step 0
7
- # session-continuity, Step 0 fetch failure, Step 6.5 CI-failure, Step
8
- # 6.5 ADR-042 Rule 5, Step 6.75 dirty-for-unknown-reason).
9
- #
10
- # The fix shape: extract Step 2.5's surfacing routine into a reusable
11
- # named sub-step (Step 2.5b) that every halt path cross-references
12
- # before emitting its summary. Empty-skip halts skip the round-trip
13
- # (gating clause: ≥1 user-answerable skip accumulated).
14
- #
15
- # Doc-lint contract assertions per ADR-037 Permitted Exception
16
- # (structural checks on prose contract, not behavioural coverage).
17
- #
18
- # @problem P126
19
- # @jtbd JTBD-001 (Enforce Governance Without Slowing Down)
20
- # @jtbd JTBD-006 (Progress the Backlog While I'm Away)
21
-
22
- setup() {
23
- REPO_ROOT="$(cd "$(dirname "$BATS_TEST_FILENAME")/../../../../.." && pwd)"
24
- SKILL_MD="$REPO_ROOT/packages/itil/skills/work-problems/SKILL.md"
25
- BRIEFING_MD="$REPO_ROOT/docs/briefing/afk-subprocess.md"
26
- }
27
-
28
- @test "work-problems P126: SKILL.md exists" {
29
- [ -f "$SKILL_MD" ]
30
- }
31
-
32
- @test "work-problems P126: SKILL.md names Step 2.5b as the reusable surfacing routine" {
33
- # The fix extracts Step 2.5's AskUserQuestion-when-available-else-table
34
- # logic into a named reusable sub-step that halt paths can cross-reference
35
- # uniformly. The name MUST appear as a heading or anchor so cross-references
36
- # resolve to a single source of truth.
37
- run grep -F 'Step 2.5b' "$SKILL_MD"
38
- [ "$status" -eq 0 ]
39
- }
40
-
41
- @test "work-problems P126: Step 2.5b heading exists in SKILL.md" {
42
- # Stronger structural check: Step 2.5b must be a markdown heading (### or
43
- # ####) so it is a navigable anchor, not just an inline mention.
44
- run grep -E '^#{3,4} Step 2\.5b' "$SKILL_MD"
45
- [ "$status" -eq 0 ]
46
- }
47
-
48
- @test "work-problems P126: Step 2.5b preserves the AskUserQuestion default branch" {
49
- # Step 2.5b must inherit P122's interactive-default routing — calling
50
- # AskUserQuestion when available is the load-bearing fix.
51
- run grep -F 'AskUserQuestion' "$SKILL_MD"
52
- [ "$status" -eq 0 ]
53
- }
54
-
55
- @test "work-problems P126: Step 2.5b preserves the table fallback for ADR-013 Rule 6" {
56
- # Rule 6 fail-safe: when AskUserQuestion is unavailable, emit the
57
- # Outstanding Design Questions table.
58
- run grep -F 'Outstanding Design Questions' "$SKILL_MD"
59
- [ "$status" -eq 0 ]
60
- }
61
-
62
- @test "work-problems P126: Step 2.5b is gated on at least one accumulated user-answerable skip" {
63
- # The gating clause prevents empty-skip halts from triggering an
64
- # unnecessary round-trip. Architect-flagged refinement: the gate clause
65
- # must be named in Step 2.5b so future authors don't copy-paste cross-
66
- # references and forget the gate.
67
- run grep -nE 'at least one accumulated user-answerable skip|≥ ?1 (accumulated )?user-answerable skip|>= ?1 user-answerable skip|one or more user-answerable skip' "$SKILL_MD"
68
- [ "$status" -eq 0 ]
69
- }
70
-
71
- @test "work-problems P126: Step 0 session-continuity halt cross-references Step 2.5b" {
72
- # P109's Step 0 AFK fallback halts with a Prior-Session State report.
73
- # When iters have accumulated user-answerable skips before the halt fires
74
- # (rare at Step 0 since iters haven't run yet, but the contract must be
75
- # uniform), the halt must run Step 2.5b first.
76
- run grep -nE 'Step 0.*Step 2\.5b|session-continuity.*Step 2\.5b' "$SKILL_MD"
77
- [ "$status" -eq 0 ]
78
- }
79
-
80
- @test "work-problems P126: Step 0 fetch failure halt cross-references Step 2.5b" {
81
- # Step 0's git fetch network failure halt also emits a final summary
82
- # without iter context — the cross-reference is for contract uniformity
83
- # even when no skips can accumulate at Step 0.
84
- run grep -nE 'fetch.*Step 2\.5b|Network failure.*Step 2\.5b|fetch failure.*Step 2\.5b' "$SKILL_MD"
85
- [ "$status" -eq 0 ]
86
- }
87
-
88
- @test "work-problems P126: Step 6.5 CI-failure halt cross-references Step 6.5b" {
89
- # The Step 6.5 "Failure handling" clause halts on push:watch / release:watch
90
- # failure. After N iters this halt path frequently has accumulated user-
91
- # answerable skips (the empirically observed P126 surface).
92
- run grep -nE 'Failure handling.*Step 2\.5b|CI failure.*Step 2\.5b|release:watch.*Step 2\.5b' "$SKILL_MD"
93
- [ "$status" -eq 0 ]
94
- }
95
-
96
- @test "work-problems P126: Step 6.5 ADR-042 Rule 5 halt cross-references Step 2.5b with halt-vs-prior-skip guard" {
97
- # Architect-flagged refinement: the cross-reference under Rule 5 halt
98
- # must explicitly distinguish "Step 2.5b surfaces prior-iter accumulated
99
- # skips" from "ADR-042 Rule 5 halt remains the bug signal — the user is
100
- # NOT asked how to remediate the above-appetite state". Two grep checks:
101
- # cross-reference present AND the guard prose present nearby.
102
- run grep -nE 'Rule 5.*Step 2\.5b|halted-above-appetite.*Step 2\.5b' "$SKILL_MD"
103
- [ "$status" -eq 0 ]
104
- # Guard: prior-iter accumulated skips are surfaced; the halt-causing
105
- # scorer-gap remains a halt with bug-signal.
106
- run grep -nE 'prior[- ]iter accumulated|surfaces? prior[- ]iter|NOT ask the user how to remediate|halt-causing scorer[- ]gap' "$SKILL_MD"
107
- [ "$status" -eq 0 ]
108
- }
109
-
110
- @test "work-problems P126: Step 6.75 dirty-for-unknown-reason halt cross-references Step 2.5b" {
111
- # P036's Step 6.75 inter-iter verification halt emits a final summary
112
- # when git status is dirty for unknown reason between iters. After N
113
- # iters this halt path is the second most common P126 surface
114
- # empirically.
115
- run grep -nE 'Dirty for an unknown reason.*Step 2\.5b|dirty[- ]for[- ]unknown[- ]reason.*Step 2\.5b|Step 6\.75.*Step 2\.5b' "$SKILL_MD"
116
- [ "$status" -eq 0 ]
117
- }
118
-
119
- @test "work-problems P126: Step 2.5 still cross-references Step 2.5b (single source of truth)" {
120
- # The original Step 2.5 stop-condition #2 branch must also call into
121
- # Step 2.5b — keeping the surfacing logic in one place rather than
122
- # duplicated between Step 2.5 and Step 2.5b.
123
- run grep -nE 'Step 2\.5 .*Step 2\.5b|Step 2\.5b.*surfacing|Step 2\.5\b.*calls? Step 2\.5b' "$SKILL_MD"
124
- [ "$status" -eq 0 ]
125
- }
126
-
127
- @test "work-problems P126: Decisions Table row exists for halt-paths-cross-route via Step 2.5b" {
128
- # The "Non-Interactive Decision Making" Decisions Table at the bottom
129
- # of SKILL.md must carry a row that names the cross-halt routing so the
130
- # decision summary is consistent with the Step prose.
131
- run grep -nE '\| Halt[- ]path .*Step 2\.5b|halt path.*accumulated user-answerable' "$SKILL_MD"
132
- [ "$status" -eq 0 ]
133
- }
134
-
135
- @test "work-problems P126: Briefing entry documents the halt-paths-must-route principle" {
136
- # The cross-session briefing entry must record the principle alongside
137
- # the existing P122 entry so future sessions inherit the reasoning.
138
- [ -f "$BRIEFING_MD" ]
139
- run grep -nE 'P126|halt[- ]paths[- ]must[- ]route|halt-paths-must-route-design-questions-through-Step-2\.5' "$BRIEFING_MD"
140
- [ "$status" -eq 0 ]
141
- }
142
-
143
- @test "work-problems P126: Briefing entry cross-references P122" {
144
- # Architect-flagged refinement: the briefing entry must cite both
145
- # P122 (parent) and P126 (extension) so the principle's evolution is
146
- # traceable.
147
- run grep -nE 'P122' "$BRIEFING_MD"
148
- [ "$status" -eq 0 ]
149
- }
@@ -1,191 +0,0 @@
1
- #!/usr/bin/env bats
2
-
3
- # Step 3.5 behavioural fixture per RFC-016 + P344:
4
- # work-problems orchestrator predicate-checks the cited JTBDs of the
5
- # selected ticket BEFORE dispatching the iter-worker. The predicate
6
- # decision lives in `packages/itil/scripts/check-ticket-jtbd-ratification.sh`
7
- # so the SKILL.md Step 3.5 prose is a thin source-and-call wrapper around
8
- # a behaviorally-testable shell script (P081 / user feedback: prefer
9
- # behavioural over structural-grep tests).
10
- #
11
- # Polarity (RFC-016 § Scope):
12
- # exit 0 = all cited JTBDs ratified (or none cited) → orchestrator proceeds
13
- # with the dispatch
14
- # exit 1 = ≥1 cited JTBD unratified; one ID per stdout line, `(unresolved)`
15
- # tag for the per-JTBD predicate's exit-2 cases → orchestrator
16
- # routes to user-answerable skip + queues outstanding_question
17
- # exit 2 = ticket file missing / unreadable → halt
18
- #
19
- # Cases covered (per RFC-016 § Verification + § Tasks bats coverage):
20
- # 1. Helper exists at the contracted PATH-shim location.
21
- # 2. Ticket cites no JTBDs at all → exit 0 (vacuous-pass).
22
- # 3. Ticket cites a ratified JTBD (frontmatter `human-oversight: confirmed`)
23
- # → exit 0.
24
- # 4. Ticket cites an unratified JTBD → exit 1 + ID on stdout.
25
- # 5. Ticket cites an unresolved JTBD ID (no matching JTBD file) → exit 1
26
- # + `(unresolved)` tag.
27
- # 6. Ticket file missing → exit 2.
28
- # 7. Missing per-JTBD predicate shim → silent-pass exit 0 (ADR-031
29
- # degenerate adopter case).
30
-
31
- setup() {
32
- REPO_ROOT="$(cd "$(dirname "$BATS_TEST_FILENAME")/../../../../.." && pwd)"
33
- SHIM="$REPO_ROOT/packages/itil/bin/wr-itil-check-ticket-jtbd-ratification"
34
-
35
- FIXTURE="$(mktemp -d)"
36
- mkdir -p "$FIXTURE/docs/jtbd/developer"
37
- mkdir -p "$FIXTURE/docs/problems/open"
38
-
39
- # Shim search PATH: put the real per-JTBD predicate shim on PATH so the
40
- # helper can dispatch it. The helper resolves shims through PATH per
41
- # ADR-049 — no source-relative paths.
42
- export PATH="$REPO_ROOT/packages/jtbd/bin:$PATH"
43
- }
44
-
45
- teardown() {
46
- rm -rf "$FIXTURE"
47
- }
48
-
49
- @test "shim exists at the contracted PATH location" {
50
- [ -f "$SHIM" ]
51
- [ -x "$SHIM" ]
52
- }
53
-
54
- @test "case 1: ticket cites no JTBDs → exit 0 (vacuous-pass)" {
55
- cat > "$FIXTURE/docs/problems/open/999-no-jtbds.md" <<'EOF'
56
- # Problem 999: ticket with no JTBD citations
57
-
58
- **Status**: Open
59
-
60
- ## Description
61
-
62
- This ticket has no Decision Drivers section and no JTBD citations.
63
- EOF
64
- cd "$FIXTURE"
65
- run "$SHIM" "docs/problems/open/999-no-jtbds.md"
66
- [ "$status" -eq 0 ]
67
- [ -z "$output" ]
68
- }
69
-
70
- @test "case 2: ticket cites a ratified JTBD → exit 0" {
71
- cat > "$FIXTURE/docs/jtbd/developer/JTBD-501-ratified.md" <<'EOF'
72
- ---
73
- human-oversight: confirmed
74
- ---
75
-
76
- # JTBD-501: A ratified job
77
- EOF
78
- cat > "$FIXTURE/docs/problems/open/998-cites-ratified.md" <<'EOF'
79
- # Problem 998: cites a ratified JTBD
80
-
81
- ## Decision Drivers
82
-
83
- - JTBD-501 — A ratified job
84
- EOF
85
- cd "$FIXTURE"
86
- run "$SHIM" "docs/problems/open/998-cites-ratified.md"
87
- [ "$status" -eq 0 ]
88
- [ -z "$output" ]
89
- }
90
-
91
- @test "case 3: ticket cites an unratified JTBD → exit 1 + ID stdout" {
92
- # Unratified = no `human-oversight: confirmed` frontmatter.
93
- cat > "$FIXTURE/docs/jtbd/developer/JTBD-502-unratified.md" <<'EOF'
94
- ---
95
- status: proposed
96
- ---
97
-
98
- # JTBD-502: An unratified job (no human-oversight: confirmed)
99
- EOF
100
- cat > "$FIXTURE/docs/problems/open/997-cites-unratified.md" <<'EOF'
101
- # Problem 997: cites an unratified JTBD
102
-
103
- ## Decision Drivers
104
-
105
- - JTBD-502 — An unratified job
106
- EOF
107
- cd "$FIXTURE"
108
- run "$SHIM" "docs/problems/open/997-cites-unratified.md"
109
- [ "$status" -eq 1 ]
110
- [[ "$output" == *"JTBD-502"* ]]
111
- }
112
-
113
- @test "case 4: ticket cites an unresolved JTBD ID → exit 1 + (unresolved) tag" {
114
- cat > "$FIXTURE/docs/problems/open/996-cites-unresolved.md" <<'EOF'
115
- # Problem 996: cites an unresolved JTBD ID
116
-
117
- ## Decision Drivers
118
-
119
- - JTBD-999 — Does not exist
120
- EOF
121
- cd "$FIXTURE"
122
- run "$SHIM" "docs/problems/open/996-cites-unresolved.md"
123
- [ "$status" -eq 1 ]
124
- [[ "$output" == *"JTBD-999"* ]]
125
- [[ "$output" == *"(unresolved)"* ]]
126
- }
127
-
128
- @test "case 5: ticket file missing → exit 2" {
129
- cd "$FIXTURE"
130
- run "$SHIM" "docs/problems/open/nonexistent.md"
131
- [ "$status" -eq 2 ]
132
- }
133
-
134
- @test "case 6: missing per-JTBD predicate shim → silent-pass exit 0" {
135
- # Strip ALL per-JTBD predicate shim locations from PATH (source-repo
136
- # packages/jtbd/bin AND the global plugin install cache); degenerate
137
- # adopter case (ADR-031). The helper should silent-pass (exit 0) rather
138
- # than fail.
139
- cat > "$FIXTURE/docs/problems/open/995-cites-unratified.md" <<'EOF'
140
- # Problem 995: cites an unratified JTBD but shim is missing
141
-
142
- ## Decision Drivers
143
-
144
- - JTBD-502 — An unratified job
145
- EOF
146
- cd "$FIXTURE"
147
- # Strip every PATH entry that exposes wr-jtbd-is-job-or-persona-unconfirmed.
148
- # Both packages/jtbd/bin (source-repo) and ~/.claude/plugins/cache/.../bin
149
- # (plugin install) must go.
150
- STRIPPED_PATH=""
151
- while IFS= read -r entry; do
152
- [ -z "$entry" ] && continue
153
- if [ -x "$entry/wr-jtbd-is-job-or-persona-unconfirmed" ]; then
154
- continue
155
- fi
156
- STRIPPED_PATH="${STRIPPED_PATH}${entry}:"
157
- done < <(printf '%s' "$PATH" | tr ':' '\n')
158
- PATH="${STRIPPED_PATH%:}" run "$SHIM" "docs/problems/open/995-cites-unratified.md"
159
- [ "$status" -eq 0 ]
160
- }
161
-
162
- @test "case 7: ticket cites multiple JTBDs, one unratified → exit 1 + unratified ID only" {
163
- cat > "$FIXTURE/docs/jtbd/developer/JTBD-503-ratified.md" <<'EOF'
164
- ---
165
- human-oversight: confirmed
166
- ---
167
-
168
- # JTBD-503: A ratified job
169
- EOF
170
- cat > "$FIXTURE/docs/jtbd/developer/JTBD-504-unratified.md" <<'EOF'
171
- ---
172
- status: proposed
173
- ---
174
-
175
- # JTBD-504: An unratified job
176
- EOF
177
- cat > "$FIXTURE/docs/problems/open/994-cites-mixed.md" <<'EOF'
178
- # Problem 994: cites both ratified and unratified JTBDs
179
-
180
- ## Decision Drivers
181
-
182
- - JTBD-503 — A ratified job
183
- - JTBD-504 — An unratified job
184
- EOF
185
- cd "$FIXTURE"
186
- run "$SHIM" "docs/problems/open/994-cites-mixed.md"
187
- [ "$status" -eq 1 ]
188
- [[ "$output" == *"JTBD-504"* ]]
189
- # Ratified IDs are NOT echoed — only the unratified set.
190
- [[ "$output" != *"JTBD-503"* ]]
191
- }
@@ -1,91 +0,0 @@
1
- #!/usr/bin/env bats
2
- # Doc-lint guard: work-problems SKILL.md Step 5 iteration prompt body must
3
- # carry a prompt-discipline rule forbidding the bash-until-loop bats-output-
4
- # polling antipattern that caused P146.
5
- #
6
- # Antipattern (observed 2026-04-29, iter 1, PID 23580 child PID 16408 —
7
- # 68m34s wall-clock burn + lost JSON metadata):
8
- # until [ -f $TASK_OUTPUT ] && grep -qE '^[0-9]+ tests?,' $TASK_OUTPUT \
9
- # 2>/dev/null; do sleep 5; done; tail -25 $TASK_OUTPUT
10
- # The regex `^[0-9]+ tests?,` matches bats's *default* (non-TAP) console-
11
- # summary line. `bats --tap` never emits that line, so the until-loop spins
12
- # forever after bats completes. Silent deadlock; no error; no exit.
13
- #
14
- # The polling idiom is NOT taught by any SKILL.md (grep across the repo
15
- # returns only this ticket itself). It is agent-learned from training data —
16
- # a generic bash + bats Bourne idiom. The fix per the ticket strategy is a
17
- # prompt-discipline rule + behavioural assertion: the iteration prompt body
18
- # must explicitly forbid the antipattern AND name a safe substitute, so the
19
- # iteration agent does not fall back on the learned idiom.
20
- #
21
- # Structural assertion — Permitted Exception under ADR-037 (SKILL.md is
22
- # explicitly a contract document; doc-lint contract assertion against the
23
- # contract document itself is the named permitted pattern; same rationale
24
- # as work-problems-step-5-delegation.bats's @problem P083 / P089 fixtures).
25
- # Behavioural alternative would require spawning a real `claude -p`
26
- # subprocess and observing its tool-call traces; that harness sits outside
27
- # the skill layer.
28
- #
29
- # @problem P146
30
- # @jtbd JTBD-006
31
- # @jtbd JTBD-001
32
- # @jtbd JTBD-101
33
- #
34
- # Cross-reference:
35
- # P146 (bash until-loop polls bats output with bats-console regex against
36
- # TAP-format) — driver for this clause
37
- # P147 (sibling — SIGTERM-flush metadata-loss caveat fires when an iter
38
- # deadlocks before ITERATION_SUMMARY emission; P146's regex-poll is the
39
- # concrete mechanism behind today's stuck-before-emit incident)
40
- # ADR-037 (skill testing strategy — contract-assertion Permitted Exception)
41
- # ADR-014 (single-commit grain — fix + bats + ticket transition land
42
- # together)
43
-
44
- setup() {
45
- SKILL_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
46
- SKILL_FILE="${SKILL_DIR}/SKILL.md"
47
- }
48
-
49
- @test "SKILL.md Step 5 iteration prompt forbids bats-console-summary regex polling (P146)" {
50
- # The iteration prompt body MUST explicitly name the antipattern so the
51
- # iteration agent does not reach for the learned bash idiom. The
52
- # prohibition phrase must reference the regex-poll-on-bats-output shape
53
- # OR the bats-console-summary line shape, since both are the failure
54
- # surface today.
55
- run grep -niE "do not poll.{0,40}bats|bats.{0,40}console.summary.{0,40}regex|never poll.{0,40}bats|grep.{0,20}tests\\?,.{0,80}(forbidden|antipattern|do not|never)" "$SKILL_FILE"
56
- [ "$status" -eq 0 ]
57
- }
58
-
59
- @test "SKILL.md Step 5 iteration prompt names a safe substitute for backgrounded bats waits (P146)" {
60
- # Forbidding the antipattern without naming a substitute leaves the agent
61
- # without a path forward, and the agent will silently fall back on the
62
- # antipattern. The prompt must name `wait \$bg_pid` (Unix idiom) OR the
63
- # Bash tool's `run_in_background=true` + BashOutput check (Claude Code
64
- # idiom) as the recommended replacement.
65
- run grep -niE "wait[[:space:]]+[\"']?\\\$[A-Z_]*pid|wait[[:space:]]+[\"']?\\\$[A-Z_]*PID|run_in_background.{0,80}BashOutput|BashOutput.{0,80}run_in_background|background.{0,40}wait.{0,40}exit" "$SKILL_FILE"
66
- [ "$status" -eq 0 ]
67
- }
68
-
69
- @test "SKILL.md Step 5 bats-polling clause cites P146 (self-documenting contract)" {
70
- # The clause must cite P146 inline so a future contributor reading the
71
- # rule understands why it exists before deleting it (mirrors the P083
72
- # ScheduleWakeup-clause discipline already in place at line ~301).
73
- run grep -nE "P146" "$SKILL_FILE"
74
- [ "$status" -eq 0 ]
75
- }
76
-
77
- @test "SKILL.md Step 5 bats-polling clause names the TAP/console-summary divergence (P146)" {
78
- # The clause must explain WHY the regex `^[0-9]+ tests?,` fails — the
79
- # divergence between bats's default (console-summary) and `--tap` output
80
- # formats. Without this, a future contributor who switches from `--tap`
81
- # to default formatting may "fix" the rule incorrectly.
82
- run grep -niE "TAP.{0,80}console.summary|console.summary.{0,80}TAP|--tap.{0,80}(does not|never|no console summary)|tap.format.{0,80}(does not|never).{0,40}emit" "$SKILL_FILE"
83
- [ "$status" -eq 0 ]
84
- }
85
-
86
- @test "SKILL.md Related section cites P146" {
87
- # Self-documenting contract: ticket cited in Related so a future reader
88
- # of the file finds the driving incident without scrolling to find it.
89
- run grep -nE "P146" "$SKILL_FILE"
90
- [ "$status" -eq 0 ]
91
- }