@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,71 +0,0 @@
1
- #!/usr/bin/env bats
2
- # Contract assertions for manage-problem's `review` subcommand forwarder (P071 split slice 2).
3
- #
4
- # Per ADR-010 amended (Skill Granularity section) + P071 phased plan:
5
- # `/wr-itil:manage-problem review` delegates to the new
6
- # `/wr-itil:review-problems` skill via a thin-router forwarder. Original
7
- # skill carries `deprecated-arguments: true` frontmatter (asserted in
8
- # the list-forwarder bats); this file asserts the review-forwarder-specific
9
- # contract.
10
- #
11
- # Structural assertion — Permitted Exception to the source-grep ban
12
- # (ADR-005 / P011 / ADR-037 contract-assertion pattern).
13
- #
14
- # @problem P071
15
- # @jtbd JTBD-001 (enforce governance without slowing down)
16
- # @jtbd JTBD-101 (extend the suite with clear patterns)
17
- #
18
- # Cross-reference:
19
- # P071: docs/problems/071-argument-based-skill-subcommands-are-not-discoverable.open.md
20
- # ADR-010 amended — split naming + forwarder contract + deprecated-arguments flag
21
- # ADR-013 Rule 1 — structured user interaction (forwarder emits systemMessage, not AskUserQuestion)
22
- # ADR-037 — contract-assertion bats pattern
23
-
24
- setup() {
25
- SKILL_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
26
- SKILL_FILE="${SKILL_DIR}/SKILL.md"
27
- }
28
-
29
- @test "manage-problem Step 1 forwards 'review' argument to /wr-itil:review-problems (P071)" {
30
- # The forwarder names the target skill explicitly so the router is legible
31
- # at the contract level. ADR-010's canonical shape: "invokes the new
32
- # named skill via the Skill tool, not via re-prompting the user".
33
- run grep -inE "/wr-itil:review-problems" "$SKILL_FILE"
34
- [ "$status" -eq 0 ]
35
- }
36
-
37
- @test "manage-problem Step 1 emits the canonical review deprecation notice (ADR-010 amended)" {
38
- # ADR-010's canonical deprecation-notice template:
39
- # "/wr-<plugin>:<old> <arg> is deprecated; use /wr-<plugin>:<new>
40
- # directly. This forwarder will be removed in <plugin>'s next major
41
- # version."
42
- # The notice MUST be emitted as a systemMessage (not AskUserQuestion)
43
- # because deprecation is informational, not decisional (ADR-013 Rule 1
44
- # structured-interaction scope). The review-forwarder notice is
45
- # distinct from the list-forwarder notice; both must co-exist verbatim.
46
- run grep -inE "is deprecated.*use /wr-itil:review-problems|deprecated.*review-problems|removed in .* next major version" "$SKILL_FILE"
47
- [ "$status" -eq 0 ]
48
- }
49
-
50
- @test "manage-problem Step 1 review-forwarder does not re-implement the review logic (P071 regression guard)" {
51
- # The forwarder must not duplicate the review logic — it must delegate.
52
- # Per ADR-010: "thin-router forwarder re-invokes the new named skill
53
- # via the Skill tool". If the forwarder grows its own re-scoring or
54
- # README-refresh logic, the deprecation window will harden into a
55
- # permanent fork. Guard against this by asserting the forwarder block
56
- # mentions "delegate" or "Skill tool" language near the
57
- # review-problems reference.
58
- run grep -inE "delegate.*review-problems|Skill tool.*review-problems|review-problems.*Skill tool" "$SKILL_FILE"
59
- [ "$status" -eq 0 ]
60
- }
61
-
62
- @test "manage-problem review-forwarder Step 1 parser no longer runs review logic inline (P071 slice 2)" {
63
- # Slice 2's defining behaviour: Step 1's `review` branch must
64
- # delegate, not run Step 9 inline. The parser line must say
65
- # "delegate to /wr-itil:review-problems", matching the shape the
66
- # list-forwarder uses in slice 1. A stale "run the review (step 9)"
67
- # line would indicate the forwarder was added without updating the
68
- # parser (common slip).
69
- run grep -nE "^- If arguments contain \"review\", \*\*delegate to \`/wr-itil:review-problems\`\*\*" "$SKILL_FILE"
70
- [ "$status" -eq 0 ]
71
- }
@@ -1,97 +0,0 @@
1
- #!/usr/bin/env bats
2
- #
3
- # packages/itil/skills/manage-problem/test/manage-problem-step-9d-recovery-path.bats
4
- #
5
- # Behavioural tests for manage-problem Step 9d's recovery-path
6
- # documentation (P135 Phase 2 / R5 / ADR-044).
7
- #
8
- # Step 9d closes verifying tickets on evidence WITHOUT firing
9
- # AskUserQuestion (per ADR-044 framework-resolution boundary).
10
- # Mirrors the run-retro Step 4a recovery-path contract.
11
- #
12
- # tdd-review: structural-permitted (justification: skill behavioural
13
- # harness pending P012 + P081 Phase 2; SKILL.md contract assertions
14
- # bridge until then; expected to migrate to behavioural form once
15
- # the harness exists)
16
- #
17
- # @problem P135 Phase 2 R5
18
- # @adr ADR-044 (Decision-Delegation Contract — closes are reversible)
19
- # @adr ADR-022 (verification-pending lifecycle)
20
- # @adr ADR-026 (cost-source grounding for in-session evidence)
21
- # @adr ADR-005 / ADR-037 (testing strategy — bridge during harness build)
22
- # @jtbd JTBD-001 / JTBD-006 / JTBD-201
23
-
24
- SKILL_FILE="${BATS_TEST_DIRNAME}/../SKILL.md"
25
-
26
- setup() {
27
- [ -f "$SKILL_FILE" ]
28
- }
29
-
30
- # ── Step 9d's close-on-evidence contract ────────────────────────────────────
31
-
32
- @test "Step 9d SKILL.md cites /wr-itil:transition-problem as the close-on-evidence dispatch target" {
33
- # Bound the search to Step 9d (not the entire file)
34
- run awk '/^\*\*Step 9d:/,/^\*\*Step 9e:/ {print}' "$SKILL_FILE"
35
- [ "$status" -eq 0 ]
36
- [[ "$output" == *"/wr-itil:transition-problem"* ]]
37
- }
38
-
39
- @test "Step 9d SKILL.md names ADR-044 framework-resolution boundary as the rationale for no-AskUserQuestion close" {
40
- run awk '/^\*\*Step 9d:/,/^\*\*Step 9e:/ {print}' "$SKILL_FILE"
41
- [ "$status" -eq 0 ]
42
- [[ "$output" == *"ADR-044"* ]]
43
- }
44
-
45
- @test "Step 9d SKILL.md cites ADR-026 grounding requirement for in-session evidence" {
46
- run awk '/^\*\*Step 9d:/,/^\*\*Step 9e:/ {print}' "$SKILL_FILE"
47
- [ "$status" -eq 0 ]
48
- [[ "$output" == *"ADR-026"* ]]
49
- }
50
-
51
- @test "Step 9d SKILL.md cites ADR-022 verification-pending lifecycle semantics" {
52
- run awk '/^\*\*Step 9d:/,/^\*\*Step 9e:/ {print}' "$SKILL_FILE"
53
- [ "$status" -eq 0 ]
54
- [[ "$output" == *"ADR-022"* ]]
55
- }
56
-
57
- # ── Recovery-path contract ──────────────────────────────────────────────────
58
-
59
- @test "Step 9d SKILL.md documents that closes are reversible" {
60
- run awk '/^\*\*Step 9d:/,/^\*\*Step 9e:/ {print}' "$SKILL_FILE"
61
- [ "$status" -eq 0 ]
62
- [[ "$output" == *"reversible"* ]]
63
- }
64
-
65
- @test "Step 9d SKILL.md names the recovery invocation (transition-problem known-error)" {
66
- run awk '/^\*\*Step 9d:/,/^\*\*Step 9e:/ {print}' "$SKILL_FILE"
67
- [ "$status" -eq 0 ]
68
- [[ "$output" == *"known-error"* ]]
69
- }
70
-
71
- @test "Step 9d SKILL.md cites 2026-04-27 P124 verifying-flip-back precedent" {
72
- run awk '/^\*\*Step 9d:/,/^\*\*Step 9e:/ {print}' "$SKILL_FILE"
73
- [ "$status" -eq 0 ]
74
- [[ "$output" == *"P124"* ]]
75
- }
76
-
77
- # ── Ambiguous-evidence preservation (no auto-close on weak evidence) ────────
78
-
79
- @test "Step 9d SKILL.md preserves the ambiguous-evidence path (left as Verification Pending)" {
80
- run awk '/^\*\*Step 9d:/,/^\*\*Step 9e:/ {print}' "$SKILL_FILE"
81
- [ "$status" -eq 0 ]
82
- [[ "$output" == *"ambiguous"* ]] || [[ "$output" == *"Verification Pending"* ]]
83
- }
84
-
85
- @test "Step 9d SKILL.md routes user disagreement through authentic-correction surface" {
86
- run awk '/^\*\*Step 9d:/,/^\*\*Step 9e:/ {print}' "$SKILL_FILE"
87
- [ "$status" -eq 0 ]
88
- [[ "$output" == *"authentic-correction"* ]] || [[ "$output" == *"P078"* ]]
89
- }
90
-
91
- # ── Step 9d output contract ─────────────────────────────────────────────────
92
-
93
- @test "Step 9d SKILL.md says output table records each close action with citation" {
94
- run awk '/^\*\*Step 9d:/,/^\*\*Step 9e:/ {print}' "$SKILL_FILE"
95
- [ "$status" -eq 0 ]
96
- [[ "$output" == *"citation"* ]] || [[ "$output" == *"output table"* ]]
97
- }
@@ -1,96 +0,0 @@
1
- #!/usr/bin/env bats
2
- # Contract assertions for manage-problem's `<NNN> <status>` transition forwarder (P071 split slice 4).
3
- #
4
- # Per ADR-010 amended (Skill Granularity section) + P071 phased plan:
5
- # `/wr-itil:manage-problem <NNN> known-error` (and the sibling close
6
- # form) delegates to the new `/wr-itil:transition-problem` skill via
7
- # a thin-router forwarder. Original skill already carries
8
- # `deprecated-arguments: true` frontmatter from slice 1; this file
9
- # asserts the transition-forwarder-specific contract.
10
- #
11
- # Note on shape: the transition forwarders are the trickiest of the
12
- # P071 phased set because the argument is `<NNN> <word>` (data +
13
- # verb). The parser must route on the PRESENCE of the verb token
14
- # (`known-error` / `verifying` / `close`) AFTER the data parameter
15
- # `<NNN>`. A bare `<NNN>` remains the legitimate update flow — it
16
- # must NOT forward. This test locks the distinction in.
17
- #
18
- # Structural assertion — Permitted Exception to the source-grep ban
19
- # (ADR-005 / P011 / ADR-037 contract-assertion pattern).
20
- #
21
- # @problem P071
22
- # @jtbd JTBD-001 (enforce governance without slowing down)
23
- # @jtbd JTBD-101 (extend the suite with clear patterns)
24
- #
25
- # Cross-reference:
26
- # P071: docs/problems/071-argument-based-skill-subcommands-are-not-discoverable.open.md
27
- # ADR-010 amended — split naming + forwarder contract + deprecated-arguments flag
28
- # ADR-013 Rule 1 — structured user interaction (forwarder emits systemMessage, not AskUserQuestion)
29
- # ADR-022 — Verification Pending is a first-class status; .verifying.md suffix on release
30
- # ADR-037 — contract-assertion bats pattern
31
-
32
- setup() {
33
- SKILL_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
34
- SKILL_FILE="${SKILL_DIR}/SKILL.md"
35
- }
36
-
37
- @test "manage-problem Step 1 forwards '<NNN> known-error' argument to /wr-itil:transition-problem (P071 slice 4)" {
38
- # The forwarder names the target skill explicitly so the router is
39
- # legible at the contract level. ADR-010's canonical shape: "invokes
40
- # the new named skill via the Skill tool, not via re-prompting the
41
- # user".
42
- run grep -inE "/wr-itil:transition-problem" "$SKILL_FILE"
43
- [ "$status" -eq 0 ]
44
- }
45
-
46
- @test "manage-problem Step 1 emits the canonical known-error transition deprecation notice (ADR-010 amended)" {
47
- # ADR-010's canonical deprecation-notice template:
48
- # "/wr-<plugin>:<old> <arg> is deprecated; use /wr-<plugin>:<new>
49
- # directly. This forwarder will be removed in <plugin>'s next major
50
- # version."
51
- # The notice MUST be emitted as a systemMessage (not AskUserQuestion)
52
- # because deprecation is informational, not decisional (ADR-013
53
- # Rule 1 scope). The transition-forwarder notice is distinct from
54
- # list + review + work forwarders; all four must co-exist verbatim.
55
- run grep -inE "is deprecated.*use /wr-itil:transition-problem|deprecated.*transition-problem|removed in .* next major version" "$SKILL_FILE"
56
- [ "$status" -eq 0 ]
57
- }
58
-
59
- @test "manage-problem Step 1 transition-forwarder does not re-implement Step 7 transition logic (P071 regression guard)" {
60
- # The forwarder must not duplicate the transition logic — it must
61
- # delegate. Per ADR-010: "thin-router forwarder re-invokes the new
62
- # named skill via the Skill tool". If the forwarder grows its own
63
- # pre-flight + P057 + P063 + P062 stack, the deprecation window
64
- # will harden into a permanent fork.
65
- run grep -inE "delegate.*transition-problem|Skill tool.*transition-problem|transition-problem.*Skill tool" "$SKILL_FILE"
66
- [ "$status" -eq 0 ]
67
- }
68
-
69
- @test "manage-problem Step 1 parser distinguishes bare <NNN> (update) from <NNN> <status> (transition)" {
70
- # Critical safety rule: a bare `<NNN>` argument must REMAIN the
71
- # update flow — it must not accidentally forward to
72
- # transition-problem. Only the `<NNN> <status>` shape (where
73
- # <status> ∈ {known-error, verifying, close}) triggers the
74
- # transition forwarder. The parser block must name both branches
75
- # so the distinction is legible at the contract level.
76
- run grep -inE "known-error|verifying|close" "$SKILL_FILE"
77
- [ "$status" -eq 0 ]
78
- # And the bare-NNN update path is still documented.
79
- run grep -inE "bare .NNN.|update flow|<NNN>.*update" "$SKILL_FILE"
80
- [ "$status" -eq 0 ]
81
- }
82
-
83
- @test "manage-problem transition-forwarder covers known-error, verifying, and close (lifecycle completeness)" {
84
- # ADR-022 codifies three transition destinations: known-error,
85
- # verifying (Verification Pending), and closed. All three must
86
- # appear in the forwarder contract so users can rely on the
87
- # forwarder for the full lifecycle during the deprecation window.
88
- # Missing any destination would force users back onto inline
89
- # execution for that one case.
90
- run grep -inE "known-error" "$SKILL_FILE"
91
- [ "$status" -eq 0 ]
92
- run grep -inE "verifying|verification.pending" "$SKILL_FILE"
93
- [ "$status" -eq 0 ]
94
- run grep -inE "\bclose\b" "$SKILL_FILE"
95
- [ "$status" -eq 0 ]
96
- }
@@ -1,365 +0,0 @@
1
- #!/usr/bin/env bats
2
- # Contract + behavioural tests: manage-problem SKILL.md must define a
3
- # transitive-dependency rule for WSJF effort, extend Step 9b with
4
- # dependency-graph traversal, and the problem-ticket template must carry
5
- # a `## Dependencies` section.
6
- #
7
- # Mixed shape — structural assertions (ADR-037 Permitted Exception) for
8
- # the contract prose Claude interprets at invocation time, AND one
9
- # behavioural fixture test that exercises the transitive-closure
10
- # algorithm directly so the rule is not merely "keyword present" (P081
11
- # pressure — behavioural where feasible).
12
- #
13
- # Cross-reference:
14
- # @problem P076 — docs/problems/076-wsjf-does-not-model-transitive-dependencies.open.md
15
- # ADR-022: verification-pending status carve-out from the closure
16
- # ADR-014: governance-skills commit their own work
17
- # ADR-037: contract-assertion bats pattern for SKILL.md prose contracts
18
- # @jtbd JTBD-001 (solo-developer — enforce governance without slowing down)
19
- # @jtbd JTBD-006 (solo-developer — progress the backlog while I'm away)
20
- # @jtbd JTBD-201 (tech-lead — restore service fast with an audit trail)
21
-
22
- setup() {
23
- SKILL_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
24
- SKILL_FILE="${SKILL_DIR}/SKILL.md"
25
- FIXTURE_DIR="$(mktemp -d)"
26
- }
27
-
28
- teardown() {
29
- [ -n "${FIXTURE_DIR:-}" ] && [ -d "$FIXTURE_DIR" ] && rm -rf "$FIXTURE_DIR"
30
- }
31
-
32
- # ──────────────────────────────────────────────────────────────────────────────
33
- # Contract: WSJF section defines the transitive-dependency rule
34
- # ──────────────────────────────────────────────────────────────────────────────
35
-
36
- @test "SKILL.md WSJF section has a Transitive dependencies subsection (P076)" {
37
- # The rule must live in a discoverable subsection so Claude finds it
38
- # when interpreting the WSJF scoring contract.
39
- run grep -nE "^### .*[Tt]ransitive [Dd]ependenc" "$SKILL_FILE"
40
- [ "$status" -eq 0 ]
41
- }
42
-
43
- @test "SKILL.md transitive rule defines effort as max(marginal, blocked-by closure) (P076)" {
44
- # The core rule: Effort(T)_transitive = max(marginal, max{blocked-by})
45
- # The prose must make the max-of relationship explicit so a dependent
46
- # ticket inherits upstream effort.
47
- run grep -inE "max.*marginal|marginal.*max|transitive.*effort|effort.*transitive" "$SKILL_FILE"
48
- [ "$status" -eq 0 ]
49
- }
50
-
51
- @test "SKILL.md transitive rule cites Blocked by as the dependency signal (P076)" {
52
- # Blocked_by is the formally-scoped edge in the ticket-dependency graph.
53
- # The rule must name it (not just generic "dependencies") so Claude knows
54
- # which `## Dependencies` row drives the effort propagation.
55
- run grep -inE "Blocked[[:space:]-]?by" "$SKILL_FILE"
56
- [ "$status" -eq 0 ]
57
- }
58
-
59
- @test "SKILL.md transitive rule carves Composes with OUT of the closure (P076)" {
60
- # Compositional overlap does NOT strictly block — sibling work that
61
- # shares surface should not inflate the dependent's effort.
62
- run grep -inE "[Cc]omposes[[:space:]]with.*not|not.*[Cc]omposes|[Cc]omposes[[:space:]]with.*does NOT|[Cc]omposes[[:space:]]with.*excluded" "$SKILL_FILE"
63
- [ "$status" -eq 0 ]
64
- }
65
-
66
- @test "SKILL.md transitive rule carves .closed / .verifying / .parked OUT of the closure (architect note)" {
67
- # Architect correction: already-done or user-blocked upstreams contribute
68
- # zero marginal dev effort — otherwise a ticket blocked by a closed
69
- # ticket would inherit XL forever.
70
- run grep -inE "(\.closed\.md|\.verifying\.md|\.parked\.md).*(contribut|0|zero|exclud)|contribut.*0.*(\.closed|\.verifying|\.parked)" "$SKILL_FILE"
71
- [ "$status" -eq 0 ]
72
- }
73
-
74
- @test "SKILL.md transitive rule documents cycle bundling (shared WSJF as computed artefact) (P076)" {
75
- # Cycles (e.g. P038/P064 mutual composition) must be handled — bundle's
76
- # effort = max of members' marginals; shared WSJF surfaced in review
77
- # output, not written as a field per-ticket (ADR-022 suffix-based pattern).
78
- run grep -inE "cycle|bundle" "$SKILL_FILE"
79
- [ "$status" -eq 0 ]
80
- }
81
-
82
- @test "SKILL.md transitive rule carries a worked example (P076)" {
83
- # Worked example: P073 marginal S blocked by P038 XL → transitive XL →
84
- # WSJF drops to match P038. The number-grounded example keeps the rule
85
- # out of hand-wavy territory (ADR-026 grounded output).
86
- run grep -inE "[Ww]orked[[:space:]]example|example.*transitive|transitive.*example" "$SKILL_FILE"
87
- [ "$status" -eq 0 ]
88
- }
89
-
90
- @test "SKILL.md transitive rule notes reassessment-criteria for future ADR extraction (architect note)" {
91
- # Architect guidance: keep a pointer for when another skill adopts the
92
- # `## Dependencies` convention — at that point, extract to a sibling ADR.
93
- # Inline note now avoids speculative ADR authoring today.
94
- run grep -inE "[Rr]eassessment|[Ee]xtract.*ADR|sibling ADR|future ADR" "$SKILL_FILE"
95
- [ "$status" -eq 0 ]
96
- }
97
-
98
- # ──────────────────────────────────────────────────────────────────────────────
99
- # Contract: Step 9b review extends to dependency-graph traversal
100
- # ──────────────────────────────────────────────────────────────────────────────
101
-
102
- @test "SKILL.md Step 9b describes a dependency-graph traversal pass (P076)" {
103
- # After per-ticket marginal scoring, Step 9b must walk the graph and
104
- # propagate effort up. The prose must name the traversal explicitly so
105
- # Claude performs the second pass, not just the first.
106
- run grep -inE "dependency[[:space:]-]?graph|graph traversal|topological.*sort|propagate.*effort|effort.*propagat" "$SKILL_FILE"
107
- [ "$status" -eq 0 ]
108
- }
109
-
110
- @test "SKILL.md Step 9b reports transitive re-rates in the review summary (P076 + JTBD-006)" {
111
- # The AFK orchestrator (JTBD-006) and the audit-trail persona (JTBD-201)
112
- # depend on Step 9b emitting a visible re-rate line — not a silent
113
- # update.
114
- run grep -inE "transitive.*(re-?rate|rerat|re-?estimat)|report.*transitive|re-?rate.*transitive" "$SKILL_FILE"
115
- [ "$status" -eq 0 ]
116
- }
117
-
118
- @test "SKILL.md Step 9b re-rate message format is concrete (architect note — bats-assertable shape)" {
119
- # Architect correction 4: specify a concrete message shape so the
120
- # contract can be grepped. Format: P<NNN>: Effort <OLD> → <NEW>
121
- # (transitive via <UPSTREAM>).
122
- run grep -inE "Effort.*→.*transitive via|transitive via.*P[0-9]" "$SKILL_FILE"
123
- [ "$status" -eq 0 ]
124
- }
125
-
126
- # ──────────────────────────────────────────────────────────────────────────────
127
- # Contract: Step 5 problem-ticket template includes `## Dependencies`
128
- # ──────────────────────────────────────────────────────────────────────────────
129
-
130
- @test "SKILL.md Step 5 template includes a ## Dependencies section (P076)" {
131
- # New tickets must carry an explicit dependency list so the graph is
132
- # legible. Empty lists are allowed (default: no deps).
133
- run grep -nE "^## Dependencies" "$SKILL_FILE"
134
- [ "$status" -eq 0 ]
135
- }
136
-
137
- @test "SKILL.md Dependencies template lists Blocks / Blocked by / Composes with rows (P076)" {
138
- # The three row labels must all be present in the template so the
139
- # author knows which semantics apply. Blocks = downstream; Blocked by =
140
- # drives effort propagation; Composes with = overlap without blocking.
141
- run grep -inE "\*\*Blocks\*\*|\*\*Blocked by\*\*|\*\*Composes with\*\*" "$SKILL_FILE"
142
- [ "$status" -eq 0 ]
143
- # All three labels must be present.
144
- blocks_hits=$(grep -cE "\*\*Blocks\*\*" "$SKILL_FILE" || true)
145
- blocked_hits=$(grep -cE "\*\*Blocked by\*\*" "$SKILL_FILE" || true)
146
- composes_hits=$(grep -cE "\*\*Composes with\*\*" "$SKILL_FILE" || true)
147
- [ "$blocks_hits" -ge 1 ]
148
- [ "$blocked_hits" -ge 1 ]
149
- [ "$composes_hits" -ge 1 ]
150
- }
151
-
152
- @test "SKILL.md Dependencies rows use bare ticket IDs (architect note Q1)" {
153
- # Bare IDs (P038) beat link syntax (`[P038](./038-...)`) — less
154
- # maintenance; review output renders to links on demand. The template
155
- # example must show bare-ID form (not `[P038](./038-...)`).
156
- # Canonical shape: `- **Blocked by**: P<NNN>, P<NNN>` — match either
157
- # bold-markdown label form or plain-label form, asserting the ID is
158
- # bare (not bracketed).
159
- run grep -inE "Blocked by\*{0,2}:[[:space:]]*P[0-9]" "$SKILL_FILE"
160
- [ "$status" -eq 0 ]
161
- # Assert the example does NOT use link syntax `[PNNN](./...)`.
162
- ! grep -E "Blocked by\*{0,2}:[[:space:]]*\[P[0-9]" "$SKILL_FILE"
163
- }
164
-
165
- # ──────────────────────────────────────────────────────────────────────────────
166
- # Traceability: P076 cited
167
- # ──────────────────────────────────────────────────────────────────────────────
168
-
169
- @test "SKILL.md cites P076 in the transitive-dependencies prose (traceability)" {
170
- # Every governance-contract change must cite the problem ticket that
171
- # motivated it — audit trail per ADR-014.
172
- run grep -n "P076" "$SKILL_FILE"
173
- [ "$status" -eq 0 ]
174
- }
175
-
176
- # ──────────────────────────────────────────────────────────────────────────────
177
- # Behavioural: exercise the transitive-closure rule with fixture tickets
178
- # ──────────────────────────────────────────────────────────────────────────────
179
- # These tests build a minimal fixture backlog and run a bash transcription
180
- # of the transitive-closure rule against it. The rule's executable form is
181
- # small enough to bash-implement; we assert the output matches the rule's
182
- # spec so a prose drift (e.g. accidentally documenting `min` instead of
183
- # `max`) would be caught at test time.
184
-
185
- # Bash transcription of the transitive-closure rule — effort map is
186
- # keyed by ticket ID, value is the integer divisor from the SKILL.md
187
- # effort table (S=1, M=2, L=4, XL=8).
188
- transitive_effort() {
189
- local ticket="$1"
190
- local backlog_dir="$2"
191
- local file
192
- file=$(ls "$backlog_dir"/${ticket}-*.md 2>/dev/null | head -1)
193
- [ -z "$file" ] && { echo 0; return; }
194
-
195
- # Extract marginal effort from the Effort line. The line shape matches
196
- # the SKILL.md Priority/Effort convention: "**Effort**: <bucket> — ..."
197
- local marginal_bucket
198
- marginal_bucket=$(grep -oE '\*\*Effort\*\*: [SMLXL]+' "$file" | head -1 | grep -oE '[SMLXL]+' | head -1)
199
- local marginal_divisor
200
- case "$marginal_bucket" in
201
- S) marginal_divisor=1 ;;
202
- M) marginal_divisor=2 ;;
203
- L) marginal_divisor=4 ;;
204
- XL) marginal_divisor=8 ;;
205
- *) marginal_divisor=2 ;; # default M
206
- esac
207
-
208
- # .closed.md / .verifying.md / .parked.md upstreams contribute 0 (architect carve-out)
209
- case "$file" in
210
- *.closed.md|*.verifying.md|*.parked.md)
211
- echo 0
212
- return
213
- ;;
214
- esac
215
-
216
- # Extract `Blocked by:` dependency IDs (bare, comma-separated).
217
- # The template shape is `- **Blocked by**: P<NNN>, P<NNN>` (markdown
218
- # list item under `## Dependencies`) — match the label with optional
219
- # leading list marker.
220
- local blocked_by_line
221
- blocked_by_line=$(grep -E "^[[:space:]]*-?[[:space:]]*\*\*Blocked by\*\*:" "$file" | head -1 | sed 's/.*\*\*Blocked by\*\*://')
222
- local max_upstream=0
223
- local dep
224
- for dep in $(echo "$blocked_by_line" | grep -oE 'P[0-9]+'); do
225
- local upstream_effort
226
- upstream_effort=$(transitive_effort "$dep" "$backlog_dir")
227
- [ "$upstream_effort" -gt "$max_upstream" ] && max_upstream="$upstream_effort"
228
- done
229
-
230
- # Transitive = max(marginal, upstream closure)
231
- if [ "$max_upstream" -gt "$marginal_divisor" ]; then
232
- echo "$max_upstream"
233
- else
234
- echo "$marginal_divisor"
235
- fi
236
- }
237
-
238
- @test "behavioural: dependent ticket inherits upstream XL when blocked by XL ticket (P076 worked example)" {
239
- # Fixture: P200 (marginal S) Blocked by: P201 (XL)
240
- # Expected: transitive effort for P200 = XL divisor = 8
241
- cat > "$FIXTURE_DIR/P201-upstream-xl.open.md" <<'EOF'
242
- # Problem 201: upstream XL ticket
243
- **Status**: Open
244
- **Effort**: XL — multi-day cross-package work
245
-
246
- ## Dependencies
247
- - **Blocked by**: (none)
248
- EOF
249
- cat > "$FIXTURE_DIR/P200-dependent-small.open.md" <<'EOF'
250
- # Problem 200: dependent with small marginal effort
251
- **Status**: Open
252
- **Effort**: S — one-line surface add
253
-
254
- ## Dependencies
255
- - **Blocked by**: P201
256
- EOF
257
- result=$(transitive_effort "P200" "$FIXTURE_DIR")
258
- [ "$result" = "8" ]
259
- }
260
-
261
- @test "behavioural: self-contained ticket keeps marginal effort (P076 no-op path)" {
262
- # Fixture: P210 (marginal M) with empty Blocked by.
263
- # Expected: transitive = marginal M divisor = 2.
264
- cat > "$FIXTURE_DIR/P210-solo-m.open.md" <<'EOF'
265
- # Problem 210: self-contained
266
- **Status**: Open
267
- **Effort**: M — couple of files
268
-
269
- ## Dependencies
270
- - **Blocked by**: (none)
271
- EOF
272
- result=$(transitive_effort "P210" "$FIXTURE_DIR")
273
- [ "$result" = "2" ]
274
- }
275
-
276
- @test "behavioural: closed upstream contributes 0 to the closure (architect carve-out)" {
277
- # Fixture: P220 (marginal S) Blocked by: P221 (was XL, now closed).
278
- # Expected: transitive = marginal S = 1 (closed upstream contributes 0;
279
- # otherwise P220 would inherit XL forever).
280
- cat > "$FIXTURE_DIR/P221-closed-xl.closed.md" <<'EOF'
281
- # Problem 221: closed upstream (was XL)
282
- **Status**: Closed
283
- **Effort**: XL
284
- EOF
285
- cat > "$FIXTURE_DIR/P220-dependent-on-closed.open.md" <<'EOF'
286
- # Problem 220: dependent on closed
287
- **Status**: Open
288
- **Effort**: S
289
-
290
- ## Dependencies
291
- - **Blocked by**: P221
292
- EOF
293
- result=$(transitive_effort "P220" "$FIXTURE_DIR")
294
- [ "$result" = "1" ]
295
- }
296
-
297
- @test "behavioural: marginal effort wins when upstream is smaller (P076 max-of semantics)" {
298
- # Fixture: P230 (marginal L = 4) Blocked by: P231 (S = 1)
299
- # Expected: transitive = max(L, S) = L divisor = 4.
300
- # (Contrast: a buggy implementation using min or sum would produce 1 or 5.)
301
- cat > "$FIXTURE_DIR/P231-small-upstream.open.md" <<'EOF'
302
- # Problem 231: small upstream
303
- **Status**: Open
304
- **Effort**: S
305
- EOF
306
- cat > "$FIXTURE_DIR/P230-big-dependent.open.md" <<'EOF'
307
- # Problem 230: bigger dependent
308
- **Status**: Open
309
- **Effort**: L
310
-
311
- ## Dependencies
312
- - **Blocked by**: P231
313
- EOF
314
- result=$(transitive_effort "P230" "$FIXTURE_DIR")
315
- [ "$result" = "4" ]
316
- }
317
-
318
- @test "behavioural: transitive propagates across two hops (P076 closure semantics)" {
319
- # Fixture: P240 (S) → blocked by P241 (S) → blocked by P242 (XL)
320
- # Expected: transitive(P240) = max(S, transitive(P241)) = max(S, max(S, XL)) = XL = 8.
321
- cat > "$FIXTURE_DIR/P242-deepest-xl.open.md" <<'EOF'
322
- # Problem 242: deepest XL
323
- **Status**: Open
324
- **Effort**: XL
325
- EOF
326
- cat > "$FIXTURE_DIR/P241-middle-s.open.md" <<'EOF'
327
- # Problem 241: middle S
328
- **Status**: Open
329
- **Effort**: S
330
-
331
- ## Dependencies
332
- - **Blocked by**: P242
333
- EOF
334
- cat > "$FIXTURE_DIR/P240-top-s.open.md" <<'EOF'
335
- # Problem 240: top S
336
- **Status**: Open
337
- **Effort**: S
338
-
339
- ## Dependencies
340
- - **Blocked by**: P241
341
- EOF
342
- result=$(transitive_effort "P240" "$FIXTURE_DIR")
343
- [ "$result" = "8" ]
344
- }
345
-
346
- @test "behavioural: verification-pending upstream contributes 0 (architect carve-out for .verifying.md)" {
347
- # Fixture: P250 (marginal S) Blocked by: P251 (was XL, now verifying).
348
- # Expected: transitive = marginal S = 1 (verifying contributes 0 — the
349
- # remaining work is user-side verification, not dev effort).
350
- cat > "$FIXTURE_DIR/P251-verifying-xl.verifying.md" <<'EOF'
351
- # Problem 251: verification pending (was XL)
352
- **Status**: Verification Pending
353
- **Effort**: XL
354
- EOF
355
- cat > "$FIXTURE_DIR/P250-dependent-on-verifying.open.md" <<'EOF'
356
- # Problem 250: dependent on verifying
357
- **Status**: Open
358
- **Effort**: S
359
-
360
- ## Dependencies
361
- - **Blocked by**: P251
362
- EOF
363
- result=$(transitive_effort "P250" "$FIXTURE_DIR")
364
- [ "$result" = "1" ]
365
- }