@windyroad/itil 0.9.0 → 0.10.0-preview.144
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.
- package/.claude-plugin/plugin.json +1 -1
- package/package.json +1 -1
- package/skills/list-problems/SKILL.md +110 -0
- package/skills/list-problems/test/list-problems-contract.bats +100 -0
- package/skills/manage-problem/SKILL.md +17 -2
- package/skills/manage-problem/test/manage-problem-list-forwarder.bats +66 -0
package/package.json
CHANGED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wr-itil:list-problems
|
|
3
|
+
description: List open and known-error problem tickets from docs/problems/ sorted by WSJF priority. Read-only display of the current backlog — no edits, no interaction. Shown as a markdown table with ID, title, severity, status, and effort columns.
|
|
4
|
+
allowed-tools: Read, Bash, Grep, Glob
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# List Problems
|
|
8
|
+
|
|
9
|
+
Display the current problem backlog — open and known-error tickets — sorted by Weighted Shortest Job First (WSJF) priority. This skill is a pure read-only view of `docs/problems/`; it does not edit, transition, close, or create tickets. For those operations, use the dedicated skills (`/wr-itil:manage-problem`, `/wr-itil:transition-problem`, etc.).
|
|
10
|
+
|
|
11
|
+
This skill is the P071 phased-landing split of `/wr-itil:manage-problem list` per ADR-010 amended Skill Granularity rule: one skill per distinct user intent. The original `/wr-itil:manage-problem list` subcommand route remains as a thin-router forwarder during the deprecation window but is scheduled for removal in `@windyroad/itil`'s next major version.
|
|
12
|
+
|
|
13
|
+
## Scope
|
|
14
|
+
|
|
15
|
+
Included in the ranking table:
|
|
16
|
+
- `docs/problems/*.open.md` — open tickets (under investigation)
|
|
17
|
+
- `docs/problems/*.known-error.md` — known errors (root cause confirmed, fix NOT yet released)
|
|
18
|
+
|
|
19
|
+
Shown in separate sections, excluded from the dev-work WSJF ranking per ADR-022:
|
|
20
|
+
- `docs/problems/*.verifying.md` — Verification Pending (fix released, awaiting user verification; WSJF multiplier 0)
|
|
21
|
+
- `docs/problems/*.parked.md` — Parked on upstream or user-suspended (WSJF multiplier 0)
|
|
22
|
+
|
|
23
|
+
`docs/problems/*.closed.md` is omitted entirely (the view is of active backlog, not the closed archive).
|
|
24
|
+
|
|
25
|
+
## Steps
|
|
26
|
+
|
|
27
|
+
### 1. Check README.md cache freshness
|
|
28
|
+
|
|
29
|
+
Reuse the same `git log`-based freshness test as `/wr-itil:manage-problem review` Step 9 (per P031 — filesystem mtime is unreliable in worktrees and fresh checkouts, so git history is the authoritative staleness signal):
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
readme_commit=$(git log -1 --format=%H -- docs/problems/README.md 2>/dev/null)
|
|
33
|
+
if [ -z "$readme_commit" ] || \
|
|
34
|
+
git log --oneline "${readme_commit}..HEAD" -- 'docs/problems/*.md' ':!docs/problems/README.md' 2>/dev/null | grep -q .; then
|
|
35
|
+
echo "stale"
|
|
36
|
+
fi
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Cache fresh** (no output): read `docs/problems/README.md` directly — it already contains the ranked table from the last review. Display the WSJF Rankings section + Verification Queue section + Parked section as-is. Note in the output: "Using cached ranking from [timestamp in README.md]".
|
|
40
|
+
|
|
41
|
+
**Cache stale** (prints "stale") or `README.md` missing: run the live scan in Step 2.
|
|
42
|
+
|
|
43
|
+
### 2. Live scan (cache-stale fallback)
|
|
44
|
+
|
|
45
|
+
Enumerate the backlog files via glob:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
ls docs/problems/*.open.md docs/problems/*.known-error.md 2>/dev/null
|
|
49
|
+
ls docs/problems/*.verifying.md 2>/dev/null # for Verification Queue section
|
|
50
|
+
ls docs/problems/*.parked.md 2>/dev/null # for Parked section
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
For each `.open.md` and `.known-error.md` file, read the `**Status**`, `**Priority**`, `**Effort**`, and `**WSJF**` lines from the frontmatter section. Compute WSJF if missing: `WSJF = (Severity × StatusMultiplier) / EffortDivisor` per `/wr-itil:manage-problem` WSJF Prioritisation. Default to M (divisor 2) when Effort is absent; flag missing scores so the user knows a review is overdue.
|
|
54
|
+
|
|
55
|
+
For each `.verifying.md` file, read the `## Fix Released` marker and extract the release age for the `Likely verified?` column per P048 Candidate 4 (within-skill default: 14 days = `yes`).
|
|
56
|
+
|
|
57
|
+
### 3. Display
|
|
58
|
+
|
|
59
|
+
Render three sections matching the README.md format so cached and live output look identical:
|
|
60
|
+
|
|
61
|
+
**WSJF Rankings** — dev-work queue (open + known-error), sorted by WSJF descending:
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
| WSJF | ID | Title | Severity | Status | Effort |
|
|
65
|
+
|------|-----|-------|----------|--------|--------|
|
|
66
|
+
| <score> | P<NNN> | <title> | <severity> | <status> | <effort> |
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**Verification Queue** — `.verifying.md` tickets, sorted by release age (oldest first):
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
| ID | Title | Released | Likely verified? |
|
|
73
|
+
|----|-------|----------|------------------|
|
|
74
|
+
| P<NNN> | <title> | <release marker> | yes (N days) / no (N days) |
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Parked** — `.parked.md` tickets:
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
| ID | Title | Reason | Parked since |
|
|
81
|
+
|----|-------|--------|-------------|
|
|
82
|
+
| P<NNN> | <title> | <reason> | <date> |
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
If a section is empty, omit it rather than rendering an empty header.
|
|
86
|
+
|
|
87
|
+
### 4. Trailing suggestions
|
|
88
|
+
|
|
89
|
+
After the tables, print one of two short pointers depending on what the output showed:
|
|
90
|
+
|
|
91
|
+
- When dev-work queue is non-empty: `Run /wr-itil:work-problem to work the highest-WSJF ticket, or /wr-itil:manage-problem <NNN> to update a specific ticket.` (Note: `/wr-itil:work-problem` is singular — distinct from `/wr-itil:work-problems` plural AFK orchestrator.)
|
|
92
|
+
- When Verification Queue is non-empty: `Run /wr-itil:manage-problem review to trigger the verification prompt for pending tickets.`
|
|
93
|
+
|
|
94
|
+
## Ownership boundary
|
|
95
|
+
|
|
96
|
+
`list-problems` does not modify, rename, or commit any files. If the README.md cache is stale, `list-problems` performs a live scan but does NOT rewrite `README.md` — refreshing the cache is `/wr-itil:manage-problem review`'s ownership. The trailing-suggestion pointer surfaces this boundary so the user can refresh via the correct skill when they notice stale output.
|
|
97
|
+
|
|
98
|
+
## Related
|
|
99
|
+
|
|
100
|
+
- **P071** (`docs/problems/071-argument-based-skill-subcommands-are-not-discoverable.open.md`) — originating ticket. This skill is phase 1 of the P071 phased-landing plan.
|
|
101
|
+
- **ADR-010 amended** (`docs/decisions/010-rename-wr-problem-to-wr-itil.proposed.md` — Skill Granularity section) — canonical skill-split naming + forwarder contract + `deprecated-arguments: true` frontmatter flag.
|
|
102
|
+
- **ADR-022** (`docs/decisions/022-verification-pending-status.proposed.md`) — Verification Pending status conventions; `.verifying.md` exclusion from WSJF ranking.
|
|
103
|
+
- **ADR-037** (`docs/decisions/037-skill-testing-strategy.proposed.md`) — contract-assertion bats pattern applied to this skill.
|
|
104
|
+
- **P031** — git-history freshness check rationale (mtime unreliable in worktrees).
|
|
105
|
+
- **P048** Candidate 4 — the 14-day `Likely verified?` heuristic.
|
|
106
|
+
- **JTBD-001** (`docs/jtbd/solo-developer/JTBD-001-enforce-governance.proposed.md`) — discoverable surface via `/wr-itil:` autocomplete.
|
|
107
|
+
- **JTBD-101** (`docs/jtbd/plugin-developer/JTBD-101-extend-suite.proposed.md`) — one skill per distinct user intent.
|
|
108
|
+
- `packages/itil/skills/manage-problem/SKILL.md` — hosts the thin-router forwarder for the deprecated `manage-problem list` form.
|
|
109
|
+
|
|
110
|
+
$ARGUMENTS
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
#!/usr/bin/env bats
|
|
2
|
+
# Contract assertions for /wr-itil:list-problems (P071 split slice 1).
|
|
3
|
+
#
|
|
4
|
+
# This skill hosts the "list open and known-error problems" user intent
|
|
5
|
+
# previously hidden behind /wr-itil:manage-problem list. It is a pure
|
|
6
|
+
# read-only display skill — no branching, no interaction, no file edits.
|
|
7
|
+
#
|
|
8
|
+
# Structural assertion — Permitted Exception to the source-grep ban
|
|
9
|
+
# (ADR-005 / P011 / ADR-037 contract-assertion pattern).
|
|
10
|
+
#
|
|
11
|
+
# @problem P071
|
|
12
|
+
# @jtbd JTBD-001 (enforce governance without slowing down — discoverable surface)
|
|
13
|
+
# @jtbd JTBD-101 (extend the suite with clear patterns — one skill per distinct user intent)
|
|
14
|
+
#
|
|
15
|
+
# Cross-reference:
|
|
16
|
+
# P071: docs/problems/071-argument-based-skill-subcommands-are-not-discoverable.open.md
|
|
17
|
+
# ADR-010 amended (Skill Granularity section) — split naming + forwarder contract
|
|
18
|
+
# ADR-022 — Verification Pending status conventions (list-problems respects `.verifying.md` exclusion)
|
|
19
|
+
# ADR-037 — contract-assertion bats pattern
|
|
20
|
+
|
|
21
|
+
setup() {
|
|
22
|
+
SKILL_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
|
|
23
|
+
SKILL_FILE="${SKILL_DIR}/SKILL.md"
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@test "SKILL.md exists and has frontmatter" {
|
|
27
|
+
[ -f "$SKILL_FILE" ]
|
|
28
|
+
run head -1 "$SKILL_FILE"
|
|
29
|
+
[ "$status" -eq 0 ]
|
|
30
|
+
[ "$output" = "---" ]
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@test "SKILL.md frontmatter name is wr-itil:list-problems (P071 + ADR-010 amended)" {
|
|
34
|
+
# Split naming convention per ADR-010 amendment: <verb>-<object> pair.
|
|
35
|
+
# The new skill's name must match the phased-landing plan pinned in P071.
|
|
36
|
+
run grep -n "^name: wr-itil:list-problems$" "$SKILL_FILE"
|
|
37
|
+
[ "$status" -eq 0 ]
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@test "SKILL.md frontmatter description names the list intent (P071)" {
|
|
41
|
+
# Description must name "list" and "problem" so Claude Code autocomplete
|
|
42
|
+
# surfaces the user intent rather than a generic name.
|
|
43
|
+
run grep -inE "^description:.*list.*problem|^description:.*problem.*list" "$SKILL_FILE"
|
|
44
|
+
[ "$status" -eq 0 ]
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@test "SKILL.md frontmatter allowed-tools is read-only (P071 + architect Q3)" {
|
|
48
|
+
# Architect Q3: pure read-only list display. No Write, no Edit, no
|
|
49
|
+
# AskUserQuestion. This assertion is the enforceable contract — future
|
|
50
|
+
# maintainers cannot accidentally grow the tool surface past the intent.
|
|
51
|
+
run grep -nE "^allowed-tools:" "$SKILL_FILE"
|
|
52
|
+
[ "$status" -eq 0 ]
|
|
53
|
+
run grep -E "^allowed-tools:.*(Write|Edit|AskUserQuestion)" "$SKILL_FILE"
|
|
54
|
+
[ "$status" -ne 0 ]
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@test "SKILL.md documents the read-only scan scope (P071)" {
|
|
58
|
+
# The skill reads .open.md and .known-error.md files from docs/problems/.
|
|
59
|
+
# .verifying.md and .parked.md are excluded from the dev-work ranking per
|
|
60
|
+
# ADR-022 (Verification Pending) and the Parked-policy; but they MAY be
|
|
61
|
+
# shown in dedicated sections. The SKILL.md must name both `.open.md` and
|
|
62
|
+
# `.known-error.md` glob patterns explicitly so the contract is legible.
|
|
63
|
+
run grep -inE "\.open\.md" "$SKILL_FILE"
|
|
64
|
+
[ "$status" -eq 0 ]
|
|
65
|
+
run grep -inE "\.known-error\.md" "$SKILL_FILE"
|
|
66
|
+
[ "$status" -eq 0 ]
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@test "SKILL.md reuses the git-log freshness check from manage-problem review (P071 + architect Q4)" {
|
|
70
|
+
# Architect Q4: reuse the git-log freshness check from manage-problem
|
|
71
|
+
# review (same skill suite, same cache semantics per P031).
|
|
72
|
+
run grep -inE "git log.*README\.md|readme_commit|git log -1 --format=%H" "$SKILL_FILE"
|
|
73
|
+
[ "$status" -eq 0 ]
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
@test "SKILL.md cites P071 and ADR-010 amended (P071 + ADR-025)" {
|
|
77
|
+
# ADR-025 inheritance per ADR-037: contract-assertion bats should reflect
|
|
78
|
+
# traceability cites on the skill spec document.
|
|
79
|
+
run grep -inE "P071|ADR-010" "$SKILL_FILE"
|
|
80
|
+
[ "$status" -eq 0 ]
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
@test "SKILL.md does not carry a deprecated-arguments frontmatter flag (clean-split skill)" {
|
|
84
|
+
# Architect advisory: list-problems is a clean-split skill with no
|
|
85
|
+
# argument-subcommands itself. ADR-010 amendment's
|
|
86
|
+
# `deprecated-arguments: true` flag is only valid on host skills with
|
|
87
|
+
# forwarder routes — list-problems is the forwarder TARGET, not the
|
|
88
|
+
# host. It must NOT carry the flag.
|
|
89
|
+
run grep -E "^deprecated-arguments:" "$SKILL_FILE"
|
|
90
|
+
[ "$status" -ne 0 ]
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
@test "SKILL.md does not use word-argument subcommand branching (P071 regression guard)" {
|
|
94
|
+
# The whole point of P071: Claude Code autocomplete does not surface
|
|
95
|
+
# arguments. A clean-split skill must not reintroduce word-arg subcommand
|
|
96
|
+
# routing. The SKILL.md must not contain `If arguments start with "list"`
|
|
97
|
+
# / `If arguments contain "work"` / etc. patterns.
|
|
98
|
+
run grep -inE "If arguments start with|If arguments contain" "$SKILL_FILE"
|
|
99
|
+
[ "$status" -ne 0 ]
|
|
100
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: wr-itil:manage-problem
|
|
3
3
|
description: Create, update, or transition a problem ticket using an ITIL-aligned problem management workflow with WSJF prioritisation. Supports creating new problems, updating root cause analysis, transitioning status, and closing problems.
|
|
4
|
-
allowed-tools: Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion
|
|
4
|
+
allowed-tools: Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion, Skill
|
|
5
|
+
deprecated-arguments: true
|
|
5
6
|
---
|
|
6
7
|
|
|
7
8
|
# Problem Management Skill
|
|
@@ -125,11 +126,25 @@ What "work" means depends on the problem's status:
|
|
|
125
126
|
|
|
126
127
|
Determine the operation from `$ARGUMENTS`:
|
|
127
128
|
- If arguments start with a number (e.g., "011"), this is an update or transition
|
|
128
|
-
- If arguments contain "list",
|
|
129
|
+
- If arguments contain "list", **delegate to `/wr-itil:list-problems`** via the Skill tool. See "Deprecated-argument forwarders" below.
|
|
129
130
|
- If arguments contain "work", run a **review** first (step 9), then begin working the highest-WSJF problem
|
|
130
131
|
- If arguments contain "review", run the review (step 9) only
|
|
131
132
|
- Otherwise, this is a new problem creation
|
|
132
133
|
|
|
134
|
+
#### Deprecated-argument forwarders (ADR-010 amended + P071)
|
|
135
|
+
|
|
136
|
+
Per ADR-010's amended Skill Granularity section, word-argument subcommands that name distinct user intents are being split into their own named skills. During the deprecation window, this skill's Step 1 parser retains the legacy argument routes as **thin-router forwarders** that re-invoke the new named skill via the Skill tool AND emit a one-line systemMessage with the canonical deprecation notice so the user learns the new invocation shape.
|
|
137
|
+
|
|
138
|
+
**Forwarder for `list`** (P071 split slice 1 — new skill `/wr-itil:list-problems`):
|
|
139
|
+
|
|
140
|
+
When `$ARGUMENTS` contains the word `list` as a top-level argument (not inside a ticket body edit), delegate to `/wr-itil:list-problems` via the Skill tool and emit this systemMessage verbatim:
|
|
141
|
+
|
|
142
|
+
> `/wr-itil:manage-problem list is deprecated; use /wr-itil:list-problems directly. This forwarder will be removed in @windyroad/itil's next major version.`
|
|
143
|
+
|
|
144
|
+
The forwarder does NOT re-implement the list logic locally — it invokes the Skill tool with `wr-itil:list-problems` and returns the new skill's output verbatim. Duplicating the logic would harden the deprecation window into a permanent fork.
|
|
145
|
+
|
|
146
|
+
Forwarders for `work`, `review`, `<NNN> known-error`, and `<NNN> close` land in subsequent P071 phased-landing slices (see P071 ticket's "Split proposal" section for the full plan). Until those slices land, the corresponding Step-2+ branches continue to execute inline.
|
|
147
|
+
|
|
133
148
|
### 2. For new problems: Check for duplicates FIRST
|
|
134
149
|
|
|
135
150
|
Before creating, search existing problems for similar issues. The user may not know a problem already exists.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#!/usr/bin/env bats
|
|
2
|
+
# Contract assertions for manage-problem's `list` subcommand forwarder (P071 split slice 1).
|
|
3
|
+
#
|
|
4
|
+
# Per ADR-010 amended (Skill Granularity section) + P071 phased plan:
|
|
5
|
+
# `/wr-itil:manage-problem list` delegates to the new `/wr-itil:list-problems`
|
|
6
|
+
# skill via a thin-router forwarder. Original skill carries
|
|
7
|
+
# `deprecated-arguments: true` frontmatter; forwarder emits a
|
|
8
|
+
# canonical one-line systemMessage deprecation notice.
|
|
9
|
+
#
|
|
10
|
+
# Structural assertion — Permitted Exception to the source-grep ban
|
|
11
|
+
# (ADR-005 / P011 / ADR-037 contract-assertion pattern).
|
|
12
|
+
#
|
|
13
|
+
# @problem P071
|
|
14
|
+
# @jtbd JTBD-001 (enforce governance without slowing down)
|
|
15
|
+
# @jtbd JTBD-101 (extend the suite with clear patterns)
|
|
16
|
+
#
|
|
17
|
+
# Cross-reference:
|
|
18
|
+
# P071: docs/problems/071-argument-based-skill-subcommands-are-not-discoverable.open.md
|
|
19
|
+
# ADR-010 amended — split naming + forwarder contract + deprecated-arguments flag
|
|
20
|
+
# ADR-013 Rule 1 — structured user interaction (forwarder emits systemMessage, not AskUserQuestion)
|
|
21
|
+
# ADR-037 — contract-assertion bats pattern
|
|
22
|
+
|
|
23
|
+
setup() {
|
|
24
|
+
SKILL_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
|
|
25
|
+
SKILL_FILE="${SKILL_DIR}/SKILL.md"
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@test "manage-problem SKILL.md frontmatter has deprecated-arguments: true (ADR-010 amended)" {
|
|
29
|
+
# ADR-010 amendment pins the frontmatter flag name as `deprecated-arguments`.
|
|
30
|
+
# The host skill of any forwarder route must carry this flag so ADR-037
|
|
31
|
+
# cross-plugin contract assertions can find the opt-in during the
|
|
32
|
+
# deprecation window.
|
|
33
|
+
run grep -nE "^deprecated-arguments:[[:space:]]*true[[:space:]]*$" "$SKILL_FILE"
|
|
34
|
+
[ "$status" -eq 0 ]
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@test "manage-problem Step 1 forwards 'list' argument to /wr-itil:list-problems (P071)" {
|
|
38
|
+
# The forwarder names the target skill explicitly so the router is legible
|
|
39
|
+
# at the contract level. ADR-010's canonical shape: "invokes the new
|
|
40
|
+
# named skill via the Skill tool, not via re-prompting the user".
|
|
41
|
+
run grep -inE "/wr-itil:list-problems" "$SKILL_FILE"
|
|
42
|
+
[ "$status" -eq 0 ]
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@test "manage-problem Step 1 emits the canonical deprecation notice (ADR-010 amended)" {
|
|
46
|
+
# ADR-010's canonical deprecation-notice template:
|
|
47
|
+
# "/wr-<plugin>:<old> <arg> is deprecated; use /wr-<plugin>:<new>
|
|
48
|
+
# directly. This forwarder will be removed in <plugin>'s next major
|
|
49
|
+
# version."
|
|
50
|
+
# The notice MUST be emitted as a systemMessage (not AskUserQuestion)
|
|
51
|
+
# because deprecation is informational, not decisional (ADR-013 Rule 1
|
|
52
|
+
# structured-interaction scope).
|
|
53
|
+
run grep -inE "is deprecated.*use /wr-itil:list-problems|deprecated.*list-problems|removed in .* next major version" "$SKILL_FILE"
|
|
54
|
+
[ "$status" -eq 0 ]
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@test "manage-problem Step 1 forwarder does not re-implement the list logic (P071 regression guard)" {
|
|
58
|
+
# The forwarder must not duplicate the list logic — it must delegate.
|
|
59
|
+
# Per ADR-010: "thin-router forwarder re-invokes the new named skill
|
|
60
|
+
# via the Skill tool". If the forwarder grows its own scan logic, the
|
|
61
|
+
# deprecation window will harden into a permanent fork. Guard against
|
|
62
|
+
# this by asserting the forwarder block mentions "delegate" or
|
|
63
|
+
# "Skill tool" language near the list-problems reference.
|
|
64
|
+
run grep -inE "delegate.*list-problems|Skill tool.*list-problems|list-problems.*Skill tool" "$SKILL_FILE"
|
|
65
|
+
[ "$status" -eq 0 ]
|
|
66
|
+
}
|