@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,285 +0,0 @@
1
- #!/usr/bin/env bats
2
- # Contract assertions for /wr-itil:transition-problem (P071 split slice 4).
3
- #
4
- # This skill hosts the "advance a ticket's lifecycle" user intent
5
- # previously hidden behind /wr-itil:manage-problem <NNN> known-error
6
- # (and the sibling <NNN> close form). Transition renames the ticket
7
- # file, updates the Status field, and refreshes docs/problems/README.md
8
- # in the same commit per ADR-014 + ADR-022 + P062.
9
- #
10
- # This skill is the AUTHORITATIVE executor for the user-initiated
11
- # transition path per P093: it hosts the Step 7 transition block inline
12
- # (pre-flight checks, P063 external-root-cause detection, git mv + Edit
13
- # + P057 re-stage, Status field edit, ## Fix Released section write for
14
- # the verifying destination, P062 README.md refresh, ADR-014 commit).
15
- # The skill does NOT delegate execution back to /wr-itil:manage-problem;
16
- # the deprecation-window forwarder on manage-problem routes one-way to
17
- # this skill and returns its output verbatim (no round-trip).
18
- #
19
- # The in-skill Step 7 block on manage-problem remains the authoritative
20
- # source for in-skill callers (Step 9b auto-transition, the Parked path,
21
- # Step 9d closure inside review). Per ADR-010 amended "Split-skill
22
- # execution ownership": copy, not move — the user-initiated transition
23
- # path owned by this skill carries an inline scoped copy of the
24
- # mechanic; the host skill's in-house callers keep their inline copy.
25
- #
26
- # Structural assertion — Permitted Exception to the source-grep ban
27
- # (ADR-005 / P011 / ADR-037 contract-assertion pattern).
28
- #
29
- # @problem P071
30
- # @problem P093
31
- # @jtbd JTBD-001 (enforce governance without slowing down — discoverable surface + terminating contract)
32
- # @jtbd JTBD-101 (extend the suite with clear patterns — one skill per distinct user intent, split skills own execution)
33
- #
34
- # Cross-reference:
35
- # P071: docs/problems/071-argument-based-skill-subcommands-are-not-discoverable.open.md
36
- # P093: docs/problems/093-transition-problem-and-manage-problem-circular-delegation-for-nnn-status-args.*.md
37
- # ADR-010 amended (Skill Granularity section) — split naming + forwarder contract + split-skill execution ownership
38
- # ADR-013 Rule 1 — structured user interaction (tie-break selection, if any)
39
- # ADR-013 Rule 6 — AFK non-interactive fallback
40
- # ADR-014 — governance skills commit their own work (this skill owns the transition commit)
41
- # ADR-022 — .verifying.md suffix on release; Verification Pending distinct from Known Error
42
- # ADR-037 — contract-assertion bats pattern
43
- # P057 — git mv + Edit staging trap
44
- # P062 — README.md refresh on every transition
45
- # P063 — external-root-cause detection at Open → Known Error
46
-
47
- setup() {
48
- SKILL_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
49
- SKILL_FILE="${SKILL_DIR}/SKILL.md"
50
- }
51
-
52
- @test "SKILL.md exists and has frontmatter" {
53
- [ -f "$SKILL_FILE" ]
54
- run head -1 "$SKILL_FILE"
55
- [ "$status" -eq 0 ]
56
- [ "$output" = "---" ]
57
- }
58
-
59
- @test "SKILL.md frontmatter name is wr-itil:transition-problem (P071 + ADR-010 amended)" {
60
- # Split naming convention per ADR-010 amendment: <verb>-<object>.
61
- # The verb is "transition" (not "resolve", "advance", or
62
- # "change-status") because the original subcommand form was
63
- # `/wr-itil:manage-problem <NNN> known-error` — a status transition
64
- # with a declarative destination. The P071 ticket's split proposal
65
- # names this skill explicitly; the test locks the name in.
66
- run grep -n "^name: wr-itil:transition-problem$" "$SKILL_FILE"
67
- [ "$status" -eq 0 ]
68
- }
69
-
70
- @test "SKILL.md frontmatter description names the transition intent (P071)" {
71
- # Description must name "transition" / "status" / one of the
72
- # destination names (known-error / verifying / closed) so Claude Code
73
- # autocomplete surfaces the user intent rather than a generic name.
74
- run grep -inE "^description:.*(transition|status|lifecycle|advance)" "$SKILL_FILE"
75
- [ "$status" -eq 0 ]
76
- run grep -inE "^description:.*(known.error|verification|closed|verify)" "$SKILL_FILE"
77
- [ "$status" -eq 0 ]
78
- }
79
-
80
- @test "SKILL.md frontmatter allowed-tools includes Skill (retained for orchestrator composition)" {
81
- # Although this skill no longer delegates Step 7 execution to
82
- # /wr-itil:manage-problem (P093 fix — inline execution), the Skill
83
- # tool remains in allowed-tools so the skill can be invoked from
84
- # orchestrators (e.g. /wr-itil:work-problems) and so it can invoke
85
- # /wr-itil:report-upstream when P063 external-root-cause detection
86
- # fires option 1. Dropping Skill from allowed-tools would break both
87
- # composition paths.
88
- run grep -nE "^allowed-tools:.*Skill" "$SKILL_FILE"
89
- [ "$status" -eq 0 ]
90
- }
91
-
92
- @test "SKILL.md frontmatter allowed-tools includes Bash (ticket-file discovery)" {
93
- # Step 1 discovers the ticket file for a given ID by listing
94
- # docs/problems/<NNN>-*.md. That's a Bash invocation; without the
95
- # tool in allowed-tools, the discovery step cannot run.
96
- run grep -nE "^allowed-tools:.*Bash" "$SKILL_FILE"
97
- [ "$status" -eq 0 ]
98
- }
99
-
100
- @test "SKILL.md documents all three lifecycle transition destinations (ADR-022)" {
101
- # The canonical lifecycle per ADR-022: Open → Known Error → Verification Pending → Closed.
102
- # The skill must name each destination so users can pick the right
103
- # transition. Missing any destination would leave a gap in the
104
- # split coverage and force users back to the deprecated forwarder.
105
- run grep -inE "known.error" "$SKILL_FILE"
106
- [ "$status" -eq 0 ]
107
- run grep -inE "verifying|verification.pending" "$SKILL_FILE"
108
- [ "$status" -eq 0 ]
109
- run grep -inE "\.closed\.md|closed" "$SKILL_FILE"
110
- [ "$status" -eq 0 ]
111
- }
112
-
113
- @test "SKILL.md hosts the transition execution inline (P093 — no round-trip to manage-problem)" {
114
- # P093 inversion: the split skill owns BOTH intent selection AND
115
- # execution. The pre-flight / P063 external-root-cause detection /
116
- # staging-trap / README refresh stack is hosted inline here so a
117
- # contract-literal agent invoking /wr-itil:transition-problem NNN
118
- # <status> reaches a terminal state — no recursion into
119
- # /wr-itil:manage-problem.
120
- #
121
- # "No round-trip" scope: the SKILL.md body MUST NOT contain a
122
- # delegation-imperative instruction that routes Step 7 execution back
123
- # to /wr-itil:manage-problem. Citations to manage-problem in the
124
- # Related section or as a sibling skill reference are permitted —
125
- # this assertion targets delegation-imperative language only.
126
- #
127
- # Per ADR-010 amended "Split-skill execution ownership": copy, not
128
- # move. The Step 7 block on manage-problem stays in place for
129
- # in-skill callers (Step 9b auto-transition, Parked path, Step 9d
130
- # closure inside review). This skill carries a scoped inline copy for
131
- # the user-initiated transition path only.
132
- run grep -inE "delegate.{0,40}(to |/)?/?wr-itil:manage-problem|Skill tool.{0,40}manage-problem|manage-problem.{0,40}(via|through)? ?the Skill tool" "$SKILL_FILE"
133
- [ "$status" -ne 0 ]
134
- }
135
-
136
- @test "SKILL.md documents the inline Step 7 execution mechanics (P093 — authoritative executor)" {
137
- # Positive assertion: the skill must describe the full Step 7
138
- # mechanic so a contract-literal agent has enough information to
139
- # execute the transition without reading manage-problem's SKILL.md.
140
- # Each mechanic is represented by at least one identifying phrase;
141
- # missing any of them would leave a gap the execution path can fall
142
- # through.
143
- run grep -inE "pre-flight|pre.flight" "$SKILL_FILE"
144
- [ "$status" -eq 0 ]
145
- run grep -inE "git mv" "$SKILL_FILE"
146
- [ "$status" -eq 0 ]
147
- run grep -inE "git add" "$SKILL_FILE"
148
- [ "$status" -eq 0 ]
149
- run grep -inE "Fix Released" "$SKILL_FILE"
150
- [ "$status" -eq 0 ]
151
- run grep -inE "git commit|commit per ADR-014" "$SKILL_FILE"
152
- [ "$status" -eq 0 ]
153
- }
154
-
155
- @test "SKILL.md cites the P057 staging-trap rule (transitive contract)" {
156
- # The delegated Step 7 block on manage-problem implements the
157
- # staging-trap rule (re-stage after git mv + Edit). This skill must
158
- # reference P057 so the transitive-contract dependency is legible —
159
- # if the manage-problem Step 7 rule changes, this skill's delegation
160
- # contract changes with it.
161
- run grep -inE "P057|staging.trap|re-stage" "$SKILL_FILE"
162
- [ "$status" -eq 0 ]
163
- }
164
-
165
- @test "SKILL.md cites the P062 README.md refresh rule (transitive contract)" {
166
- # The delegated Step 7 block refreshes docs/problems/README.md on
167
- # every transition. This skill must reference P062 so the
168
- # downstream-refresh expectation is legible to callers (and so the
169
- # skill does not mistakenly skip the refresh on the assumption that
170
- # "the README is someone else's job").
171
- run grep -inE "P062|README\.md.*refresh|refresh.*README\.md" "$SKILL_FILE"
172
- [ "$status" -eq 0 ]
173
- }
174
-
175
- @test "SKILL.md cites ADR-022 (Verification Pending is a first-class status)" {
176
- # Known Error → Verification Pending is the transition most users
177
- # will type this skill for (it fires on every released fix). The
178
- # skill must cite ADR-022 so the semantic distinction — "Verification
179
- # Pending means fix SHIPPED, not fix-path-clear" — stays legible.
180
- run grep -inE "ADR-022" "$SKILL_FILE"
181
- [ "$status" -eq 0 ]
182
- }
183
-
184
- @test "SKILL.md documents the AFK non-interactive branch (ADR-013 Rule 6)" {
185
- # When /wr-itil:work-problems invokes this skill inside an AFK
186
- # subagent iteration, AskUserQuestion is unavailable — the skill
187
- # must degrade gracefully. Common case: Known Error → Verification
188
- # Pending fires automatically in the release-commit orchestration.
189
- run grep -inE "AFK|non-interactive|ADR-013 Rule 6|Rule 6" "$SKILL_FILE"
190
- [ "$status" -eq 0 ]
191
- }
192
-
193
- @test "SKILL.md does not carry a deprecated-arguments frontmatter flag (clean-split skill)" {
194
- # Architect advisory: transition-problem is a clean-split skill. The
195
- # deprecated-arguments flag is only valid on host skills with
196
- # forwarder routes — transition-problem is a forwarder TARGET, not
197
- # a host. The status argument (known-error / verifying / close) is
198
- # a *data parameter*, not a word-subcommand, per the P071 split rule.
199
- run grep -E "^deprecated-arguments:" "$SKILL_FILE"
200
- [ "$status" -ne 0 ]
201
- }
202
-
203
- @test "SKILL.md cites P071 and ADR-010 amended (traceability per ADR-037)" {
204
- # ADR-037 traceability: the skill spec cites the problem it closes
205
- # and the ADR that authorises the split.
206
- run grep -inE "P071|ADR-010" "$SKILL_FILE"
207
- [ "$status" -eq 0 ]
208
- }
209
-
210
- @test "SKILL.md documents the ticket-ID data-parameter shape (not a word-subcommand)" {
211
- # The ticket ID (<NNN>) is a data parameter per P071's split rule.
212
- # The status destination (known-error / verifying / close) is ALSO
213
- # a data parameter — the user supplies it alongside the ID. This is
214
- # the same shape as /wr-itil:report-upstream <NNN>: data parameters
215
- # are fine, word-subcommands routing to distinct user intents are not.
216
- run grep -inE "<NNN>|ticket.{0,5}ID|ID.*argument|data parameter" "$SKILL_FILE"
217
- [ "$status" -eq 0 ]
218
- }
219
-
220
- # ──────────────────────────────────────────────────────────────────────
221
- # P331 — Inline P134 rotation mechanism (anti-skip contract)
222
- #
223
- # Before P331's fix, the P134 line-3 rotation discipline was documented
224
- # at this skill's Step 7 (and 5 sibling surfaces) as a single-sentence
225
- # cross-document reference of shape:
226
- #
227
- # "Update the 'Last reviewed' line per the **Last-reviewed line
228
- # discipline (P134)** contract documented in `manage-problem`
229
- # SKILL.md Step 5"
230
- #
231
- # Agents reading the SKILL in a single-pass execution context did not
232
- # cross-navigate to manage-problem Step 5 and executed the obvious
233
- # "regenerate README.md" + "git add" steps without first archiving the
234
- # displaced line 3 to README-history.md. Iter-7 + iter-8 of 2026-05-30's
235
- # AFK work-problems session silently skipped the rotation in 2 of 9
236
- # transition-bearing iters (~22%).
237
- #
238
- # Positive control: reconcile-readme Step 5 inlines the same 3-step
239
- # Mechanism as an enumerated numbered list AT the execution site — that
240
- # surface fires correctly. The asymmetry confirms the bug class is
241
- # "cross-document reference at execution sites" vs "inlined mechanism".
242
- #
243
- # The fix elevates the rotation from a one-liner to a 4-step inline
244
- # Mechanism block (Read line 3 / Append-if-non-empty BEFORE rewrite /
245
- # Rewrite line 3 / Stage both). The assertions below lock the inline
246
- # block's presence at this skill's Step 7 execution site so future
247
- # refactors don't silently regress to the cross-doc one-liner.
248
-
249
- @test "SKILL.md inlines the P134 rotation Mechanism Read step at Step 7 (P331)" {
250
- # The mechanism must explicitly call out reading line 3 before
251
- # rewriting it. The canonical read pattern is `awk 'NR==3'` (matching
252
- # reconcile-readme Step 5's worked example); `head -3` or `sed -n '3p'`
253
- # are acceptable equivalents.
254
- run grep -iE "awk +'NR==3'|head +-3|sed +-n +'3p'|line 3.{0,40}(read|of \`docs/problems/README.md\`)" "$SKILL_FILE"
255
- [ "$status" -eq 0 ]
256
- }
257
-
258
- @test "SKILL.md inlines the P134 rotation Mechanism Append-BEFORE-Rewrite ordering (P331)" {
259
- # The ordering rule is load-bearing: the displaced line 3 MUST be
260
- # appended to README-history.md BEFORE the Edit-tool rewrite of line
261
- # 3. Without this rule, the Edit replace destroys the displaced
262
- # content. The assertion checks for explicit ordering language
263
- # (BEFORE / before rewriting / before step 3) co-located with the
264
- # README-history.md target.
265
- run grep -inE "(BEFORE|before).{0,80}(rewrit|step 3|Edit)" "$SKILL_FILE"
266
- [ "$status" -eq 0 ]
267
- }
268
-
269
- @test "SKILL.md cites README-history.md as the rotation archive target at Step 7 (P331)" {
270
- # The archive sibling docs/problems/README-history.md is named at the
271
- # rotation step. Without an explicit named target, the agent has no
272
- # destination to append to.
273
- run grep -E "README-history\.md" "$SKILL_FILE"
274
- [ "$status" -eq 0 ]
275
- }
276
-
277
- @test "SKILL.md cites P331 + P134 at the inlined rotation mechanism (traceability per ADR-037)" {
278
- # The inlined mechanism block cites P331 (this ticket) and P134
279
- # (the originating discipline ticket) so future readers can trace
280
- # the load-bearing rationale.
281
- run grep -inE "P331" "$SKILL_FILE"
282
- [ "$status" -eq 0 ]
283
- run grep -inE "P134" "$SKILL_FILE"
284
- [ "$status" -eq 0 ]
285
- }
@@ -1,331 +0,0 @@
1
- #!/usr/bin/env bats
2
- # Contract assertions for /wr-itil:transition-problems (P117 plural sibling).
3
- #
4
- # This skill is the BATCH variant of /wr-itil:transition-problem — it
5
- # advances multiple problem tickets through the lifecycle in one
6
- # invocation. Mirrors the P071 singular/plural split precedent
7
- # (work-problem vs work-problems) at a new grain: per-ticket transition
8
- # (singular) vs batch transition (plural).
9
- #
10
- # Why this skill exists (P117):
11
- # Closing N tickets via the singular skill costs N× SKILL.md reload
12
- # into the caller's context — this is the very SKILL.md-runtime-size
13
- # pressure P097 captures. The plural surface eliminates the N× cost
14
- # by inlining the per-ticket mechanic and looping in-band, single
15
- # commit at the end per ADR-014 batch grain.
16
- #
17
- # Architect-resolved design points (2026-04-26):
18
- # 1. Partial-failure semantics: skip-and-surface (succeeded pairs
19
- # commit at end; failed pairs surfaced in summary; zero successes
20
- # means no commit).
21
- # 2. Argument shape: space-separated `<NNN> <status> <NNN> <status>`
22
- # pairs — same shape as singular repeated N times. No P prefix,
23
- # no = separator, no CLI flags.
24
- # 3. Inline per-ticket mechanic — "copy, not move" per ADR-010
25
- # amended Split-skill execution ownership. NOT Skill-tool
26
- # re-invocation back into the singular (would reintroduce the
27
- # N×SKILL.md-reload cost the ticket targets).
28
- # 4. Single commit at end + single README refresh at end (P062
29
- # mechanic applied at batch grain).
30
- # 5. Three call sites now share the per-ticket mechanic via "copy,
31
- # not move": singular transition-problem, plural
32
- # transition-problems (this skill), and manage-problem in-skill
33
- # Step 7 block.
34
- #
35
- # Structural assertion — Permitted Exception to the source-grep ban
36
- # (ADR-005 / P011 / ADR-037 contract-assertion pattern). SKILL.md is
37
- # explicitly a contract document.
38
- #
39
- # @problem P117
40
- # @problem P071
41
- # @problem P093
42
- # @jtbd JTBD-001 (enforce governance without slowing down — eliminates
43
- # N×SKILL.md reload tax + ownership-boundary violation)
44
- # @jtbd JTBD-006 (progress backlog while AFK — work-problems may
45
- # delegate batch closures here without the per-ticket
46
- # reload cost)
47
- # @jtbd JTBD-101 (extend the suite with clear patterns — singular/plural
48
- # split mirrors the P071 work-problem/work-problems
49
- # precedent)
50
- #
51
- # Cross-reference:
52
- # P117: docs/problems/117-no-batch-transition-for-multiple-problem-tickets.open.md
53
- # P071: docs/problems/071-argument-based-skill-subcommands-are-not-discoverable.open.md
54
- # P093: docs/problems/093-transition-problem-and-manage-problem-circular-delegation-for-nnn-status-args.*.md
55
- # ADR-010 amended (Skill Granularity + Split-skill execution ownership) — copy-not-move guidance
56
- # ADR-013 Rule 6 — AFK non-interactive fallback
57
- # ADR-014 — single commit at batch-grain unit of work
58
- # ADR-022 — .verifying.md suffix
59
- # ADR-037 — contract-assertion bats pattern; canonical <skill>-contract.bats naming
60
- # P057 — git mv + Edit staging trap (re-stage per pair)
61
- # P062 — README.md refresh on transition (applied once at batch grain)
62
- # P063 — external-root-cause detection at Open → Known Error
63
-
64
- setup() {
65
- SKILL_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
66
- SKILL_FILE="${SKILL_DIR}/SKILL.md"
67
- SINGULAR_SKILL_FILE="${SKILL_DIR}/../transition-problem/SKILL.md"
68
- }
69
-
70
- @test "SKILL.md exists and has frontmatter" {
71
- [ -f "$SKILL_FILE" ]
72
- run head -1 "$SKILL_FILE"
73
- [ "$status" -eq 0 ]
74
- [ "$output" = "---" ]
75
- }
76
-
77
- @test "SKILL.md frontmatter name is wr-itil:transition-problems (plural sibling)" {
78
- # Plural naming convention per ADR-010 amended Skill Granularity rule.
79
- # The trailing 's' marks the plural sibling — same shape as
80
- # list-problems, review-problems, work-problems.
81
- run grep -n "^name: wr-itil:transition-problems$" "$SKILL_FILE"
82
- [ "$status" -eq 0 ]
83
- }
84
-
85
- @test "SKILL.md frontmatter description names the batch intent (P117)" {
86
- # Description must name "batch" / "multiple" / "many" so Claude Code
87
- # autocomplete distinguishes the plural from the singular at the
88
- # autocomplete-discoverability surface.
89
- run grep -inE "^description:.*(batch|multiple|many)" "$SKILL_FILE"
90
- [ "$status" -eq 0 ]
91
- # Description must also surface at least one of the destination
92
- # status names so the user can correlate the skill with the
93
- # lifecycle it operates on.
94
- run grep -inE "^description:.*(known.error|verification|verifying|closed|close|lifecycle|transition|advance)" "$SKILL_FILE"
95
- [ "$status" -eq 0 ]
96
- }
97
-
98
- @test "SKILL.md frontmatter allowed-tools includes Bash + Edit + Read + Skill + Agent" {
99
- # Bash: ticket-file discovery + git mv + git add + git commit.
100
- # Edit: Status field updates + ## Fix Released section writes.
101
- # Read: ticket file inspection + README.md refresh source-of-truth.
102
- # Skill: orchestrator composition (work-problems may delegate here).
103
- # Agent: risk-scorer commit-gate delegation per ADR-014 + ADR-015.
104
- run grep -nE "^allowed-tools:.*Bash" "$SKILL_FILE"
105
- [ "$status" -eq 0 ]
106
- run grep -nE "^allowed-tools:.*Edit" "$SKILL_FILE"
107
- [ "$status" -eq 0 ]
108
- run grep -nE "^allowed-tools:.*Read" "$SKILL_FILE"
109
- [ "$status" -eq 0 ]
110
- run grep -nE "^allowed-tools:.*Skill" "$SKILL_FILE"
111
- [ "$status" -eq 0 ]
112
- run grep -nE "^allowed-tools:.*Agent" "$SKILL_FILE"
113
- [ "$status" -eq 0 ]
114
- }
115
-
116
- @test "SKILL.md cites P117 (originating ticket) and ADR-010 amended (split authorisation)" {
117
- run grep -inE "P117" "$SKILL_FILE"
118
- [ "$status" -eq 0 ]
119
- run grep -inE "ADR-010" "$SKILL_FILE"
120
- [ "$status" -eq 0 ]
121
- }
122
-
123
- @test "SKILL.md cites the work-problem/work-problems precedent (P071 singular/plural split)" {
124
- # Plugin-developers reading this skill should immediately recognise
125
- # the singular/plural split pattern. P071 + the work-problem/
126
- # work-problems precedent is the explicit source.
127
- run grep -inE "P071|work-problem" "$SKILL_FILE"
128
- [ "$status" -eq 0 ]
129
- }
130
-
131
- @test "SKILL.md documents inline per-ticket mechanic — no Skill-tool delegation back to singular" {
132
- # Architect-resolved design point 3: inline per-ticket mechanic per
133
- # ADR-010 amended "copy, not move". Delegating back to the singular
134
- # via the Skill tool would re-introduce the N×SKILL.md-reload cost
135
- # this ticket targets — the core motivation for P117. The skill must
136
- # NOT contain delegation-imperative language routing pair execution
137
- # back to /wr-itil:transition-problem via Skill-tool invocation.
138
- #
139
- # Citations to the singular in the Related section or as a sibling
140
- # source-of-truth are PERMITTED — this assertion targets
141
- # delegation-imperative wording only.
142
- run grep -inE "delegate.{0,40}(to |/)?/?wr-itil:transition-problem|Skill tool.{0,40}transition-problem|invoke /?wr-itil:transition-problem.{0,40}per pair|loop.{0,40}invoke /?wr-itil:transition-problem" "$SKILL_FILE"
143
- [ "$status" -ne 0 ]
144
- }
145
-
146
- @test "SKILL.md documents the per-pair mechanic inline (Step 7 staging-trap rule + ## Fix Released)" {
147
- # Positive assertion: the skill must describe the per-pair mechanic
148
- # inline so a contract-literal agent has enough information to
149
- # execute the batch without reading the singular's SKILL.md.
150
- # Each mechanic is represented by at least one identifying phrase.
151
- run grep -inE "pre-flight|pre.flight" "$SKILL_FILE"
152
- [ "$status" -eq 0 ]
153
- run grep -inE "git mv" "$SKILL_FILE"
154
- [ "$status" -eq 0 ]
155
- run grep -inE "git add" "$SKILL_FILE"
156
- [ "$status" -eq 0 ]
157
- run grep -inE "Fix Released" "$SKILL_FILE"
158
- [ "$status" -eq 0 ]
159
- }
160
-
161
- @test "SKILL.md documents single-commit-at-end batch semantics (ADR-014 batch grain)" {
162
- # Architect-resolved design point 4 + user direction: ONE commit
163
- # covering all surviving transitions. The skill must say so
164
- # explicitly and must NOT instruct per-pair commits.
165
- run grep -inE "single commit|one commit|commit.{0,15}(at the )?end|batch commit|one (shared )?commit covering" "$SKILL_FILE"
166
- [ "$status" -eq 0 ]
167
- # Negative: no per-pair-commit instruction. Match wording like
168
- # "commit each pair", "commit per pair", "commit per ticket".
169
- run grep -inE "commit (each|per) (pair|ticket|transition)" "$SKILL_FILE"
170
- [ "$status" -ne 0 ]
171
- }
172
-
173
- @test "SKILL.md documents single README refresh at end (P062 at batch grain)" {
174
- # Architect-resolved design point 4: single render reflecting all
175
- # surviving renames, not N renders. Cite P062 explicitly so the
176
- # transitive contract is legible.
177
- run grep -inE "P062" "$SKILL_FILE"
178
- [ "$status" -eq 0 ]
179
- run grep -inE "(refresh|render|regenerate).{0,50}(README|once|at end|at the end)|README.{0,80}(once|at end|at the end)" "$SKILL_FILE"
180
- [ "$status" -eq 0 ]
181
- }
182
-
183
- @test "SKILL.md documents partial-failure skip-and-surface semantics" {
184
- # Architect-resolved design point 1: failed pairs are skipped, NOT
185
- # halted; succeeded pairs commit at end; zero successes means no
186
- # commit. The skill must make this explicit so users know what
187
- # outcome to expect when one ID is mistyped or one ticket is missing.
188
- run grep -inE "partial.failure|partial failure|failed pair|skip.{0,30}(failed|invalid)|surface.{0,30}(failure|failed)|succeeded pair" "$SKILL_FILE"
189
- [ "$status" -eq 0 ]
190
- # Zero-success path must be explicit: no commit if zero pairs
191
- # succeeded.
192
- run grep -inE "zero (pairs )?succeed|no successful|no pairs? succeed|all (pairs? )?fail" "$SKILL_FILE"
193
- [ "$status" -eq 0 ]
194
- }
195
-
196
- @test "SKILL.md cites P057 staging-trap rule (per-pair re-stage)" {
197
- # The per-pair mechanic implements P057's re-stage rule (git add
198
- # after Edit). Citation makes the transitive contract dependency
199
- # legible.
200
- run grep -inE "P057|staging.trap|re-stage" "$SKILL_FILE"
201
- [ "$status" -eq 0 ]
202
- }
203
-
204
- @test "SKILL.md cites P063 external-root-cause detection (Open → Known Error per pair)" {
205
- # P063 detection fires on every Open → Known Error transition,
206
- # including those done via batch. The plural inherits the singular's
207
- # AFK fallback (append the stable Upstream report pending marker).
208
- run grep -inE "P063|external.root.cause|upstream report pending" "$SKILL_FILE"
209
- [ "$status" -eq 0 ]
210
- }
211
-
212
- @test "SKILL.md cites ADR-022 (.verifying.md suffix on release)" {
213
- # Known Error → Verification Pending is a common batch transition
214
- # destination (release-batched closures). ADR-022 governs the
215
- # .verifying.md suffix + ## Fix Released section semantics.
216
- run grep -inE "ADR-022" "$SKILL_FILE"
217
- [ "$status" -eq 0 ]
218
- }
219
-
220
- @test "SKILL.md cites ADR-013 Rule 6 AFK fallback (inherited from singular)" {
221
- run grep -inE "AFK|non-interactive|ADR-013 Rule 6|Rule 6" "$SKILL_FILE"
222
- [ "$status" -eq 0 ]
223
- }
224
-
225
- @test "SKILL.md cites ADR-037 / contract-assertion drift detection note (split-skill ownership)" {
226
- # ADR-010 amended "copy, not move" creates drift risk between
227
- # singular and plural. The skill's documentation should name the
228
- # drift management strategy so future maintainers know how the
229
- # copies stay in sync.
230
- run grep -inE "ADR-010 amended|Split-skill execution ownership|copy.{0,5}not.{0,5}move" "$SKILL_FILE"
231
- [ "$status" -eq 0 ]
232
- }
233
-
234
- @test "SKILL.md documents the argument shape (space-separated <NNN> <status> pairs)" {
235
- # Argument shape per architect-resolved design point 2: repeating
236
- # the singular's shape, no P prefix, no = separator, no CLI flags.
237
- run grep -inE "<NNN>.{0,30}<status>|space.separated|pair.{0,5}of (arguments|tokens)|repeating .{0,30}arguments" "$SKILL_FILE"
238
- [ "$status" -eq 0 ]
239
- # Negative: no flag-style or = separator should be documented as
240
- # the canonical shape.
241
- run grep -inE "^\s*--pairs\b|<NNN>=<status>|<NNN>:<status>" "$SKILL_FILE"
242
- [ "$status" -ne 0 ]
243
- }
244
-
245
- @test "SKILL.md does not carry a deprecated-arguments frontmatter flag (clean-split sibling)" {
246
- # Architect: transition-problems is a clean-split sibling. The
247
- # deprecated-arguments flag is only valid on host skills with
248
- # forwarder routes — transition-problems is a clean addition with
249
- # no prior subcommand surface to deprecate.
250
- run grep -E "^deprecated-arguments:" "$SKILL_FILE"
251
- [ "$status" -ne 0 ]
252
- }
253
-
254
- @test "SKILL.md names singular sibling in Related (ADR-037 traceability + drift management)" {
255
- # Drift management: the plural carries an inline copy of the
256
- # singular's per-ticket mechanic. The Related section must name the
257
- # singular as the source-of-truth for the mechanic so future
258
- # maintainers know where to update both copies in sync.
259
- run grep -inE "wr-itil:transition-problem\b|/wr-itil:transition-problem|transition-problem/SKILL\.md|packages/itil/skills/transition-problem" "$SKILL_FILE"
260
- [ "$status" -eq 0 ]
261
- }
262
-
263
- @test "SKILL.md and singular SKILL.md share the staging-trap pattern wording (drift detection)" {
264
- # The per-pair mechanic on the plural carries an inline copy of the
265
- # singular's git mv + Edit + git add re-stage rule. Drift detection
266
- # at the contract level: the canonical 'git add' phrase must appear
267
- # in both files so a future edit that drops the re-stage from one
268
- # is immediately visible.
269
- [ -f "$SINGULAR_SKILL_FILE" ]
270
- run grep -cE "git add docs/problems/" "$SINGULAR_SKILL_FILE"
271
- singular_count="$output"
272
- run grep -cE "git add docs/problems/" "$SKILL_FILE"
273
- plural_count="$output"
274
- [ "$singular_count" -ge 1 ]
275
- [ "$plural_count" -ge 1 ]
276
- }
277
-
278
- # ──────────────────────────────────────────────────────────────────────
279
- # P331 — Inline P134 rotation mechanism (anti-skip contract; plural mirror)
280
- #
281
- # See the singular contract bats for the full rationale. At batch grain
282
- # the rotation still fires ONCE per batch (per Step 4a) — but the
283
- # Mechanism prose must be inlined here at the execution site too, so a
284
- # contract-literal agent invoking transition-problems doesn't skip the
285
- # archive step under the same one-liner-cross-doc failure mode P331
286
- # captured at the singular's Step 7. The cross-skill drift between
287
- # singular and plural is detected by the shared-substring assertions
288
- # below — if the singular inlines the mechanism but the plural still
289
- # carries the one-liner, the assertions fail.
290
-
291
- @test "SKILL.md inlines the P134 rotation Mechanism Read step at Step 4a (P331)" {
292
- # Same Read pattern as the singular — `awk 'NR==3'` or equivalent
293
- # before the line 3 rewrite. Inline mechanism at the execution site
294
- # so the rotation cannot be silently skipped on the cross-doc trip
295
- # to manage-problem Step 5.
296
- run grep -iE "awk +'NR==3'|head +-3|sed +-n +'3p'|line 3.{0,40}(read|of \`docs/problems/README.md\`)" "$SKILL_FILE"
297
- [ "$status" -eq 0 ]
298
- }
299
-
300
- @test "SKILL.md inlines the P134 rotation Mechanism Append-BEFORE-Rewrite ordering (P331)" {
301
- # Ordering rule load-bearing per the singular — see the singular's
302
- # rationale comment. Plural inherits the rule at batch grain.
303
- run grep -inE "(BEFORE|before).{0,80}(rewrit|step 3|Edit)" "$SKILL_FILE"
304
- [ "$status" -eq 0 ]
305
- }
306
-
307
- @test "SKILL.md cites README-history.md as the rotation archive target at Step 4a (P331)" {
308
- run grep -E "README-history\.md" "$SKILL_FILE"
309
- [ "$status" -eq 0 ]
310
- }
311
-
312
- @test "SKILL.md cites P331 + P134 at the inlined rotation mechanism (traceability per ADR-037)" {
313
- run grep -inE "P331" "$SKILL_FILE"
314
- [ "$status" -eq 0 ]
315
- run grep -inE "P134" "$SKILL_FILE"
316
- [ "$status" -eq 0 ]
317
- }
318
-
319
- @test "SKILL.md and singular SKILL.md share the P134 Read-step pattern (drift detection)" {
320
- # The canonical Read-step pattern `awk 'NR==3'` (or equivalent) must
321
- # appear in BOTH the singular SKILL.md and this plural SKILL.md.
322
- # Inline-copy drift between the two re-opens P331; this assertion
323
- # surfaces the drift as a contract failure.
324
- [ -f "$SINGULAR_SKILL_FILE" ]
325
- run grep -cE "awk +'NR==3'|head +-3|sed +-n +'3p'" "$SINGULAR_SKILL_FILE"
326
- singular_count="$output"
327
- run grep -cE "awk +'NR==3'|head +-3|sed +-n +'3p'" "$SKILL_FILE"
328
- plural_count="$output"
329
- [ "$singular_count" -ge 1 ]
330
- [ "$plural_count" -ge 1 ]
331
- }