@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,389 +0,0 @@
1
- #!/usr/bin/env bats
2
- # Behavioural fixtures for /wr-itil:capture-problem (P155).
3
- #
4
- # Per ADR-052 (Behavioural-tests-default for skill testing), these tests
5
- # exercise the load-bearing primitives the skill dispatches and assert
6
- # observable state — NOT the prose contents of SKILL.md.
7
- #
8
- # Behavioural surfaces under test:
9
- # 1. P119 create-gate composition — capture-problem must source the
10
- # session-id + create-gate helpers and call mark_step2_complete
11
- # before the Write so the PreToolUse hook permits the new ticket
12
- # file to land. Test simulates the helper-sourcing sequence and
13
- # asserts the marker file lands in /tmp.
14
- # 2. Skeleton-fill ticket shape — captured ticket has Description from
15
- # $ARGUMENTS plus the deferred-placeholder fields the skill
16
- # prescribes. Test runs the skeleton-fill command sequence against
17
- # a fixture description and asserts the resulting file's sections.
18
- # 3. Next-ID computation — capture-problem reuses the manage-problem
19
- # Step 3 P056-safe local_max + origin_max formula. Test runs the
20
- # formula against a fixture problems directory and asserts the
21
- # computed next ID matches the expected zero-padded value.
22
- # 4. Conservative title-only duplicate-grep — 3-keyword cap, filename
23
- # matches only (NOT body). Test runs the grep pattern against a
24
- # fixture and asserts the conservative match shape.
25
- #
26
- # @problem P155
27
- # @jtbd JTBD-001 (enforce governance without slowing down — lightweight
28
- # capture path)
29
- # @jtbd JTBD-006 (progress backlog while AFK — sibling-finding capture
30
- # in iter subprocesses)
31
- # @jtbd JTBD-101 (extend the suite — discoverable / on / autocomplete)
32
- # @adr ADR-032 (governance skill invocation patterns — foreground-
33
- # lightweight-capture variant)
34
- # @adr ADR-038 (progressive disclosure — SKILL.md + REFERENCE.md split)
35
- # @adr ADR-049 (bin/ on PATH — capture-problem reuses existing
36
- # wr-itil-reconcile-readme shim, no new shim needed)
37
- # @adr ADR-052 (behavioural-tests-default — these tests exercise
38
- # primitives, not SKILL.md prose)
39
- # @adr ADR-119 (manage-problem create-gate — capture-problem composes
40
- # with the same per-session marker)
41
-
42
- setup() {
43
- REPO_ROOT="$(cd "$(dirname "$BATS_TEST_FILENAME")/../../../../.." && pwd)"
44
- SKILL_DIR="${REPO_ROOT}/packages/itil/skills/capture-problem"
45
- SKILL_FILE="${SKILL_DIR}/SKILL.md"
46
- REF_FILE="${SKILL_DIR}/REFERENCE.md"
47
- CREATE_GATE_LIB="${REPO_ROOT}/packages/itil/hooks/lib/create-gate.sh"
48
-
49
- # Fresh per-test scratch directory and SESSION_ID.
50
- TMPROOT=$(mktemp -d)
51
- TEST_SESSION_ID="capture-problem-bats-$BATS_TEST_NUMBER-$$"
52
- MARKER_PATH="/tmp/manage-problem-grep-${TEST_SESSION_ID}"
53
- rm -f "$MARKER_PATH"
54
- }
55
-
56
- teardown() {
57
- rm -rf "$TMPROOT"
58
- rm -f "$MARKER_PATH"
59
- }
60
-
61
- # ---------------------------------------------------------------------------
62
- # Existence / wiring tests — minimum surface required for the skill to be
63
- # discoverable. Not structural prose-greps; these assert artefacts exist.
64
- # ---------------------------------------------------------------------------
65
-
66
- @test "capture-problem: SKILL.md and REFERENCE.md both exist (ADR-038 split)" {
67
- [ -f "$SKILL_FILE" ]
68
- [ -f "$REF_FILE" ]
69
- }
70
-
71
- @test "capture-problem: SKILL.md frontmatter declares wr-itil:capture-problem name" {
72
- # Discoverable on / autocomplete depends on the canonical name.
73
- # ADR-032 names this skill; ADR-010-amended skill-granularity rule.
74
- run grep -E '^name: wr-itil:capture-problem$' "$SKILL_FILE"
75
- [ "$status" -eq 0 ]
76
- }
77
-
78
- # ---------------------------------------------------------------------------
79
- # P119 create-gate composition — load-bearing behavioural primitive.
80
- # capture-problem must call mark_step2_complete before any Write of a new
81
- # ticket file, otherwise the PreToolUse:Write hook denies the Write.
82
- # ---------------------------------------------------------------------------
83
-
84
- @test "capture-problem: mark_step2_complete writes marker the P119 hook checks" {
85
- # Source the helper the skill prescribes; call the canonical mark
86
- # function; assert the marker file lands at the path the hook reads.
87
- source "$CREATE_GATE_LIB"
88
- mark_step2_complete "$TEST_SESSION_ID"
89
- [ -f "$MARKER_PATH" ]
90
- }
91
-
92
- @test "capture-problem: check_create_gate returns 0 after mark_step2_complete" {
93
- # Composes with manage-problem-enforce-create.sh which uses
94
- # check_create_gate $SESSION_ID — exit 0 means "permit Write".
95
- source "$CREATE_GATE_LIB"
96
- run check_create_gate "$TEST_SESSION_ID"
97
- [ "$status" -ne 0 ] # before mark — denied
98
- mark_step2_complete "$TEST_SESSION_ID"
99
- run check_create_gate "$TEST_SESSION_ID"
100
- [ "$status" -eq 0 ] # after mark — permitted
101
- }
102
-
103
- @test "capture-problem: mark_step2_complete is idempotent across cross-skill order" {
104
- # Whether manage-problem fires first then capture-problem, or vice
105
- # versa, the marker mechanic is a no-op after the first call.
106
- source "$CREATE_GATE_LIB"
107
- mark_step2_complete "$TEST_SESSION_ID"
108
- mark_step2_complete "$TEST_SESSION_ID"
109
- mark_step2_complete "$TEST_SESSION_ID"
110
- [ -f "$MARKER_PATH" ]
111
- }
112
-
113
- # ---------------------------------------------------------------------------
114
- # Next-ID computation — capture-problem reuses manage-problem Step 3 formula
115
- # ---------------------------------------------------------------------------
116
-
117
- @test "capture-problem: next-ID formula is P056-safe (origin/local max + 1)" {
118
- # Build a fixture problems directory with mixed status suffixes.
119
- # The formula must pick the max ID across all suffixes and zero-pad.
120
- mkdir -p "$TMPROOT/docs/problems"
121
- : > "$TMPROOT/docs/problems/001-foo.closed.md"
122
- : > "$TMPROOT/docs/problems/042-bar.open.md"
123
- : > "$TMPROOT/docs/problems/099-baz.known-error.md"
124
- : > "$TMPROOT/docs/problems/107-qux.verifying.md"
125
-
126
- # Mirror manage-problem Step 3 local-max formula exactly.
127
- local_max=$(ls "$TMPROOT/docs/problems"/*.md 2>/dev/null \
128
- | sed 's/.*\///' \
129
- | grep -oE '^[0-9]+' \
130
- | sort -n | tail -1)
131
- [ "$local_max" = "107" ]
132
-
133
- # No origin available in the fixture; default to 0 then increment.
134
- next=$(printf '%03d' $(( 10#$(echo -e "${local_max:-0}\n0" | sort -n | tail -1) + 1 )))
135
- [ "$next" = "108" ]
136
- }
137
-
138
- @test "capture-problem: next-ID handles empty problems dir (first ticket)" {
139
- mkdir -p "$TMPROOT/docs/problems"
140
- local_max=$(ls "$TMPROOT/docs/problems"/*.md 2>/dev/null \
141
- | sed 's/.*\///' \
142
- | grep -oE '^[0-9]+' \
143
- | sort -n | tail -1)
144
- next=$(printf '%03d' $(( 10#$(echo -e "${local_max:-0}\n0" | sort -n | tail -1) + 1 )))
145
- [ "$next" = "001" ]
146
- }
147
-
148
- @test "capture-problem: next-ID handles 099 → 100 transition without octal-eval failure (P164)" {
149
- # P164 regression: bash $(( ... )) parses leading-zero numbers as octal.
150
- # `099` is invalid octal (digits >= 8). Without `10#` prefix, this fires:
151
- # bash: 099: value too great for base (error token is "099")
152
- # The fix is the standard `10#` base-10 prefix on the inner $(echo ... | tail -1).
153
- mkdir -p "$TMPROOT/docs/problems"
154
- : > "$TMPROOT/docs/problems/098-foo.open.md"
155
- : > "$TMPROOT/docs/problems/099-bar.open.md"
156
-
157
- local_max=$(ls "$TMPROOT/docs/problems"/*.md 2>/dev/null \
158
- | sed 's/.*\///' \
159
- | grep -oE '^[0-9]+' \
160
- | sort -n | tail -1)
161
- [ "$local_max" = "099" ]
162
-
163
- next=$(printf '%03d' $(( 10#$(echo -e "${local_max:-0}\n0" | sort -n | tail -1) + 1 )))
164
- [ "$next" = "100" ]
165
- }
166
-
167
- # ---------------------------------------------------------------------------
168
- # Conservative duplicate-grep — title-only filename match, 3-keyword cap.
169
- # Architect Q1 verdict: title-only because conservative threshold rationale
170
- # (P155 line 24) — false-positives on body text would either over-prompt
171
- # or be silently swallowed (capture-problem has no AskUserQuestion).
172
- # ---------------------------------------------------------------------------
173
-
174
- @test "capture-problem: duplicate-grep matches kebab-cased keywords in filenames" {
175
- mkdir -p "$TMPROOT/docs/problems"
176
- : > "$TMPROOT/docs/problems/050-checkpoint-stuck-saving.open.md"
177
- : > "$TMPROOT/docs/problems/051-foul-drawn-garbled.closed.md"
178
-
179
- # Description: "checkpoint stuck on save retry" — extract 3 kebab tokens.
180
- # Title-only grep against filenames; bodies are NOT scanned (conservative).
181
- match_count=$(ls "$TMPROOT/docs/problems"/*.md \
182
- | grep -ciE 'checkpoint|stuck|save' || true)
183
- [ "$match_count" -ge 1 ]
184
- }
185
-
186
- @test "capture-problem: duplicate-grep does NOT match keywords in body content (title-only)" {
187
- mkdir -p "$TMPROOT/docs/problems"
188
- # File whose title has zero overlap but whose body mentions checkpoint
189
- cat > "$TMPROOT/docs/problems/060-unrelated.open.md" <<'EOF'
190
- # Unrelated ticket
191
- Body mentions checkpoint somewhere but title doesn't.
192
- EOF
193
-
194
- # Title-only grep on filenames must NOT match.
195
- match_count=$(ls "$TMPROOT/docs/problems"/*.md \
196
- | grep -ciE 'checkpoint' || true)
197
- [ "$match_count" -eq 0 ]
198
- }
199
-
200
- # ---------------------------------------------------------------------------
201
- # Skeleton-fill ticket shape — capture-problem DERIVES the Priority/Effort
202
- # rating at capture (P375 / ADR-032 amendment 2026-06-24). NO deferred false-
203
- # low placeholder. The ADR-026 sentinel `not estimated — no prior data` is the
204
- # residual re-rate signal, emitted only when no comparable prior grounds the
205
- # rating.
206
- # ---------------------------------------------------------------------------
207
-
208
- @test "capture-problem: skeleton ticket carries a DERIVED rating, not a deferred false-low" {
209
- mkdir -p "$TMPROOT/docs/problems/open"
210
- TITLE="example-aside-finding"
211
- ID="200"
212
- TODAY=$(date -u +%Y-%m-%d)
213
- DESCRIPTION="Quick observation worth a ticket but not blocking."
214
-
215
- # Mirror the SKILL.md Step 4a + Step 4 template: a derived rating (real
216
- # Impact × Likelihood) — a real best-effort value, NO deferral marker of
217
- # any kind (no "deferred — re-rate", no "not estimated" sentinel).
218
- cat > "$TMPROOT/docs/problems/open/${ID}-${TITLE}.md" <<EOF
219
- # Problem ${ID}: ${TITLE}
220
-
221
- **Status**: Open
222
- **Reported**: ${TODAY}
223
- **Priority**: 6 (Medium) — Impact: 3 × Likelihood: 2
224
- **Effort**: M
225
-
226
- ## Description
227
-
228
- ${DESCRIPTION}
229
-
230
- ## Symptoms
231
-
232
- (deferred to investigation)
233
-
234
- ## Root Cause Analysis
235
-
236
- ### Investigation Tasks
237
-
238
- - [ ] Investigate root cause
239
- - [ ] Create reproduction test
240
-
241
- ## Related
242
-
243
- (captured via /wr-itil:capture-problem; expand at next investigation)
244
- EOF
245
-
246
- TICKET="$TMPROOT/docs/problems/open/${ID}-${TITLE}.md"
247
- [ -f "$TICKET" ]
248
- run grep -F '**Status**: Open' "$TICKET"
249
- [ "$status" -eq 0 ]
250
- run grep -F "$DESCRIPTION" "$TICKET"
251
- [ "$status" -eq 0 ]
252
-
253
- # The dropped false-low default MUST NOT appear.
254
- run grep -F 'deferred — re-rate at next /wr-itil:review-problems' "$TICKET"
255
- [ "$status" -ne 0 ]
256
- run grep -F 'Re-rate Priority and Effort at next /wr-itil:review-problems' "$TICKET"
257
- [ "$status" -ne 0 ]
258
- run grep -F 'Likelihood: 1 (deferred' "$TICKET"
259
- [ "$status" -ne 0 ]
260
- # No "not estimated" sentinel either — that is just another deferral
261
- # (user correction 2026-06-24). Every capture carries a real value.
262
- run grep -F 'not estimated' "$TICKET"
263
- [ "$status" -ne 0 ]
264
-
265
- # A real derived Impact × Likelihood is present (not the buried false-low).
266
- run grep -E 'Impact: [1-5] (×|x) Likelihood: [1-5]' "$TICKET"
267
- [ "$status" -eq 0 ]
268
- # And a real Effort bucket with no trailing deferral marker.
269
- run grep -E '^\*\*Effort\*\*: (S|M|L|XL)$' "$TICKET"
270
- [ "$status" -eq 0 ]
271
- }
272
-
273
- # ---------------------------------------------------------------------------
274
- # Skill-allowed-tools surface contract — capture-problem MUST NOT carry
275
- # AskUserQuestion (per design Q4 + ADR-044 framework-mediated mechanical-
276
- # stage decisions). This is observable from the frontmatter declaration
277
- # the runtime consumes.
278
- # ---------------------------------------------------------------------------
279
-
280
- @test "capture-problem: allowed-tools includes AskUserQuestion (I12 derive-then-ratify dispatch — ADR-060 Amendment 2026-06-02)" {
281
- # Amended 2026-06-02: the I12 derive-then-ratify contract (ADR-060
282
- # Amendment 2026-06-02) requires AskUserQuestion for the derive-failure
283
- # ratification fallback (REJECT / option-pick / free-text correction
284
- # semantics). Pre-amendment contract was "no AskUserQuestion at all";
285
- # the amendment promoted persona+JTBD anchoring from optional to
286
- # required-via-ratification, applies to ALL problems (no type-keyed
287
- # gating). The historical no-AskUserQuestion contract is preserved at
288
- # the derive-success paths (silent-framework per ADR-044 cat 4); the
289
- # AskUserQuestion fires only on derive-failure (ADR-044 cat 1
290
- # direction-setting). See SKILL.md Step 1.5b dispatch + Rule 6 row.
291
- run grep -E '^allowed-tools:' "$SKILL_FILE"
292
- [ "$status" -eq 0 ]
293
- run grep -E '^allowed-tools:.*AskUserQuestion' "$SKILL_FILE"
294
- [ "$status" -eq 0 ]
295
- }
296
-
297
- @test "capture-problem: allowed-tools includes Bash (for create-gate marker write)" {
298
- # mark_step2_complete via Bash is the load-bearing primitive — without
299
- # Bash in allowed-tools the skill cannot satisfy P119.
300
- run grep -E '^allowed-tools:.*Bash' "$SKILL_FILE"
301
- [ "$status" -eq 0 ]
302
- }
303
-
304
- @test "capture-problem: allowed-tools includes Write (for new ticket file)" {
305
- run grep -E '^allowed-tools:.*Write' "$SKILL_FILE"
306
- [ "$status" -eq 0 ]
307
- }
308
-
309
- # ---------------------------------------------------------------------------
310
- # Deferred-README-refresh contract — distinguishing capture-problem from
311
- # manage-problem. capture-problem must NOT stage docs/problems/README.md
312
- # in its commit (deferred to /wr-itil:review-problems).
313
- # ---------------------------------------------------------------------------
314
-
315
- @test "capture-problem: SKILL.md prescribes deferred README refresh (no inline P094 block)" {
316
- # The contract distinction from manage-problem: capture-problem does
317
- # NOT regenerate README.md inline; it defers to /wr-itil:review-problems.
318
- # This is a behavioural primitive — a future maintainer who copies the
319
- # P094 block over would break the lightweight-capture promise.
320
- # Asserts the SKILL.md names the deferred contract explicitly.
321
- run grep -F '/wr-itil:review-problems' "$SKILL_FILE"
322
- [ "$status" -eq 0 ]
323
- }
324
-
325
- # ---------------------------------------------------------------------------
326
- # P287 (2026-06-02) — retirement of P185 Step 1.5 derive-first classifier.
327
- #
328
- # The type-classification axis was REMOVED per twice-confirmed user
329
- # direction (2026-05-25 + 2026-06-02). The lexical-signal classifier,
330
- # stderr-advisory contract, flag pre-resolution dispatch, and
331
- # meta-recursive corpus assertions that lived here have been removed —
332
- # they exercise behaviour that no longer exists in capture-problem.
333
- #
334
- # The P287 regression guards (capture-problem skeleton template has no
335
- # **Type**: line; SKILL.md has no Step 1.5 Type classification header;
336
- # no committed ticket carries a **Type**: body field; the helper has
337
- # no lexical_classify_two_sided function) live in the sibling fixture
338
- # packages/itil/scripts/test/no-type-regression-guard.bats.
339
- # ---------------------------------------------------------------------------
340
-
341
- # (P287: classifier + advisory + flag-precedence + meta-recursive tests
342
- # retired with the type axis. Regression guards now live in
343
- # packages/itil/scripts/test/no-type-regression-guard.bats.)
344
-
345
- # ---------------------------------------------------------------------------
346
- # P281 — ADR-031 per-state-subdir layout conformance on the SKILL.md
347
- # write-target path template.
348
- #
349
- # Surface 2 / structural-grep is justified here per ADR-052 § Surface 2
350
- # escape-hatch contract: the SKILL.md path template IS the contract surface
351
- # that adopter-side agents read literally. Concrete observed regression
352
- # (voder-mcp-hub commit 6c73880) landed a ticket at the pre-ADR-031 flat
353
- # path because the SKILL.md template named the flat shape. No pure-bash
354
- # script equivalent exists to behaviourally test against — the test target
355
- # IS the agent-driven prose instruction. Drift here re-opens the P281
356
- # regression vector.
357
- # ---------------------------------------------------------------------------
358
-
359
- @test "P281: SKILL.md Step 4 File-path template names per-state-subdir layout (ADR-031)" {
360
- # The contract surface: the literal `**File path**:` declaration in
361
- # Step 4 of SKILL.md. Must name `docs/problems/open/<NNN>-<kebab-title>.md`
362
- # per ADR-031 (accepted + human-oversight: confirmed), NOT the pre-ADR-031
363
- # flat shape `docs/problems/<NNN>-<kebab-title>.open.md`.
364
- run grep -F '**File path**: `docs/problems/open/<NNN>-<kebab-title>.md`' "$SKILL_FILE"
365
- [ "$status" -eq 0 ]
366
- }
367
-
368
- @test "P281: SKILL.md Step 4-5-6 path declarations do NOT carry the pre-ADR-031 flat shape" {
369
- # Negative assertion: none of the SKILL.md write-target path declarations
370
- # may name the flat `docs/problems/<NNN>-<kebab-title>.open.md` shape.
371
- # The voder-mcp-hub P032 regression (commit 6c73880) was driven by this
372
- # literal text appearing in SKILL.md and being followed by an adopter-side
373
- # agent. Title-anchored grep — body-text mentions of the old shape (e.g.
374
- # commit-message examples that don't actually carry the path) are fine.
375
- run grep -F 'docs/problems/<NNN>-<kebab-title>.open.md' "$SKILL_FILE"
376
- [ "$status" -ne 0 ]
377
- }
378
-
379
- @test "P281: SKILL.md Step 5 Write target names per-state-subdir layout" {
380
- # Step 5 prescribes the single Write call — must direct to per-state path.
381
- run grep -F 'Single `Write` to `docs/problems/open/<NNN>-<kebab-title>.md`' "$SKILL_FILE"
382
- [ "$status" -eq 0 ]
383
- }
384
-
385
- @test "P281: SKILL.md Step 6 git-add target names per-state-subdir layout" {
386
- # Step 6 prescribes the stage command — must reference per-state path.
387
- run grep -F 'git add docs/problems/open/<NNN>-<kebab-title>.md' "$SKILL_FILE"
388
- [ "$status" -eq 0 ]
389
- }