@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,120 +0,0 @@
1
- #!/usr/bin/env bats
2
-
3
- # P342: Iter retros queue their own observations as outstanding-questions
4
- # for user-direction triage instead of auto-ticketing — same trust-
5
- # boundary as /wr-retrospective:run-retro Step 4a (verification close-on-
6
- # evidence).
7
- #
8
- # The fix shape amends the work-problems Step 5 iter-prompt body:
9
- # - Relax the "no capture-* siblings mid-loop" rule for RETRO-surfaced
10
- # observations specifically.
11
- # - Direct retro to auto-ticket recurring class-of-behaviour
12
- # observations via /wr-itil:capture-problem (mechanical-stage carve-
13
- # out per run-retro Step 4a precedent).
14
- # - Route ONLY direction-setting observations (genuine user-judgment-
15
- # bound questions) to outstanding_questions.
16
- # - Document the classification:
17
- # recurring class-of-behaviour / SKILL-contract drift / hook
18
- # misbehaviour / framework-gap → auto-ticket.
19
- # Direction-setting (design choice, deviation-approval, framework
20
- # boundary) → outstanding_questions.
21
- # Ambiguous → default to auto-ticket.
22
- #
23
- # Doc-lint contract assertions per ADR-037 Permitted Exception.
24
- #
25
- # @problem P342
26
- # @adr ADR-044 (Decision-Delegation Contract — mechanical-stage carve-out per Step 4a precedent)
27
- # @adr ADR-013 Rule 5 (policy-authorised silent proceed)
28
- # @adr ADR-032 (governance skill invocation patterns — foreground-spawns-background fanout pattern for capture-*)
29
- # @jtbd JTBD-006 (Progress the Backlog While I'm Away — durable WSJF-ranked backlog accumulation)
30
- # @jtbd JTBD-201 (audit-trail — auto-ticketed observations become durable artefacts)
31
-
32
- setup() {
33
- REPO_ROOT="$(cd "$(dirname "$BATS_TEST_FILENAME")/../../../../.." && pwd)"
34
- SKILL_MD="$REPO_ROOT/packages/itil/skills/work-problems/SKILL.md"
35
- }
36
-
37
- @test "work-problems P342: SKILL.md exists" {
38
- [ -f "$SKILL_MD" ]
39
- }
40
-
41
- # ── Step 5 iter-prompt: capture-* carve-out for retro observations ──────────
42
-
43
- @test "work-problems P342: iter-prompt body carves out capture-* for retro-surfaced observations" {
44
- # The fix relaxes the "No capture-* siblings mid-loop" rule for RETRO
45
- # observations specifically. Existing P078-class spam rule remains for
46
- # non-retro mid-iter capture; the carve-out is bounded to retro.
47
- run grep -nE 'retro.*capture-\*|capture-\*.*retro|retro-surfaced.*capture|capture-problem.*retro' "$SKILL_MD"
48
- [ "$status" -eq 0 ]
49
- }
50
-
51
- @test "work-problems P342: iter-prompt body directs retro to auto-ticket via /wr-itil:capture-problem" {
52
- # Recurring class-of-behaviour observations MUST route to
53
- # /wr-itil:capture-problem (mechanical-stage carve-out per run-retro
54
- # Step 4a precedent). The skill is named explicitly so adopters know
55
- # which capture sibling to invoke.
56
- run grep -nE '/wr-itil:capture-problem' "$SKILL_MD"
57
- [ "$status" -eq 0 ]
58
- }
59
-
60
- @test "work-problems P342: iter-prompt cites Step 4a precedent for mechanical-stage carve-out" {
61
- # The carve-out's authority is the run-retro Step 4a verification
62
- # close-on-evidence precedent. Cite it so future authors don't unwind
63
- # the carve-out by re-applying the broad "no capture-* mid-loop" rule
64
- # uniformly.
65
- run grep -nE 'Step 4a precedent|run-retro Step 4a|Step 4a.*mechanical' "$SKILL_MD"
66
- [ "$status" -eq 0 ]
67
- }
68
-
69
- # ── Classification taxonomy ────────────────────────────────────────────────
70
-
71
- @test "work-problems P342: iter-prompt classifies recurring class-of-behaviour as auto-ticket" {
72
- # Recurring class-of-behaviour / SKILL-contract drift / hook
73
- # misbehaviour / framework-gap → auto-ticket. The taxonomy MUST be
74
- # documented so future authors don't drift on classification.
75
- run grep -nE 'recurring class-of-behaviour|class-of-behaviour observation' "$SKILL_MD"
76
- [ "$status" -eq 0 ]
77
- }
78
-
79
- @test "work-problems P342: iter-prompt classifies direction-setting as outstanding_questions" {
80
- # Direction-setting (design choice, deviation-approval, framework
81
- # boundary) → outstanding_questions. The route must be named so the
82
- # framework boundary is preserved.
83
- run grep -nE 'Direction-setting observation|direction-setting.*outstanding_questions' "$SKILL_MD"
84
- [ "$status" -eq 0 ]
85
- }
86
-
87
- @test "work-problems P342: iter-prompt classifies ambiguous observations as default-to-auto-ticket" {
88
- # Ambiguous → default to auto-ticket. This is the trust-boundary
89
- # asymmetry that prevents observations from silently piling in the
90
- # queue file (per P342 Description).
91
- run grep -nE 'Ambiguous.*auto-ticket|default to auto-ticket|ambiguous.*default.*ticket' "$SKILL_MD"
92
- [ "$status" -eq 0 ]
93
- }
94
-
95
- # ── Trust-boundary mirror in run-retro Step 4b ─────────────────────────────
96
-
97
- @test "work-problems P342: iter-prompt cross-references run-retro Step 4b carve-out symmetry" {
98
- # The run-retro Step 4b stage classification mirrors this carve-out so
99
- # the same trust-boundary applies whether retro fires in iter context
100
- # OR standalone in main turn. Cross-reference the sibling locus so the
101
- # symmetry is discoverable.
102
- run grep -nE 'run-retro.*Step 4b|Step 4b.*mirror|symmetry.*Step 4b|Step 4b.*carve-out' "$SKILL_MD"
103
- [ "$status" -eq 0 ]
104
- }
105
-
106
- # ── Cross-reference to P342 ────────────────────────────────────────────────
107
-
108
- @test "work-problems P342: Related section cites P342 as the originating ticket" {
109
- run grep -nE '\*\*P342\*\*|P342\b' "$SKILL_MD"
110
- [ "$status" -eq 0 ]
111
- }
112
-
113
- # ── Anti-pattern preservation: P130 mid-loop ask discipline unaffected ─────
114
-
115
- @test "work-problems P342: iter-prompt preserves P130 NEVER call AskUserQuestion mid-loop discipline" {
116
- # The P342 carve-out is for capture-* siblings on the retro path only;
117
- # the iter-prompt's mid-loop AskUserQuestion ban is unchanged.
118
- run grep -nE 'NEVER call .?AskUserQuestion.? mid-loop|MUST NOT call .?AskUserQuestion.? between iter' "$SKILL_MD"
119
- [ "$status" -eq 0 ]
120
- }
@@ -1,248 +0,0 @@
1
- #!/usr/bin/env bats
2
- # tdd-review: structural-permitted (justification: the doc-lint slice below
3
- # asserts SKILL.md / ADR-032 prose contract — SKILL.md is the contract
4
- # document per ADR-037 Permitted Exception; these guards catch prose drift
5
- # away from the behavioural revert-and-proceed contract exercised above. The
6
- # load-bearing core of this fixture is behavioural per ADR-052. harness-gap P012)
7
- #
8
- # Behavioural test: work-problems Step 0 PRE-FLIGHT subprocess failure handling
9
- # (P358). Step 0b / 0c / 0d dispatch a /wr-itil:review-problems (or
10
- # check-upstream-responses) pre-flight subprocess "same shape as Step 5". But a
11
- # pre-flight is a NON-load-bearing cache-refresh dependency, NOT an iter (the
12
- # loop body). When a pre-flight subprocess exits non-zero OR returns
13
- # `is_error: true` (e.g. `API Error: The socket connection was closed
14
- # unexpectedly`), the orchestrator's contract is NON-BLOCKING:
15
- # (1) revert any dirty (unstaged) partial cache/audit/README write the
16
- # pre-flight left (`git checkout -- docs/problems/ docs/audits/`);
17
- # (1b) if a dead pre-flight left STAGED residue, `git reset` then revert
18
- # (ADR-009 no-trust-window-extension — a dead is_error:true subprocess
19
- # must not seed the parent's commit);
20
- # (2) log a one-line annotation;
21
- # (3) proceed to Step 1 with the existing README.
22
- # This is ORTHOGONAL to the Step 5 iter SALVAGE-vs-HALT axis (P261 / P214):
23
- # that axis classifies an *iter's* is_error:true; this fixture classifies the
24
- # *pre-flight role* — which NEVER salvages and NEVER halts the loop.
25
- #
26
- # The fake `claude` shim below re-creates the production shape: it dirties an
27
- # unstaged cache file in the repo, then emits an is_error:true socket-closed
28
- # JSON envelope (no commit). The harness re-implements the orchestrator's
29
- # pre-flight failure contract (faithful to SKILL.md § "Step 0 pre-flight
30
- # subprocess failure handling (P358)") and asserts the revert-and-proceed
31
- # outcome across the input shapes. Adopters who copy the SKILL.md pre-flight
32
- # block into their orchestrator should observe the same outcomes.
33
- #
34
- # @problem P358
35
- # @rfc RFC-024
36
- # @jtbd JTBD-006
37
- #
38
- # Cross-reference:
39
- # P358 (claude -p subprocess dispatch socket-closed; pre-flight is_error
40
- # handling gap) — driver ticket
41
- # RFC-024 (work-problems pre-flight subprocess failure handling) — fix vehicle
42
- # ADR-032 (governance skill invocation patterns — § "Pre-flight subprocess
43
- # failure handling — non-blocking revert-and-proceed (P358 amendment)") —
44
- # the iter-vs-pre-flight failure-semantics distinction this fixture pins
45
- # ADR-009 (gate-marker / no-trust-window-extension — staged residue git reset)
46
- # ADR-019 (preflight clean-tree reconciliation surface)
47
- # P261 / P214 (the iter is_error:true SALVAGE/HALT axis this is orthogonal to)
48
- # ADR-037 / ADR-052 (skill testing strategy — behavioural default; doc-lint
49
- # contract assertion is the Permitted Exception, marked above)
50
-
51
- setup() {
52
- TEST_TMP="$(mktemp -d)"
53
- FAKE_BIN="${TEST_TMP}/bin"
54
- mkdir -p "$FAKE_BIN"
55
-
56
- # Fake `claude` binary simulating a pre-flight subprocess of the socket-closed
57
- # class: it leaves a dirty (UNSTAGED by default) partial cache write in the
58
- # CWD git repo, then emits an is_error:true JSON envelope carrying the
59
- # socket-closed error string in `.result`. No commit. This matches the
60
- # 2026-06-10 P358 shape: a /wr-itil:review-problems pre-flight that partially
61
- # refreshed docs/problems/.upstream-cache.json then died with
62
- # `API Error: The socket connection was closed unexpectedly`.
63
- cat > "$FAKE_BIN/claude" <<'FAKE_EOF'
64
- #!/usr/bin/env bash
65
- # Test fake for work-problems Step 0 pre-flight failure-handling fixture.
66
- # Dirties a partial cache write, then emits is_error:true socket-closed JSON.
67
- mkdir -p docs/problems
68
- printf 'partial-refresh-mid-die\n' >> docs/problems/.upstream-cache.json
69
- if [ "${FAKE_STAGE_RESIDUE:-0}" = "1" ]; then
70
- git add docs/problems/.upstream-cache.json 2>/dev/null || true
71
- fi
72
- if [ "${FAKE_EXIT:-0}" != "0" ]; then
73
- printf '%s\n' '{"is_error":true,"result":"subprocess crashed"}'
74
- exit "${FAKE_EXIT}"
75
- fi
76
- printf '%s\n' '{"is_error":true,"result":"API Error: The socket connection was closed unexpectedly. For more information, pass `verbose: true`","total_cost_usd":0.0,"duration_ms":727000}'
77
- FAKE_EOF
78
- chmod +x "$FAKE_BIN/claude"
79
- export PATH="$FAKE_BIN:$PATH"
80
-
81
- # A throwaway git repo so dirty-detection + the revert are real. Seed a
82
- # committed clean cache so the partial write is observably a dirty delta.
83
- REPO="${TEST_TMP}/repo"
84
- mkdir -p "$REPO/docs/problems"
85
- git -C "$REPO" init -q
86
- git -C "$REPO" config user.email "test@example.com"
87
- git -C "$REPO" config user.name "Test"
88
- printf 'clean-cache\n' > "$REPO/docs/problems/.upstream-cache.json"
89
- git -C "$REPO" add docs/problems/.upstream-cache.json
90
- git -C "$REPO" commit -q -m "root: clean cache"
91
-
92
- SKILL_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
93
- SKILL_FILE="${SKILL_DIR}/SKILL.md"
94
- ADR_FILE="$(cd "${SKILL_DIR}/../../../.." && pwd)/docs/decisions/032-governance-skill-invocation-patterns.proposed.md"
95
- }
96
-
97
- teardown() {
98
- if [ -n "${TEST_TMP:-}" ] && [ -d "$TEST_TMP" ]; then
99
- rm -rf "$TEST_TMP"
100
- fi
101
- }
102
-
103
- # Faithful re-implementation of SKILL.md § "Step 0 pre-flight subprocess failure
104
- # handling (P358)". Consumes the pre-flight JSON envelope + the pre-flight exit
105
- # code + the repo working-tree state, applies the non-blocking revert-and-proceed
106
- # contract, and returns the orchestrator's decision. KEY PROPERTY: a pre-flight
107
- # NEVER halts the loop and NEVER salvages — it reverts and proceeds.
108
- preflight_failure_outcome() {
109
- local json="$1"
110
- local exit_code="$2"
111
- local repo="$3"
112
-
113
- local is_error
114
- is_error=$(printf '%s' "$json" | python3 -c 'import json,sys; print(str(json.load(sys.stdin).get("is_error")).lower())' 2>/dev/null || echo unknown)
115
-
116
- # Pre-flight succeeded (exit 0 AND is_error:false) → cache refreshed; proceed.
117
- if [ "$exit_code" = "0" ] && [ "$is_error" = "false" ]; then
118
- printf 'DECISION=PROCEED reason=preflight-ok\n'
119
- return 0
120
- fi
121
-
122
- # Pre-flight FAILED (non-zero exit OR is_error:true) → NON-BLOCKING contract.
123
- # Step 1b: if the dead pre-flight left STAGED residue, unstage it first
124
- # (ADR-009 — a dead is_error:true subprocess must not seed the parent index).
125
- if [ -n "$(git -C "$repo" diff --cached --name-only)" ]; then
126
- git -C "$repo" reset -q
127
- fi
128
- # Step 1: revert the whole contractually-touchable path set (not just cache).
129
- # Per-path tolerant — a COMBINED `git checkout -- A B` errors and reverts
130
- # NOTHING when B is absent (e.g. docs/audits/ on a fresh adopter repo), so
131
- # revert each path independently.
132
- git -C "$repo" checkout -- docs/problems/ 2>/dev/null || true
133
- git -C "$repo" checkout -- docs/audits/ 2>/dev/null || true
134
- # Step 3: proceed to Step 1 (never halt).
135
- printf 'DECISION=PROCEED reason=preflight-failed-reverted\n'
136
- return 0
137
- }
138
-
139
- # ---------------------------------------------------------------------------
140
- # Behavioural cases (the load-bearing core per ADR-052).
141
- # ---------------------------------------------------------------------------
142
-
143
- @test "P358: pre-flight is_error:true (socket-closed) + unstaged partial write -> revert + PROCEED (never halt)" {
144
- export FAKE_STAGE_RESIDUE=0 FAKE_EXIT=0
145
- local json
146
- json=$( cd "$REPO" && claude -p --output-format json "PREFLIGHT" < /dev/null )
147
- # The fake left a dirty partial cache write.
148
- run git -C "$REPO" status --porcelain docs/problems/.upstream-cache.json
149
- [ -n "$output" ]
150
- run preflight_failure_outcome "$json" 0 "$REPO"
151
- [ "$status" -eq 0 ]
152
- [[ "$output" == *"DECISION=PROCEED"* ]]
153
- [[ "$output" == *"preflight-failed-reverted"* ]]
154
- # The dirty partial write was reverted — tree is clean again.
155
- run git -C "$REPO" status --porcelain
156
- [ -z "$output" ]
157
- # The committed clean cache content survived (revert restored it).
158
- run cat "$REPO/docs/problems/.upstream-cache.json"
159
- [[ "$output" == "clean-cache" ]]
160
- }
161
-
162
- @test "P358: pre-flight non-zero exit -> revert + PROCEED (non-blocking; not a loop halt)" {
163
- export FAKE_STAGE_RESIDUE=0 FAKE_EXIT=1
164
- local json
165
- json=$( cd "$REPO" && claude -p --output-format json "PREFLIGHT" < /dev/null || true )
166
- run preflight_failure_outcome "$json" 1 "$REPO"
167
- [ "$status" -eq 0 ]
168
- [[ "$output" == *"DECISION=PROCEED"* ]]
169
- # Crucially NOT a HALT — a pre-flight failure does not stop the loop.
170
- [[ "$output" != *"HALT"* ]]
171
- run git -C "$REPO" status --porcelain
172
- [ -z "$output" ]
173
- }
174
-
175
- @test "P358: pre-flight left STAGED residue -> git reset then revert (ADR-009 no-seed-parent-index)" {
176
- export FAKE_STAGE_RESIDUE=1 FAKE_EXIT=0
177
- local json
178
- json=$( cd "$REPO" && claude -p --output-format json "PREFLIGHT" < /dev/null )
179
- # The fake STAGED the partial write.
180
- run git -C "$REPO" diff --cached --name-only
181
- [[ "$output" == *".upstream-cache.json"* ]]
182
- run preflight_failure_outcome "$json" 0 "$REPO"
183
- [ "$status" -eq 0 ]
184
- [[ "$output" == *"DECISION=PROCEED"* ]]
185
- # Staged residue was unstaged AND reverted — index + tree both clean.
186
- run git -C "$REPO" diff --cached --name-only
187
- [ -z "$output" ]
188
- run git -C "$REPO" status --porcelain
189
- [ -z "$output" ]
190
- }
191
-
192
- @test "P358: pre-flight success (exit 0 + is_error:false) -> PROCEED without revert" {
193
- # Hand-build a clean success envelope (the fake always fails by design).
194
- local json='{"is_error":false,"result":"refreshed"}'
195
- run preflight_failure_outcome "$json" 0 "$REPO"
196
- [ "$status" -eq 0 ]
197
- [[ "$output" == *"DECISION=PROCEED"* ]]
198
- [[ "$output" == *"preflight-ok"* ]]
199
- }
200
-
201
- # ---------------------------------------------------------------------------
202
- # Doc-lint contract assertions (Permitted Exception per ADR-037; structural
203
- # slice marked at top of file per ADR-052 Surface 2). These guard the SKILL.md
204
- # / ADR-032 prose against drift away from the behavioural contract above.
205
- # ---------------------------------------------------------------------------
206
-
207
- @test "P358: SKILL.md documents the Step 0 pre-flight failure-handling subsection" {
208
- run grep -niE "pre-flight subprocess failure handling.{0,40}P358|Step 0 pre-flight subprocess failure" "$SKILL_FILE"
209
- [ "$status" -eq 0 ]
210
- }
211
-
212
- @test "P358: SKILL.md pre-flight contract names the non-blocking revert-and-proceed rule" {
213
- run grep -niE "non-?blocking" "$SKILL_FILE"
214
- [ "$status" -eq 0 ]
215
- run grep -niE "revert.{0,40}(proceed|partial)|proceed to Step 1 with the existing" "$SKILL_FILE"
216
- [ "$status" -eq 0 ]
217
- }
218
-
219
- @test "P358: SKILL.md distinguishes pre-flight (cache-refresh dependency) from iter (loop body)" {
220
- run grep -niE "non-load-bearing cache-refresh dependency" "$SKILL_FILE"
221
- [ "$status" -eq 0 ]
222
- run grep -niE "iter IS the loop body|the iter is the loop body" "$SKILL_FILE"
223
- [ "$status" -eq 0 ]
224
- }
225
-
226
- @test "P358: SKILL.md pre-flight forward-pointer fires in the 0b/0c/0d dispatch paragraphs" {
227
- # At least three "do NOT halt the loop (a failed pre-flight ...)" pointers.
228
- run bash -c "grep -ciE 'do NOT halt the loop .a failed pre-flight' '$SKILL_FILE'"
229
- [ "$status" -eq 0 ]
230
- [ "$output" -ge 3 ]
231
- }
232
-
233
- @test "P358: SKILL.md pre-flight contract cites P358" {
234
- run grep -nE "P358" "$SKILL_FILE"
235
- [ "$status" -eq 0 ]
236
- }
237
-
238
- @test "P358: ADR-032 carries the pre-flight failure-handling P358 amendment" {
239
- run grep -niE "Pre-flight subprocess failure handling.{0,60}P358 amendment" "$ADR_FILE"
240
- [ "$status" -eq 0 ]
241
- }
242
-
243
- @test "P358: ADR-032 amendment names the iter-vs-pre-flight failure-semantics axis as orthogonal to SALVAGE/HALT" {
244
- run grep -niE "orthogonal" "$ADR_FILE"
245
- [ "$status" -eq 0 ]
246
- run grep -niE "No SALVAGE for a pre-flight|SALVAGE branch does NOT apply to a pre-flight" "$ADR_FILE"
247
- [ "$status" -eq 0 ]
248
- }
@@ -1,139 +0,0 @@
1
- #!/usr/bin/env bats
2
- # Contract-assertion bats for work-problems Step 0 session-continuity
3
- # detection (the extension per P109).
4
- #
5
- # Per ADR-037 SKILL.md is a contract document; these assertions check the
6
- # contract strings the skill prose authoritatively pins for the Step 0
7
- # session-continuity detection pass. Follows the split pattern established
8
- # by work-problems-preflight.bats (fetch/divergence assertions) — this file
9
- # covers the second invariant family: prior-session partial-work signals +
10
- # interactive/AFK routing.
11
- #
12
- # Cross-reference:
13
- # @problem P109 (work-problems preflight does not detect prior-session partial-work state)
14
- # ADR-019 (AFK orchestrator preflight — extension scope)
15
- # ADR-013 (structured user interaction — Rule 1 interactive, Rule 6 non-interactive fail-safe)
16
- # ADR-032 (governance skill invocation patterns — .afk-run-state/iter-*.json contract)
17
- # ADR-037 (skill testing strategy — contract-assertion framing)
18
- # @jtbd JTBD-006 (Progress the Backlog While I'm Away — session-continuity detection belongs in Step 0)
19
-
20
- setup() {
21
- SKILL_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
22
- SKILL_FILE="${SKILL_DIR}/SKILL.md"
23
- }
24
-
25
- @test "SKILL.md exists" {
26
- [ -f "$SKILL_FILE" ]
27
- }
28
-
29
- @test "SKILL.md Step 0 cites P109 (session-continuity driver)" {
30
- # Contract criterion: the extension is traceable to its driver ticket.
31
- run grep -n "P109" "$SKILL_FILE"
32
- [ "$status" -eq 0 ]
33
- }
34
-
35
- @test "SKILL.md Step 0 names the session-continuity detection pass" {
36
- # Contract criterion: the new detection pass is named as a discrete
37
- # concept in the Step 0 prose (not buried under the divergence check).
38
- run grep -niE "session.continuity" "$SKILL_FILE"
39
- [ "$status" -eq 0 ]
40
- }
41
-
42
- @test "SKILL.md Step 0 enumerates untracked docs/decisions/*.proposed.md signal" {
43
- # Contract criterion: drafted-but-unlanded ADRs are one of the signals
44
- # the session-continuity detection pass MUST enumerate.
45
- run grep -nE "docs/decisions/\*\.proposed\.md|docs/decisions/.*\.proposed\.md" "$SKILL_FILE"
46
- [ "$status" -eq 0 ]
47
- }
48
-
49
- @test "SKILL.md Step 0 enumerates untracked docs/problems/*.md signal" {
50
- # Contract criterion: drafted-but-unlanded problem tickets are enumerated
51
- # as one of the session-continuity signals. The preflight section already
52
- # references docs/problems/ for the scan surface; the test checks that
53
- # the Preflight section names untracked problem files as a detection
54
- # signal (not merely the backlog-scan surface).
55
- run grep -niE "untracked.*docs/problems|docs/problems/.*untracked" "$SKILL_FILE"
56
- [ "$status" -eq 0 ]
57
- }
58
-
59
- @test "SKILL.md Step 0 enumerates .afk-run-state/iter-*.json error signal" {
60
- # Contract criterion: the .afk-run-state/iter-*.json subprocess artefacts
61
- # (per ADR-032) with is_error: true or api_error_status >= 400 are named
62
- # as a signal.
63
- run grep -nE "\.afk-run-state/iter-\*\.json|\.afk-run-state/iter-.*\.json" "$SKILL_FILE"
64
- [ "$status" -eq 0 ]
65
- }
66
-
67
- @test "SKILL.md Step 0 names the is_error / api_error_status fields" {
68
- # Contract criterion: the specific JSON fields the detection pass reads
69
- # are named verbatim so the contract is unambiguous.
70
- run grep -niE "is_error.*true|api_error_status" "$SKILL_FILE"
71
- [ "$status" -eq 0 ]
72
- }
73
-
74
- @test "SKILL.md Step 0 enumerates stale .claude/worktrees signal" {
75
- # Contract criterion: stale subagent worktrees are a detection signal.
76
- # Detection only (not cleanup/mutation — per P109 scope boundary).
77
- run grep -nE "\.claude/worktrees" "$SKILL_FILE"
78
- [ "$status" -eq 0 ]
79
- }
80
-
81
- @test "SKILL.md Step 0 enumerates git worktree list signal for claude/* branches" {
82
- # Contract criterion: git worktree list is the detection mechanism for
83
- # claude/* branches adjacent to the .claude/worktrees/ dir check.
84
- run grep -niE "git worktree list" "$SKILL_FILE"
85
- [ "$status" -eq 0 ]
86
- }
87
-
88
- @test "SKILL.md Step 0 enumerates uncommitted SKILL.md / source / ADR edits signal" {
89
- # Contract criterion: mid-authoring source edits are a detection signal.
90
- run grep -niE "uncommitted.*(SKILL\.md|source|ADR)|(SKILL\.md|source|ADR).*uncommitted" "$SKILL_FILE"
91
- [ "$status" -eq 0 ]
92
- }
93
-
94
- @test "SKILL.md Step 0 routes interactive via AskUserQuestion" {
95
- # Contract criterion per ADR-013 Rule 1: the interactive branch uses
96
- # AskUserQuestion.
97
- run grep -nE "AskUserQuestion" "$SKILL_FILE"
98
- [ "$status" -eq 0 ]
99
- }
100
-
101
- @test "SKILL.md Step 0 interactive branch names the 4 option categories" {
102
- # Contract criterion: the AskUserQuestion 4-option shape is pinned so
103
- # adopters know the branch set. Resume / discard / leave-and-lower-priority / halt.
104
- run grep -niE "resume" "$SKILL_FILE"
105
- [ "$status" -eq 0 ]
106
- run grep -niE "discard" "$SKILL_FILE"
107
- [ "$status" -eq 0 ]
108
- run grep -niE "leave.*lower.priority|leave.and.lower.priority" "$SKILL_FILE"
109
- [ "$status" -eq 0 ]
110
- }
111
-
112
- @test "SKILL.md Step 0 routes AFK via halt-with-report per ADR-013 Rule 6" {
113
- # Contract criterion per ADR-013 Rule 6: the non-interactive / AFK branch
114
- # halts with a report rather than silently choosing.
115
- run grep -niE "halt.with.report|halt with report|Rule 6 fail.safe" "$SKILL_FILE"
116
- [ "$status" -eq 0 ]
117
- }
118
-
119
- @test "SKILL.md Step 0 cites ADR-013 Rule 6 for AFK fail-safe" {
120
- # Contract criterion: ADR-013 Rule 6 is named as the authority for the
121
- # non-interactive halt branch.
122
- run grep -nE "ADR-013.*Rule 6|Rule 6.*ADR-013" "$SKILL_FILE"
123
- [ "$status" -eq 0 ]
124
- }
125
-
126
- @test "SKILL.md Step 0 emits a structured Prior-Session State report" {
127
- # Contract criterion: the AFK halt branch surfaces a structured report,
128
- # not a free-text prose blurb — so the user can act on it on return.
129
- run grep -niE "Prior.Session State" "$SKILL_FILE"
130
- [ "$status" -eq 0 ]
131
- }
132
-
133
- @test "SKILL.md Non-Interactive Decision Making table covers session-continuity" {
134
- # Contract criterion: the decision-matrix section surfaces the new branch
135
- # so adopters of the skill can find the AFK default without reading
136
- # Step 0 prose in full.
137
- run grep -niE "Prior.session partial.work|session.continuity.*dirty|Prior-Session State.*AFK" "$SKILL_FILE"
138
- [ "$status" -eq 0 ]
139
- }
@@ -1,69 +0,0 @@
1
- #!/usr/bin/env bats
2
- # Doc-lint guard: work-problems SKILL.md must include the preflight
3
- # (fetch-origin + divergence handling) per ADR-019.
4
- #
5
- # Structural assertion — Permitted Exception to the source-grep ban (ADR-005 / P011).
6
- # These tests assert that the skill specification document contains the
7
- # preflight step so the AFK orchestrator does not iterate against a stale
8
- # local backlog when origin/<base> has advanced.
9
- #
10
- # Cross-reference:
11
- # P040 (work-problems does not fetch origin before starting)
12
- # ADR-019 (AFK orchestrator preflight)
13
- # @jtbd JTBD-006 (Progress the Backlog While I'm Away)
14
-
15
- setup() {
16
- SKILL_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
17
- SKILL_FILE="${SKILL_DIR}/SKILL.md"
18
- }
19
-
20
- @test "SKILL.md cites ADR-019 (preflight)" {
21
- # ADR-019 confirmation criterion: skill must reference the ADR.
22
- run grep -n "ADR-019" "$SKILL_FILE"
23
- [ "$status" -eq 0 ]
24
- }
25
-
26
- @test "SKILL.md preflight runs git fetch origin" {
27
- # ADR-019 mechanism: must run `git fetch origin` before opening the
28
- # work loop.
29
- run grep -n "git fetch origin" "$SKILL_FILE"
30
- [ "$status" -eq 0 ]
31
- }
32
-
33
- @test "SKILL.md preflight uses git pull --ff-only on trivial divergence" {
34
- # ADR-019 mechanism: trivial fast-forward is policy-authorised; non-ff is
35
- # not. The skill must cite --ff-only to prevent merge attempts.
36
- run grep -n "ff-only" "$SKILL_FILE"
37
- [ "$status" -eq 0 ]
38
- }
39
-
40
- @test "SKILL.md preflight stops the loop on non-fast-forward divergence" {
41
- # Confirmation: divergence handling must include a stop-with-report path,
42
- # not a silent retry or merge.
43
- run grep -niE "non-fast-forward|non-ff" "$SKILL_FILE"
44
- [ "$status" -eq 0 ]
45
- }
46
-
47
- @test "SKILL.md preflight has a discrete step before backlog scan" {
48
- # The preflight should appear as a discrete step (e.g. Step 0 — Preflight)
49
- # so it is not buried in prose.
50
- run grep -niE "step 0|preflight" "$SKILL_FILE"
51
- [ "$status" -eq 0 ]
52
- }
53
-
54
- @test "SKILL.md Non-Interactive Decision Making table covers origin divergence" {
55
- # ADR-019 confirmation: the non-interactive defaults table must include a
56
- # row for the divergence decision.
57
- run grep -niE "Origin diverged|origin.*divergence|fast-forward" "$SKILL_FILE"
58
- [ "$status" -eq 0 ]
59
- }
60
-
61
- @test "SKILL.md explicitly forbids non-interactive merge/rebase remediation" {
62
- # ADR-019 forbids non-interactive rebase/merge attempts. The skill must
63
- # negate these (e.g. "Do NOT attempt to rebase or merge" or "are NOT
64
- # policy-authorised") rather than silently allow them. We assert the
65
- # negation appears, not that the words are absent — discussing forbidden
66
- # operations in the negative is exactly what the ADR requires.
67
- run grep -niE "Do NOT attempt to rebase or merge|NOT policy-authorised" "$SKILL_FILE"
68
- [ "$status" -eq 0 ]
69
- }
@@ -1,63 +0,0 @@
1
- #!/usr/bin/env bats
2
- # Doc-lint guard: work-problems SKILL.md must include the inter-iteration
3
- # release-cadence check per ADR-018.
4
- #
5
- # Structural assertion — Permitted Exception to the source-grep ban (ADR-005 / P011).
6
- # These tests assert that the skill specification document contains the
7
- # release-cadence step so the AFK orchestrator does not silently accumulate
8
- # unreleased changesets across iterations.
9
- #
10
- # Cross-reference:
11
- # P041 (work-problems does not enforce release cadence)
12
- # ADR-018 (inter-iteration release cadence for AFK loops)
13
- # @jtbd JTBD-006 (Progress the Backlog While I'm Away)
14
-
15
- setup() {
16
- SKILL_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
17
- SKILL_FILE="${SKILL_DIR}/SKILL.md"
18
- }
19
-
20
- @test "SKILL.md exists" {
21
- [ -f "$SKILL_FILE" ]
22
- }
23
-
24
- @test "SKILL.md cites ADR-018 (release cadence)" {
25
- # ADR-018 confirmation criterion: skill must reference the ADR.
26
- run grep -n "ADR-018" "$SKILL_FILE"
27
- [ "$status" -eq 0 ]
28
- }
29
-
30
- @test "SKILL.md delegates to wr-risk-scorer:assess-release (preserves pure-scorer contract from ADR-015)" {
31
- # ADR-018 mechanism: must delegate to the assess-release skill rather than
32
- # re-implementing risk scoring inline.
33
- run grep -n "assess-release" "$SKILL_FILE"
34
- [ "$status" -eq 0 ]
35
- }
36
-
37
- @test "SKILL.md references release:watch as the drain mechanism" {
38
- # ADR-018 mechanism: drain action runs npm run release:watch (after
39
- # push:watch) when the queue hits appetite.
40
- run grep -n "release:watch" "$SKILL_FILE"
41
- [ "$status" -eq 0 ]
42
- }
43
-
44
- @test "SKILL.md references push:watch as part of the drain mechanism" {
45
- # ADR-018 mechanism: drain action runs push:watch before release:watch.
46
- run grep -n "push:watch" "$SKILL_FILE"
47
- [ "$status" -eq 0 ]
48
- }
49
-
50
- @test "SKILL.md has a release-cadence step between iterations" {
51
- # The inter-iteration check should appear as a discrete step or subsection
52
- # so it is not buried in prose.
53
- run grep -niE "release.cadence|cadence check|release queue" "$SKILL_FILE"
54
- [ "$status" -eq 0 ]
55
- }
56
-
57
- @test "SKILL.md Non-Interactive Decision Making table covers pipeline risk at appetite" {
58
- # ADR-018 confirmation criterion: the non-interactive defaults table must
59
- # include a row for the release-drain decision, otherwise an AFK reader
60
- # cannot find the rule.
61
- run grep -niE "Pipeline risk at appetite|release queue.*appetite|drain.*release" "$SKILL_FILE"
62
- [ "$status" -eq 0 ]
63
- }