@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,127 +0,0 @@
1
- #!/usr/bin/env bats
2
- # Behavioural shape contract for the inbound-discovery config + cache
3
- # files (RFC-004 Slice A scaffold; consumed by Slice C orchestration).
4
- #
5
- # These assertions are BEHAVIOURAL per P081 — they parse the actual JSON
6
- # files committed under docs/problems/ and verify the documented shapes
7
- # hold. No SKILL/agent prose grep here; this is config-file content
8
- # tested via jq.
9
- #
10
- # @problem P079
11
- # @rfc RFC-004 (Slice A — scaffold; Slice E — coverage)
12
- # @adr ADR-062 (channel config + cache schemas)
13
- # @adr ADR-031 (docs/problems/ as the directory for cache + config files)
14
- # @adr ADR-052 (behavioural-tests default)
15
- # @adr ADR-037 (bats doc-lint — file-shape contracts)
16
- # @jtbd JTBD-101 (downstream-adopter non-obligation — config file is opt-in)
17
- # @jtbd JTBD-201 (audit-trail replay — cache file deterministic)
18
-
19
- setup() {
20
- REPO_ROOT="$(cd "$(dirname "$BATS_TEST_FILENAME")/../../../../.." && pwd)"
21
- CHANNELS_FILE="${REPO_ROOT}/docs/problems/.upstream-channels.json"
22
- CACHE_FILE="${REPO_ROOT}/docs/problems/.upstream-cache.json"
23
- AUDIT_LOG="${REPO_ROOT}/docs/audits/inbound-discovery-log.md"
24
- }
25
-
26
- # Skip everything if jq is absent; the maintainer's dev env has jq per
27
- # the existing risk-scorer scripts, but adopter clones may not. Fail-soft.
28
- @test "jq is available for JSON shape assertions" {
29
- command -v jq
30
- }
31
-
32
- # ──────────────────────────────────────────────────────────────────────────────
33
- # docs/problems/.upstream-channels.json (Slice A scaffold — committed)
34
- # ──────────────────────────────────────────────────────────────────────────────
35
-
36
- @test "upstream-channels.json exists" {
37
- [ -f "$CHANNELS_FILE" ]
38
- }
39
-
40
- @test "upstream-channels.json is valid JSON" {
41
- run jq '.' "$CHANNELS_FILE"
42
- [ "$status" -eq 0 ]
43
- }
44
-
45
- @test "upstream-channels.json declares the schema URL" {
46
- run jq -r '."$schema"' "$CHANNELS_FILE"
47
- [ "$status" -eq 0 ]
48
- [[ "$output" =~ upstream-channels ]]
49
- }
50
-
51
- @test "upstream-channels.json has a channels[] array" {
52
- run jq -e '.channels | type == "array"' "$CHANNELS_FILE"
53
- [ "$status" -eq 0 ]
54
- }
55
-
56
- @test "upstream-channels.json carries ttl_seconds (cache freshness)" {
57
- run jq -e '.ttl_seconds | type == "number"' "$CHANNELS_FILE"
58
- [ "$status" -eq 0 ]
59
- }
60
-
61
- @test "default config polls all three documented channel types (issues / discussions / security-advisories)" {
62
- # ADR-062 § Channel config defaults: this repo's intake polls all
63
- # three. Adopters can edit; the default exercises the full pipeline.
64
- run jq -e '[.channels[] | .type] | contains(["github-issues"])' "$CHANNELS_FILE"
65
- [ "$status" -eq 0 ]
66
- run jq -e '[.channels[] | .type] | contains(["github-discussions"])' "$CHANNELS_FILE"
67
- [ "$status" -eq 0 ]
68
- run jq -e '[.channels[] | .type] | contains(["github-security-advisories"])' "$CHANNELS_FILE"
69
- [ "$status" -eq 0 ]
70
- }
71
-
72
- @test "each channel entry has a 'type' and 'repo' field (minimum schema)" {
73
- # Every channel must name what kind (type) and which upstream (repo).
74
- # Per-type additional fields (label / template / category) are optional
75
- # and per-channel-kind-specific.
76
- run jq -e '.channels | all(has("type") and has("repo"))' "$CHANNELS_FILE"
77
- [ "$status" -eq 0 ]
78
- }
79
-
80
- # ──────────────────────────────────────────────────────────────────────────────
81
- # docs/problems/.upstream-cache.json (Slice A scaffold — committed empty)
82
- # ──────────────────────────────────────────────────────────────────────────────
83
-
84
- @test "upstream-cache.json exists" {
85
- [ -f "$CACHE_FILE" ]
86
- }
87
-
88
- @test "upstream-cache.json is valid JSON" {
89
- run jq '.' "$CACHE_FILE"
90
- [ "$status" -eq 0 ]
91
- }
92
-
93
- @test "upstream-cache.json declares the schema URL" {
94
- run jq -r '."$schema"' "$CACHE_FILE"
95
- [ "$status" -eq 0 ]
96
- [[ "$output" =~ upstream-cache ]]
97
- }
98
-
99
- @test "upstream-cache.json has last_checked field (null or ISO timestamp)" {
100
- run jq -e '.last_checked == null or (.last_checked | type == "string")' "$CACHE_FILE"
101
- [ "$status" -eq 0 ]
102
- }
103
-
104
- @test "upstream-cache.json has channels{} object (per-channel cache map)" {
105
- run jq -e '.channels | type == "object"' "$CACHE_FILE"
106
- [ "$status" -eq 0 ]
107
- }
108
-
109
- # ──────────────────────────────────────────────────────────────────────────────
110
- # docs/audits/inbound-discovery-log.md (Slice D scaffold — committed)
111
- # ──────────────────────────────────────────────────────────────────────────────
112
-
113
- @test "inbound-discovery-log.md exists" {
114
- [ -f "$AUDIT_LOG" ]
115
- }
116
-
117
- @test "inbound-discovery-log.md cites ADR-062 (audit-log surface contract)" {
118
- run grep -nE 'ADR-062' "$AUDIT_LOG"
119
- [ "$status" -eq 0 ]
120
- }
121
-
122
- @test "inbound-discovery-log.md is committed under docs/audits/ per P131 (NOT under .claude/)" {
123
- # CLAUDE.md P131: project-generated artefacts under docs/, never .claude/.
124
- # The audit-log path is intentional per ADR-062 § Audit-log surface.
125
- [[ "$AUDIT_LOG" == */docs/audits/* ]]
126
- [[ "$AUDIT_LOG" != */.claude/* ]]
127
- }
@@ -1,383 +0,0 @@
1
- #!/usr/bin/env bats
2
- # Contract assertions for /wr-itil:review-problems Step 4.5
3
- # inbound-discovery + assessment-pipeline (RFC-004 Slice C + Slice E).
4
- #
5
- # Structural assertions — Permitted Exception to the source-grep ban
6
- # per ADR-005 / P011 / ADR-037 / ADR-052 § Surface 2. SKILL.md prose
7
- # governs LLM-driven runtime behaviour; behavioural-replay testing
8
- # requires a synthetic agent harness (P012 master ticket; P176 follow-up
9
- # for the SKILL.md surface). Until that harness lands, contract bats
10
- # assert the load-bearing prompt elements are present so future edits
11
- # don't silently strip them.
12
- #
13
- # @problem P079
14
- # @rfc RFC-004
15
- # @adr ADR-062 (inbound discovery + assessment pipeline)
16
- # @adr ADR-028 (external-comms gate)
17
- # @adr ADR-044 (decision-delegation contract — category 4 mechanical-stage carve-out)
18
- # @adr ADR-052 (behavioural-tests default + Permitted Exception)
19
- # @jtbd JTBD-301 (acknowledgement contract — non-negotiable)
20
- # @jtbd JTBD-001 (mechanical-stage carve-out — preserve without slowing down)
21
- # @jtbd JTBD-006 (AFK silent path)
22
- # @jtbd JTBD-101 (downstream non-obligation)
23
- # @jtbd JTBD-201 (audit-log replay)
24
-
25
- setup() {
26
- SKILL_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
27
- SKILL_FILE="${SKILL_DIR}/SKILL.md"
28
- }
29
-
30
- # ──────────────────────────────────────────────────────────────────────────────
31
- # Step 4.5 presence + ADR-062 naming reconciliation
32
- # ──────────────────────────────────────────────────────────────────────────────
33
-
34
- @test "Step 4.5 inbound-discovery section exists in SKILL.md (RFC-004 Slice C)" {
35
- run grep -nE '^### 4\.5\. Inbound-discovery' "$SKILL_FILE"
36
- [ "$status" -eq 0 ]
37
- }
38
-
39
- @test "Step 4.5 header preserves ADR-062 'Step 8.5' substring anchor verbatim" {
40
- # ADR-062 § Confirmation criterion 1 hard-keys on the "Step 8.5"
41
- # substring. SKILL.md numbering is "Step 4.5"; header cross-references
42
- # ADR-062's "Step 8.5" verbatim so the criterion remains string-anchorable.
43
- # Do NOT strip the "Step 8.5" substring on rename.
44
- run grep -nE 'Step 8\.5' "$SKILL_FILE"
45
- [ "$status" -eq 0 ]
46
- }
47
-
48
- @test "SKILL.md preserves ADR-062 'Step 9e' substring anchor verbatim" {
49
- # ADR-062 § Confirmation criterion 1 final bullet hard-keys on the
50
- # "Step 9e" substring (the renderer is owned by Slice G; this skill
51
- # carries the cross-reference forward).
52
- run grep -nE 'Step 9e' "$SKILL_FILE"
53
- [ "$status" -eq 0 ]
54
- }
55
-
56
- @test "Step 4.5 naming-reconciliation HTML comment marker exists" {
57
- # Architect issue 1+2: preserve both "Step 8.5" and "Step 9e" anchors
58
- # via a single HTML comment so a future rename doesn't silently strip
59
- # them. Comment names ADR-062 explicitly.
60
- run grep -nE 'ADR-062-step-naming-reconciliation' "$SKILL_FILE"
61
- [ "$status" -eq 0 ]
62
- }
63
-
64
- # ──────────────────────────────────────────────────────────────────────────────
65
- # Step 4.5 sub-step structure (4.5a through 4.5g)
66
- # ──────────────────────────────────────────────────────────────────────────────
67
-
68
- @test "Step 4.5a — read channel config (docs/problems/.upstream-channels.json)" {
69
- run grep -nE '4\.5a\..*[Cc]hannel config' "$SKILL_FILE"
70
- [ "$status" -eq 0 ]
71
- run grep -nE '\.upstream-channels\.json' "$SKILL_FILE"
72
- [ "$status" -eq 0 ]
73
- }
74
-
75
- @test "Step 4.5b — cache TTL check (docs/problems/.upstream-cache.json)" {
76
- run grep -nE '4\.5b\..*[Cc]ache TTL' "$SKILL_FILE"
77
- [ "$status" -eq 0 ]
78
- run grep -nE '\.upstream-cache\.json' "$SKILL_FILE"
79
- [ "$status" -eq 0 ]
80
- }
81
-
82
- @test "Step 4.5c — polls all three GitHub channels (issues / discussions / security-advisories)" {
83
- run grep -nE 'github-issues' "$SKILL_FILE"
84
- [ "$status" -eq 0 ]
85
- run grep -nE 'github-discussions' "$SKILL_FILE"
86
- [ "$status" -eq 0 ]
87
- run grep -nE 'github-security-advisories' "$SKILL_FILE"
88
- [ "$status" -eq 0 ]
89
- }
90
-
91
- @test "Step 4.5d — P070 semantic-comparator with cross-reference comment on hit (JTBD-301)" {
92
- # Architect issue 5: JTBD-301 acknowledgement contract requires a
93
- # gated cross-reference comment on matched-local-ticket hits; silent-skip
94
- # would break the contract.
95
- run grep -nE '4\.5d.*[Mm]atch.*local' "$SKILL_FILE"
96
- [ "$status" -eq 0 ]
97
- run grep -nE 'cross-reference' "$SKILL_FILE"
98
- [ "$status" -eq 0 ]
99
- }
100
-
101
- @test "Step 4.5e — six-step assessment pipeline" {
102
- run grep -nE '4\.5e\..*[Ss]ix-step assessment pipeline' "$SKILL_FILE"
103
- [ "$status" -eq 0 ]
104
- }
105
-
106
- @test "Step 4.5f — audit-log append to docs/audits/inbound-discovery-log.md" {
107
- run grep -nE '4\.5f\..*[Aa]udit-log' "$SKILL_FILE"
108
- [ "$status" -eq 0 ]
109
- run grep -nE 'inbound-discovery-log\.md' "$SKILL_FILE"
110
- [ "$status" -eq 0 ]
111
- }
112
-
113
- @test "Step 4.5g — render-time integration seam (consumed by Slice G renderer)" {
114
- run grep -nE '4\.5g\..*[Rr]ender' "$SKILL_FILE"
115
- [ "$status" -eq 0 ]
116
- }
117
-
118
- # ──────────────────────────────────────────────────────────────────────────────
119
- # Slice G: Step 5 README template carries the ## Inbound Upstream Reports section
120
- # ──────────────────────────────────────────────────────────────────────────────
121
-
122
- @test "Step 5 README template carries the ## Inbound Upstream Reports section header (Slice G)" {
123
- run grep -nE '^## Inbound Upstream Reports$' "$SKILL_FILE"
124
- [ "$status" -eq 0 ]
125
- }
126
-
127
- @test "Slice G renderer documents the lazy-empty discipline (advisory row when no pass run)" {
128
- run grep -inE 'lazy-empty|No inbound discovery pass has run' "$SKILL_FILE"
129
- [ "$status" -eq 0 ]
130
- }
131
-
132
- @test "Slice G renderer documents the classification + matched-local-ticket columns" {
133
- run grep -inE 'Classification.*Matched local ticket|matched.local.ticket.*column' "$SKILL_FILE"
134
- [ "$status" -eq 0 ]
135
- }
136
-
137
- # ──────────────────────────────────────────────────────────────────────────────
138
- # Six pipeline outcomes (4.5e steps 1-6)
139
- # ──────────────────────────────────────────────────────────────────────────────
140
-
141
- @test "Pipeline step 1 — version-aware classification (P129 Phase 1 already-fixed-in-newer; Phase 2 recurrence deferred)" {
142
- # Phase 1 landed: SKILL.md Step 1 now carries the version-aware classifier
143
- # for the already-fixed-in-newer branch. Phase 2 (recurrence-class lifecycle)
144
- # remains deferred and is captured via the cache_audit_note Phase 2 token.
145
- run grep -inE 'version-aware classification.*P129.*Phase 1|P129.*Phase 1.*already-fixed-in-newer' "$SKILL_FILE"
146
- [ "$status" -eq 0 ]
147
- }
148
-
149
- @test "Pipeline step 1 — already-fixed-in-newer classification token present (P129 Phase 1)" {
150
- run grep -nE 'already-fixed-in-newer' "$SKILL_FILE"
151
- [ "$status" -eq 0 ]
152
- }
153
-
154
- @test "Pipeline step 1 — Phase 2 recurrence deferred with cache_audit_note phase2-recurrence-deferred token" {
155
- # Phase 2 deferral is recorded as a strictly additive cache_audit_note so
156
- # Phase 2 can backfill the recurrence-link when it lands; the matched
157
- # closed-ticket ID is named on the note so Phase 2 has a backfill anchor.
158
- run grep -nE 'phase2-recurrence-deferred-bug-shape-match' "$SKILL_FILE"
159
- [ "$status" -eq 0 ]
160
- }
161
-
162
- @test "Pipeline step 1 — Versions section parse per ADR-033 amendment / P128 schema" {
163
- # The classifier inputs depend on the inbound report carrying a parsable
164
- # `## Versions` section per P128's schema (`- Local plugin: @windyroad/<pkg>@<version>`).
165
- # If P128's schema regresses, this anchor surfaces the dependency.
166
- run grep -inE 'Versions section.*P128|## Versions.*P128|Local plugin.*@windyroad' "$SKILL_FILE"
167
- [ "$status" -eq 0 ]
168
- }
169
-
170
- @test "Pipeline step 1 — missing-version fail-soft fallback (phase1-version-missing)" {
171
- # When the reporter's `## Versions` section is absent or `Local plugin` is
172
- # unparseable, Step 1 logs `cache_audit_note: phase1-version-missing` and
173
- # proceeds to step 2 (treats as still-active). Required by the fail-soft
174
- # contract at 4.5 head; protects JTBD-301 acknowledgement.
175
- run grep -nE 'phase1-version-missing' "$SKILL_FILE"
176
- [ "$status" -eq 0 ]
177
- }
178
-
179
- @test "Pipeline step 1 — fix-version-extraction-failed fail-soft fallback" {
180
- # When fix-version extraction from the matched closed ticket's
181
- # `## Fix Released` section fails (best-effort heuristic miss), Step 1
182
- # logs `cache_audit_note: phase1-fix-version-extraction-failed-P<NNN>`
183
- # and proceeds to step 2. Maintainer re-discovers the duplication via
184
- # the next /wr-itil:review-problems re-rank; no silent loss.
185
- run grep -nE 'phase1-fix-version-extraction-failed' "$SKILL_FILE"
186
- [ "$status" -eq 0 ]
187
- }
188
-
189
- @test "Pipeline step 4b — upgrade-pushback branch (P129 Phase 1 fix-released sub-shape)" {
190
- # New sub-branch wired by Step 1's already-fixed-in-newer outcome.
191
- # Posts a gated upgrade-pushback comment under the fix-released verdict
192
- # row of the 4.5e-comment-shape contract. Architect verdict 2026-06-09
193
- # confirmed this as a sub-shape (not a 6th verdict-shape row) to
194
- # preserve the JTBD-301 four-verdict contract.
195
- run grep -inE '4b\..*Upgrade-pushback|Upgrade-pushback branch.*P129' "$SKILL_FILE"
196
- [ "$status" -eq 0 ]
197
- }
198
-
199
- @test "Pipeline step 4b — no local ticket created on already-fixed-in-newer (Phase 1 contract)" {
200
- # JTBD verdict 2026-06-09: the absence-of-ticket is correct because no
201
- # new investigation is needed; the "file a new report" escape hatch
202
- # preserves the plugin-user persona's agency.
203
- run grep -inE 'Do NOT open a local ticket|absence-of-ticket is correct' "$SKILL_FILE"
204
- [ "$status" -eq 0 ]
205
- }
206
-
207
- @test "Pipeline step 4b — anti-leakage (P229) preserved on upgrade-pushback body" {
208
- # Comment bodies MUST NOT carry framework-internal vocab — Step IDs,
209
- # branch names, classification tokens, or path syntax. The only
210
- # structured tokens permitted are the plain-language upgrade target
211
- # `@windyroad/<pkg>@<fix-version>` + the reporter-readable `P<NNN>` anchor.
212
- run grep -inE 'Anti-leakage \(P229\).*4b|MUST NOT contain framework-internal vocab' "$SKILL_FILE"
213
- [ "$status" -eq 0 ]
214
- }
215
-
216
- @test "Pipeline step 4b — gate-denial sub-branch records gate-denied-already-fixed-in-newer-upgrade-pushback" {
217
- # Symmetry with the existing gate-denial sub-branches on Steps 4 / 5 / 6.
218
- # The upgrade-pushback comment retries on next discovery pass —
219
- # JTBD-301 acknowledgement is preserved across gate denials.
220
- run grep -nE 'gate-denied-already-fixed-in-newer-upgrade-pushback' "$SKILL_FILE"
221
- [ "$status" -eq 0 ]
222
- }
223
-
224
- @test "Pipeline step 2 — JTBD-alignment classifier (wr-jtbd:agent)" {
225
- run grep -nE 'JTBD-alignment classifier' "$SKILL_FILE"
226
- [ "$status" -eq 0 ]
227
- run grep -nE 'wr-jtbd:agent' "$SKILL_FILE"
228
- [ "$status" -eq 0 ]
229
- }
230
-
231
- @test "Pipeline step 3 — dual-axis risk classifier (wr-risk-scorer:inbound-report from Slice B)" {
232
- run grep -inE 'dual-axis risk classifier' "$SKILL_FILE"
233
- [ "$status" -eq 0 ]
234
- run grep -nE 'wr-risk-scorer:inbound-report' "$SKILL_FILE"
235
- [ "$status" -eq 0 ]
236
- }
237
-
238
- @test "Pipeline step 4 — above-threshold-pushback branch (gated declining comment)" {
239
- run grep -nE 'above-threshold-pushback' "$SKILL_FILE"
240
- [ "$status" -eq 0 ]
241
- }
242
-
243
- @test "Pipeline step 5 — clear-malicious branch with verdict comment BEFORE close (JTBD-301)" {
244
- # JTBD-301 acknowledgement contract: silent close is forbidden per ADR-062.
245
- run grep -nE 'clear-malicious' "$SKILL_FILE"
246
- [ "$status" -eq 0 ]
247
- run grep -inE 'verdict comment.*BEFORE close|silent close.*forbidden' "$SKILL_FILE"
248
- [ "$status" -eq 0 ]
249
- }
250
-
251
- @test "Pipeline step 6 — safe-and-valid branch invokes capture-problem --no-prompt" {
252
- # Architect issue 3: documenting the default-technical choice explicitly
253
- # so the maintainer-re-classify safety net is visible.
254
- run grep -nE 'safe-and-valid' "$SKILL_FILE"
255
- [ "$status" -eq 0 ]
256
- run grep -nE 'capture-problem.*--no-prompt' "$SKILL_FILE"
257
- [ "$status" -eq 0 ]
258
- }
259
-
260
- # ──────────────────────────────────────────────────────────────────────────────
261
- # Mechanical-stage carve-out (P132 / ADR-044 category 4)
262
- # Load-bearing test protecting JTBD-001 + JTBD-006 against inverse-P078 drift
263
- # per the architect's named Slice E acceptance criterion.
264
- # ──────────────────────────────────────────────────────────────────────────────
265
-
266
- @test "Step 4.5 cites the mechanical-stage carve-out (P132 / ADR-044)" {
267
- run grep -inE 'mechanical-stage carve-out|P132' "$SKILL_FILE"
268
- [ "$status" -eq 0 ]
269
- }
270
-
271
- @test "Step 4.5 explicitly forbids AskUserQuestion at the branch decision (anti-inverse-P078 drift)" {
272
- # The load-bearing structural assertion per architect Slice E acceptance.
273
- # If a future edit adds AskUserQuestion to the pipeline branch decision,
274
- # this assertion fails and surfaces the P132 carve-out regression.
275
- run grep -nE 'does NOT use .AskUserQuestion. at the branch decision' "$SKILL_FILE"
276
- [ "$status" -eq 0 ]
277
- }
278
-
279
- @test "Step 4.5 cites ADR-044 category 4 (silent framework action)" {
280
- run grep -nE 'ADR-044 category 4' "$SKILL_FILE"
281
- [ "$status" -eq 0 ]
282
- }
283
-
284
- # ──────────────────────────────────────────────────────────────────────────────
285
- # JTBD-301 acknowledgement contract (non-negotiable per ADR-062)
286
- # ──────────────────────────────────────────────────────────────────────────────
287
-
288
- @test "JTBD-301 acknowledgement contract cited on the matched-local-ticket path (architect issue 5)" {
289
- run grep -nE 'JTBD-301' "$SKILL_FILE"
290
- [ "$status" -eq 0 ]
291
- run grep -nE 'JTBD-301 acknowledgement' "$SKILL_FILE"
292
- [ "$status" -eq 0 ]
293
- }
294
-
295
- @test "Per-branch gate-denial sub-branches preserve report on external-comms gate FAIL" {
296
- # Silent-skip on gate-denial would break JTBD-301; the report is preserved
297
- # via cache_audit_note for the next discovery pass.
298
- run grep -nE '[Gg]ate-denial sub-branch' "$SKILL_FILE"
299
- [ "$status" -eq 0 ]
300
- run grep -nE 'cache_audit_note' "$SKILL_FILE"
301
- [ "$status" -eq 0 ]
302
- }
303
-
304
- # ──────────────────────────────────────────────────────────────────────────────
305
- # Fail-soft contract + downstream non-obligation
306
- # ──────────────────────────────────────────────────────────────────────────────
307
-
308
- @test "Step 4.5 declares the fail-soft contract" {
309
- run grep -inE 'fail-soft contract' "$SKILL_FILE"
310
- [ "$status" -eq 0 ]
311
- }
312
-
313
- @test "Missing channel config skips Step 4.5 (downstream-adopter non-obligation per JTBD-101)" {
314
- run grep -nE 'channel config absent|missing or malformed' "$SKILL_FILE"
315
- [ "$status" -eq 0 ]
316
- run grep -nE 'JTBD-101' "$SKILL_FILE"
317
- [ "$status" -eq 0 ]
318
- }
319
-
320
- @test "AFK-loop silent behaviour documented" {
321
- run grep -nE 'AFK-loop|AFK orchestrator.*silently' "$SKILL_FILE"
322
- [ "$status" -eq 0 ]
323
- }
324
-
325
- # ──────────────────────────────────────────────────────────────────────────────
326
- # Slice F: --force-upstream-recheck flag parsing + TTL-expiry auto-recheck
327
- # (Slice F replaced the Slice C SLICE-C-FLAG-STUB string-match with proper
328
- # tokenized flag parsing + explicit TTL-expiry branch)
329
- # ──────────────────────────────────────────────────────────────────────────────
330
-
331
- @test "SLICE-C-FLAG-STUB marker has been removed (Slice F replaced the stub)" {
332
- # Slice F (RFC-004) replaces the Slice C string-match with proper
333
- # tokenized flag parsing. The stub marker must be gone — its presence
334
- # would indicate Slice F regression.
335
- run grep -nE 'SLICE-C-FLAG-STUB' "$SKILL_FILE"
336
- [ "$status" -ne 0 ]
337
- }
338
-
339
- @test "--force-upstream-recheck flag documented (Slice F)" {
340
- run grep -nE -- '--force-upstream-recheck' "$SKILL_FILE"
341
- [ "$status" -eq 0 ]
342
- }
343
-
344
- @test "Step 4.5a parses \$ARGUMENTS as tokenized flag list (Slice F)" {
345
- # Slice F replaces the Slice C string-match with proper tokenized parsing.
346
- run grep -inE 'tokenize|whitespace-separated token|parse.*ARGUMENTS' "$SKILL_FILE"
347
- [ "$status" -eq 0 ]
348
- }
349
-
350
- @test "Step 4.5b — TTL-expiry auto-recheck branch fires when cache_age > ttl_seconds (Slice F)" {
351
- # Self-healing: maintainer who runs review-problems once a week still
352
- # gets a fresh poll after the 24-hour TTL expires, without needing the
353
- # explicit flag.
354
- run grep -inE 'TTL-expiry auto-recheck|cache.age.*exceeds.*ttl_seconds|cache_age.*> *ttl_seconds' "$SKILL_FILE"
355
- [ "$status" -eq 0 ]
356
- }
357
-
358
- @test "Step 4.5b — explicit branch for cache-fresh (within-TTL silent-pass)" {
359
- # Within-TTL path is silent per ADR-013 Rule 5 below-appetite silent-pass.
360
- run grep -inE 'cache-fresh branch|within-TTL|silent within-TTL' "$SKILL_FILE"
361
- [ "$status" -eq 0 ]
362
- }
363
-
364
- @test "Step 4.5a — unknown inbound-flags surface advisory rather than silently ignoring" {
365
- # Defensive contract: unknown --force-upstream / --inbound- flags get
366
- # named in an advisory so typos are visible (e.g. --force-upsteam-recheck).
367
- run grep -inE 'Unknown.*flag.*halt|unrecognised flag' "$SKILL_FILE"
368
- [ "$status" -eq 0 ]
369
- }
370
-
371
- # ──────────────────────────────────────────────────────────────────────────────
372
- # Cross-reference integrity (ADRs + sibling JTBDs)
373
- # ──────────────────────────────────────────────────────────────────────────────
374
-
375
- @test "ADR-062 cross-reference present in Step 4.5 header" {
376
- run grep -nE 'ADR-062' "$SKILL_FILE"
377
- [ "$status" -eq 0 ]
378
- }
379
-
380
- @test "ADR-028 (external-comms gate) cited for gated-comment paths" {
381
- run grep -nE 'ADR-028' "$SKILL_FILE"
382
- [ "$status" -eq 0 ]
383
- }