@windyroad/itil 0.10.1 → 0.11.0
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/manage-problem/SKILL.md +10 -2
- package/skills/manage-problem/test/manage-problem-review-forwarder.bats +71 -0
- package/skills/review-problems/SKILL.md +185 -0
- package/skills/review-problems/test/review-problems-contract.bats +177 -0
package/package.json
CHANGED
|
@@ -128,7 +128,7 @@ Determine the operation from `$ARGUMENTS`:
|
|
|
128
128
|
- If arguments start with a number (e.g., "011"), this is an update or transition
|
|
129
129
|
- If arguments contain "list", **delegate to `/wr-itil:list-problems`** via the Skill tool. See "Deprecated-argument forwarders" below.
|
|
130
130
|
- If arguments contain "work", run a **review** first (step 9), then begin working the highest-WSJF problem
|
|
131
|
-
- If arguments contain "review",
|
|
131
|
+
- If arguments contain "review", **delegate to `/wr-itil:review-problems`** via the Skill tool. See "Deprecated-argument forwarders" below.
|
|
132
132
|
- Otherwise, this is a new problem creation
|
|
133
133
|
|
|
134
134
|
#### Deprecated-argument forwarders (ADR-010 amended + P071)
|
|
@@ -143,7 +143,15 @@ When `$ARGUMENTS` contains the word `list` as a top-level argument (not inside a
|
|
|
143
143
|
|
|
144
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
145
|
|
|
146
|
-
|
|
146
|
+
**Forwarder for `review`** (P071 split slice 2 — new skill `/wr-itil:review-problems`):
|
|
147
|
+
|
|
148
|
+
When `$ARGUMENTS` contains the word `review` as a top-level argument (not inside a ticket body edit), delegate to `/wr-itil:review-problems` via the Skill tool and emit this systemMessage verbatim:
|
|
149
|
+
|
|
150
|
+
> `/wr-itil:manage-problem review is deprecated; use /wr-itil:review-problems directly. This forwarder will be removed in @windyroad/itil's next major version.`
|
|
151
|
+
|
|
152
|
+
The forwarder does NOT re-implement the review logic locally — it invokes the Skill tool with `wr-itil:review-problems` and returns the new skill's output verbatim. Duplicating the Step 9 re-scoring / auto-transition / verification-prompt / README-refresh stack would harden the deprecation window into a permanent fork.
|
|
153
|
+
|
|
154
|
+
Forwarders for `work`, `<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
155
|
|
|
148
156
|
### 2. For new problems: Check for duplicates FIRST
|
|
149
157
|
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
#!/usr/bin/env bats
|
|
2
|
+
# Contract assertions for manage-problem's `review` subcommand forwarder (P071 split slice 2).
|
|
3
|
+
#
|
|
4
|
+
# Per ADR-010 amended (Skill Granularity section) + P071 phased plan:
|
|
5
|
+
# `/wr-itil:manage-problem review` delegates to the new
|
|
6
|
+
# `/wr-itil:review-problems` skill via a thin-router forwarder. Original
|
|
7
|
+
# skill carries `deprecated-arguments: true` frontmatter (asserted in
|
|
8
|
+
# the list-forwarder bats); this file asserts the review-forwarder-specific
|
|
9
|
+
# contract.
|
|
10
|
+
#
|
|
11
|
+
# Structural assertion — Permitted Exception to the source-grep ban
|
|
12
|
+
# (ADR-005 / P011 / ADR-037 contract-assertion pattern).
|
|
13
|
+
#
|
|
14
|
+
# @problem P071
|
|
15
|
+
# @jtbd JTBD-001 (enforce governance without slowing down)
|
|
16
|
+
# @jtbd JTBD-101 (extend the suite with clear patterns)
|
|
17
|
+
#
|
|
18
|
+
# Cross-reference:
|
|
19
|
+
# P071: docs/problems/071-argument-based-skill-subcommands-are-not-discoverable.open.md
|
|
20
|
+
# ADR-010 amended — split naming + forwarder contract + deprecated-arguments flag
|
|
21
|
+
# ADR-013 Rule 1 — structured user interaction (forwarder emits systemMessage, not AskUserQuestion)
|
|
22
|
+
# ADR-037 — contract-assertion bats pattern
|
|
23
|
+
|
|
24
|
+
setup() {
|
|
25
|
+
SKILL_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
|
|
26
|
+
SKILL_FILE="${SKILL_DIR}/SKILL.md"
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@test "manage-problem Step 1 forwards 'review' argument to /wr-itil:review-problems (P071)" {
|
|
30
|
+
# The forwarder names the target skill explicitly so the router is legible
|
|
31
|
+
# at the contract level. ADR-010's canonical shape: "invokes the new
|
|
32
|
+
# named skill via the Skill tool, not via re-prompting the user".
|
|
33
|
+
run grep -inE "/wr-itil:review-problems" "$SKILL_FILE"
|
|
34
|
+
[ "$status" -eq 0 ]
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@test "manage-problem Step 1 emits the canonical review deprecation notice (ADR-010 amended)" {
|
|
38
|
+
# ADR-010's canonical deprecation-notice template:
|
|
39
|
+
# "/wr-<plugin>:<old> <arg> is deprecated; use /wr-<plugin>:<new>
|
|
40
|
+
# directly. This forwarder will be removed in <plugin>'s next major
|
|
41
|
+
# version."
|
|
42
|
+
# The notice MUST be emitted as a systemMessage (not AskUserQuestion)
|
|
43
|
+
# because deprecation is informational, not decisional (ADR-013 Rule 1
|
|
44
|
+
# structured-interaction scope). The review-forwarder notice is
|
|
45
|
+
# distinct from the list-forwarder notice; both must co-exist verbatim.
|
|
46
|
+
run grep -inE "is deprecated.*use /wr-itil:review-problems|deprecated.*review-problems|removed in .* next major version" "$SKILL_FILE"
|
|
47
|
+
[ "$status" -eq 0 ]
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@test "manage-problem Step 1 review-forwarder does not re-implement the review logic (P071 regression guard)" {
|
|
51
|
+
# The forwarder must not duplicate the review logic — it must delegate.
|
|
52
|
+
# Per ADR-010: "thin-router forwarder re-invokes the new named skill
|
|
53
|
+
# via the Skill tool". If the forwarder grows its own re-scoring or
|
|
54
|
+
# README-refresh logic, the deprecation window will harden into a
|
|
55
|
+
# permanent fork. Guard against this by asserting the forwarder block
|
|
56
|
+
# mentions "delegate" or "Skill tool" language near the
|
|
57
|
+
# review-problems reference.
|
|
58
|
+
run grep -inE "delegate.*review-problems|Skill tool.*review-problems|review-problems.*Skill tool" "$SKILL_FILE"
|
|
59
|
+
[ "$status" -eq 0 ]
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@test "manage-problem review-forwarder Step 1 parser no longer runs review logic inline (P071 slice 2)" {
|
|
63
|
+
# Slice 2's defining behaviour: Step 1's `review` branch must
|
|
64
|
+
# delegate, not run Step 9 inline. The parser line must say
|
|
65
|
+
# "delegate to /wr-itil:review-problems", matching the shape the
|
|
66
|
+
# list-forwarder uses in slice 1. A stale "run the review (step 9)"
|
|
67
|
+
# line would indicate the forwarder was added without updating the
|
|
68
|
+
# parser (common slip).
|
|
69
|
+
run grep -nE "^- If arguments contain \"review\", \*\*delegate to \`/wr-itil:review-problems\`\*\*" "$SKILL_FILE"
|
|
70
|
+
[ "$status" -eq 0 ]
|
|
71
|
+
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wr-itil:review-problems
|
|
3
|
+
description: Re-assess every open and known-error problem ticket in docs/problems/ — re-read RISK-POLICY.md, re-rate Impact × Likelihood, re-estimate Effort, recalculate WSJF, surface pending verifications, auto-transition Open → Known Error where warranted, and rewrite docs/problems/README.md with the refreshed ranking. Writes to problem files and the README cache; commits the refresh per ADR-014.
|
|
4
|
+
allowed-tools: Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion, Skill
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Review Problems
|
|
8
|
+
|
|
9
|
+
Re-assess the problem backlog. This skill is a **batch operation** that reads every `.open.md` and `.known-error.md` ticket in `docs/problems/`, re-scores each against the current `RISK-POLICY.md`, re-estimates Effort against the current fix-strategy documentation, recalculates WSJF, auto-transitions Open tickets to Known Error when root cause + workaround are documented, fires the Verification Queue prompt for `.verifying.md` tickets, and rewrites `docs/problems/README.md` so downstream fast-paths (`list-problems` cache-hit, `work-problem` fast-path) see a fresh ranked view.
|
|
10
|
+
|
|
11
|
+
This skill is the P071 phased-landing split of `/wr-itil:manage-problem review` per ADR-010 amended Skill Granularity rule: one skill per distinct user intent. The original `/wr-itil:manage-problem review` 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
|
+
**In scope:**
|
|
16
|
+
- `docs/problems/*.open.md` and `docs/problems/*.known-error.md` — re-scored (Impact × Likelihood × Effort → WSJF); Priority + Effort + WSJF lines updated when they change.
|
|
17
|
+
- `docs/problems/*.verifying.md` — surfaced in the Verification Queue and fed to Step 4's verification prompt (Known Error → Closed path when the user confirms).
|
|
18
|
+
- `docs/problems/*.parked.md` — listed in the Parked section; NOT re-scored (WSJF multiplier is 0).
|
|
19
|
+
- `docs/problems/README.md` — rewritten with the refreshed WSJF Rankings + Verification Queue + Parked tables; staged and committed with the review.
|
|
20
|
+
|
|
21
|
+
**Out of scope:**
|
|
22
|
+
- Work selection — the review produces the ranking, but does NOT pick the next ticket to work. That's `/wr-itil:work-problem` (slice 3 of P071, singular interactive variant; distinct from `/wr-itil:work-problems` plural AFK orchestrator).
|
|
23
|
+
- Ticket creation — use `/wr-itil:manage-problem`.
|
|
24
|
+
- Status transitions other than the Open → Known Error auto-transition and the Verification Pending → Closed prompt — use `/wr-itil:manage-problem <NNN>` (or the future `/wr-itil:transition-problem` split once it lands in a later slice).
|
|
25
|
+
- `docs/problems/*.closed.md` — omitted from the ranking entirely (the review addresses the active backlog).
|
|
26
|
+
|
|
27
|
+
## Steps
|
|
28
|
+
|
|
29
|
+
### 1. Read the risk framework
|
|
30
|
+
|
|
31
|
+
Read `RISK-POLICY.md` to get the current Impact levels (1-5), Likelihood levels (1-5), risk matrix, and label bands. These are the authoritative definitions — do not hardcode a scale.
|
|
32
|
+
|
|
33
|
+
### 2. Re-score every open / known-error ticket
|
|
34
|
+
|
|
35
|
+
For each `docs/problems/*.open.md` and `docs/problems/*.known-error.md` file (skip `.parked.md` and `.verifying.md` files entirely — their WSJF multiplier is 0 and they have dedicated sections in Step 3):
|
|
36
|
+
|
|
37
|
+
1. Read the problem file.
|
|
38
|
+
2. Read the codebase context — check if the root cause has been investigated since the last review, whether there are related fixes in git history, or whether the problem is stale.
|
|
39
|
+
3. **Re-assess Impact (1-5)** using the product-specific impact levels from `RISK-POLICY.md`. Ask: "If this problem occurs in production, what is the worst business consequence?"
|
|
40
|
+
4. **Re-assess Likelihood (1-5)** using the likelihood levels from `RISK-POLICY.md`. Ask: "Given the current codebase, how likely is this to affect the user?"
|
|
41
|
+
5. **Calculate Severity** = Impact × Likelihood.
|
|
42
|
+
6. **Look up Label** from the risk matrix label bands.
|
|
43
|
+
7. **Re-estimate Effort** (S / M / L / XL) by reading the Root Cause Analysis and Candidate Fix sections. Consider: how many files, how complex, does it need planning, is it cross-package or migration-heavy (XL territory)? If the bucket has changed since the last review, update the Effort line in the problem file and note the reason in a short parenthetical (e.g. "L → XL — architect review added ADR + migration script"). P047.
|
|
44
|
+
8. **Calculate WSJF** = (Severity × Status Multiplier) / Effort Divisor. Status Multiplier is 1.0 for Open, 2.0 for Known Error (per `/wr-itil:manage-problem`'s WSJF table — re-read if unsure).
|
|
45
|
+
9. **Update the Priority and WSJF lines** in the problem file if the scores changed.
|
|
46
|
+
10. **Auto-transition to Known Error** — if an open problem has confirmed root cause AND a workaround documented (even "feature disabled"), automatically transition it:
|
|
47
|
+
- `git mv docs/problems/<NNN>-<title>.open.md docs/problems/<NNN>-<title>.known-error.md`
|
|
48
|
+
- Update the Status field to "Known Error".
|
|
49
|
+
- Re-stage explicitly per the P057 staging trap: `git add <new-path>` after the Edit.
|
|
50
|
+
- This happens automatically — do not ask the user. The transition's fix-strategy is documented; only the shipping is outstanding.
|
|
51
|
+
|
|
52
|
+
### 3. Present the refreshed ranking
|
|
53
|
+
|
|
54
|
+
After re-scoring, present three sections matching the README.md format (same rendering used by `/wr-itil:list-problems` and by the README cache — Step 5 writes the same layout):
|
|
55
|
+
|
|
56
|
+
**WSJF Rankings** — dev-work queue (open + known-error), sorted by WSJF descending:
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
| WSJF | ID | Title | Severity | Status | Effort | Notes |
|
|
60
|
+
|------|-----|-------|----------|--------|--------|-------|
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**Verification Queue** — `.verifying.md` tickets, sorted by release age (oldest first). Highlight any ticket whose release age is **≥ 14 days** with a `yes (N days)` marker in the `Likely verified?` column (within-skill default per P048 Candidate 4 — tunable; promote to cross-skill policy if needed):
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
| ID | Title | Released | Fix summary | Likely verified? |
|
|
67
|
+
|----|-------|----------|-------------|------------------|
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**Parked** — `.parked.md` tickets (no ranking):
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
| ID | Title | Reason | Parked since |
|
|
74
|
+
|----|-------|--------|-------------|
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Highlight:
|
|
78
|
+
- Problems whose priority changed (↑ or ↓ since the last review).
|
|
79
|
+
- Problems that were auto-transitioned to known-error in Step 2.
|
|
80
|
+
- Problems that may be stale (reported > 2 weeks ago with no investigation progress).
|
|
81
|
+
- Problems that have been fixed but not closed (check git history for fix commits referencing the problem ID).
|
|
82
|
+
- Verification Pending tickets whose fix has been exercised repeatedly without regression (P048 detection layer — candidate for closure verification; surface these first in Step 4).
|
|
83
|
+
|
|
84
|
+
Omit an empty section rather than rendering an empty header.
|
|
85
|
+
|
|
86
|
+
### 4. Verification prompt (Verification Pending → Closed)
|
|
87
|
+
|
|
88
|
+
Target `docs/problems/*.verifying.md` via glob — do NOT scan `.known-error.md` bodies for a `## Fix Released` section (per ADR-022, Verification Pending is a first-class status, not a substring marker). For each `.verifying.md` file, use `AskUserQuestion` to ask whether the fix has been verified in production.
|
|
89
|
+
|
|
90
|
+
The question MUST include a fix summary extracted from the `## Fix Released` section — include the first sentence (or first bullet list) of that section in the question body or as the option description, so the user can answer without reading the full problem file. Do NOT ask with only the problem ID + title + version.
|
|
91
|
+
|
|
92
|
+
- Surface the Step 3 `yes (N days)` tickets first so the user can batch-close them.
|
|
93
|
+
- If the user confirms: close the problem (`git mv` from `.verifying.md` to `.closed.md`, update Status to "Closed", re-stage per the P057 staging trap).
|
|
94
|
+
- If the user says no or is unsure: leave the ticket as Verification Pending.
|
|
95
|
+
|
|
96
|
+
**AFK / non-interactive branch (ADR-013 Rule 6):** when `AskUserQuestion` is unavailable, record the Verification Queue in the review output and skip the prompt. Do NOT auto-close verifying tickets — only the user can make that call. The user sees the queue on next interactive invocation.
|
|
97
|
+
|
|
98
|
+
### 5. Rewrite `docs/problems/README.md`
|
|
99
|
+
|
|
100
|
+
Write / overwrite `docs/problems/README.md` with the refreshed ranking so future `work-problem` / `list-problems` fast-paths can skip the full re-scan. Rendering rules match the SKILL.md `Present the refreshed ranking` section above — driven off globs, not file-body scans:
|
|
101
|
+
|
|
102
|
+
```markdown
|
|
103
|
+
# Problem Backlog
|
|
104
|
+
|
|
105
|
+
> Last reviewed: <ISO timestamp> — <one-line context about what changed>
|
|
106
|
+
> Run `/wr-itil:review-problems` to refresh WSJF rankings.
|
|
107
|
+
|
|
108
|
+
## WSJF Rankings
|
|
109
|
+
|
|
110
|
+
Dev-work queue only. Verification Pending (`.verifying.md`, WSJF multiplier 0) and Parked (`.parked.md`, multiplier 0) tickets are excluded per ADR-022 — surfaced in their own sections below.
|
|
111
|
+
|
|
112
|
+
| WSJF | ID | Title | Severity | Status | Effort |
|
|
113
|
+
|------|-----|-------|----------|--------|--------|
|
|
114
|
+
| <score> | P<NNN> | <title> | <severity> | <status> | <effort> |
|
|
115
|
+
...
|
|
116
|
+
|
|
117
|
+
## Verification Queue
|
|
118
|
+
|
|
119
|
+
Fix released, awaiting user verification (driven off `docs/problems/*.verifying.md` via glob per ADR-022). Ranked by release age, oldest first. `Likely verified?` column marks tickets ≥14 days old (P048 Candidate 4 default).
|
|
120
|
+
|
|
121
|
+
| ID | Title | Released | Likely verified? |
|
|
122
|
+
|----|-------|----------|------------------|
|
|
123
|
+
| P<NNN> | <title> | <release marker> | <yes (N days) / no (N days)> |
|
|
124
|
+
...
|
|
125
|
+
|
|
126
|
+
## Parked
|
|
127
|
+
|
|
128
|
+
| ID | Title | Reason | Parked since |
|
|
129
|
+
|----|-------|--------|-------------|
|
|
130
|
+
| P<NNN> | <title> | <reason> | <date> |
|
|
131
|
+
...
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
The "Last reviewed" parenthetical should name any meaningful state change in this refresh (auto-transitions fired, priority flips, newly-stale tickets) so the next session's fast-path has a human-readable audit marker alongside the git-history staleness test.
|
|
135
|
+
|
|
136
|
+
### 6. Commit the refresh
|
|
137
|
+
|
|
138
|
+
Commit all changed files per ADR-014 (governance skills commit their own work):
|
|
139
|
+
|
|
140
|
+
1. `git add` the changed problem files AND `docs/problems/README.md` AND any files renamed via `git mv` in Step 2's auto-transition branch (per the P057 staging trap — `git mv` alone stages only the rename, not the subsequent content edit; re-stage explicitly after each Edit).
|
|
141
|
+
2. Satisfy the commit gate — two paths are valid (either produces a bypass marker):
|
|
142
|
+
- **Primary**: delegate to the `wr-risk-scorer:pipeline` subagent-type via the Agent tool.
|
|
143
|
+
- **Fallback**: if the `wr-risk-scorer:pipeline` subagent-type is not available in the current tool set (e.g., this skill is itself running inside a spawned subagent), invoke the `/wr-risk-scorer:assess-release` skill via the Skill tool. Per ADR-015 it wraps the same pipeline subagent and produces an equivalent bypass marker via the `PostToolUse:Agent` hook. Do not silently skip the gate because the primary path is unavailable — the fallback exists specifically to close this gap (see P035).
|
|
144
|
+
3. `git commit -m "docs(problems): review — re-rank priorities"`
|
|
145
|
+
|
|
146
|
+
If `AskUserQuestion` is unavailable AND risk is above appetite, skip the commit and report the uncommitted state clearly (ADR-013 Rule 6 fail-safe). This applies only to the risk-above-appetite branch, not to the delegation-unavailable case above.
|
|
147
|
+
|
|
148
|
+
### 7. Auto-release when changesets are queued (ADR-020)
|
|
149
|
+
|
|
150
|
+
Skip this step if the skill is running inside an AFK orchestrator (e.g. `/wr-itil:work-problems`) — orchestrators handle release cadence themselves per ADR-018 (Step 6.5). Detect via orchestrator markers in the invoking prompt ("AFK", "work-problems", "batch-work", `ALL_DONE`). When in doubt, defer to the orchestrator by skipping this step.
|
|
151
|
+
|
|
152
|
+
Otherwise, after the commit in Step 6 lands, drain the release queue per the mechanism documented in `/wr-itil:manage-problem` Step 12. Review commits typically score Very Low risk (doc-only), so the drain condition (push + release within appetite) is almost always satisfied.
|
|
153
|
+
|
|
154
|
+
## Ownership boundary
|
|
155
|
+
|
|
156
|
+
`review-problems` owns:
|
|
157
|
+
- Re-scoring the open / known-error backlog (writes Priority + Effort + WSJF lines on problem files).
|
|
158
|
+
- Auto-transitioning Open → Known Error when root cause + workaround are documented.
|
|
159
|
+
- Firing the Verification Queue prompt (Known Error → Closed via Verification Pending).
|
|
160
|
+
- Rewriting `docs/problems/README.md` — this is THE ownership point for the README cache. `list-problems` explicitly defers to this skill for the refresh.
|
|
161
|
+
|
|
162
|
+
`review-problems` does NOT:
|
|
163
|
+
- Pick the next ticket to work (that's `/wr-itil:work-problem`, singular).
|
|
164
|
+
- Create new tickets (that's `/wr-itil:manage-problem`).
|
|
165
|
+
- Transition tickets to Parked or implement fixes (those are dedicated transitions / fix commits — use `/wr-itil:manage-problem <NNN>` until `/wr-itil:transition-problem` lands).
|
|
166
|
+
|
|
167
|
+
## Related
|
|
168
|
+
|
|
169
|
+
- **P071** (`docs/problems/071-argument-based-skill-subcommands-are-not-discoverable.open.md`) — originating ticket. This skill is phase 2 of the P071 phased-landing plan (list-problems was phase 1; work-problem singular is phase 3).
|
|
170
|
+
- **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.
|
|
171
|
+
- **ADR-022** (`docs/decisions/022-verification-pending-status.proposed.md`) — Verification Pending status conventions; `.verifying.md` exclusion from WSJF ranking; Verification Queue rendering.
|
|
172
|
+
- **ADR-014** — governance skills commit their own work.
|
|
173
|
+
- **ADR-015** — governance skills delegate release scoring to the pipeline subagent / `assess-release` fallback.
|
|
174
|
+
- **ADR-037** (`docs/decisions/037-skill-testing-strategy.proposed.md`) — contract-assertion bats pattern applied to this skill.
|
|
175
|
+
- **P031** — git-history freshness check rationale (mtime unreliable in worktrees). Applies to the README cache this skill owns.
|
|
176
|
+
- **P047** — live-estimate effort buckets; the Step 2 re-estimate is the lifecycle transition this ticket closes.
|
|
177
|
+
- **P048** Candidate 4 — the 14-day `Likely verified?` heuristic in Step 3.
|
|
178
|
+
- **P057** — staging trap. Step 2's auto-transition MUST re-stage after Edit.
|
|
179
|
+
- **P062** — README.md refresh on transitions. Step 5 is the review-path of the same refresh; `/wr-itil:manage-problem` Step 7 carries the transition-path.
|
|
180
|
+
- **JTBD-001** (`docs/jtbd/solo-developer/JTBD-001-enforce-governance.proposed.md`) — discoverable surface via `/wr-itil:` autocomplete.
|
|
181
|
+
- **JTBD-101** (`docs/jtbd/plugin-developer/JTBD-101-extend-suite.proposed.md`) — one skill per distinct user intent.
|
|
182
|
+
- `packages/itil/skills/manage-problem/SKILL.md` — hosts the thin-router forwarder for the deprecated `manage-problem review` form.
|
|
183
|
+
- `packages/itil/skills/list-problems/SKILL.md` — sibling read-only display skill; defers the README refresh to this skill.
|
|
184
|
+
|
|
185
|
+
$ARGUMENTS
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
#!/usr/bin/env bats
|
|
2
|
+
# Contract assertions for /wr-itil:review-problems (P071 split slice 2).
|
|
3
|
+
#
|
|
4
|
+
# This skill hosts the "re-assess every open / known-error problem,
|
|
5
|
+
# auto-transition, fire the verification prompt, and rewrite the README
|
|
6
|
+
# cache" user intent previously hidden behind /wr-itil:manage-problem
|
|
7
|
+
# review. Unlike list-problems (slice 1, pure read-only) this skill
|
|
8
|
+
# owns the README cache write and the auto-transition path, so it
|
|
9
|
+
# requires the full governance tool surface (Write, Edit, Bash,
|
|
10
|
+
# AskUserQuestion, Skill for the commit-gate fallback).
|
|
11
|
+
#
|
|
12
|
+
# Structural assertion — Permitted Exception to the source-grep ban
|
|
13
|
+
# (ADR-005 / P011 / ADR-037 contract-assertion pattern).
|
|
14
|
+
#
|
|
15
|
+
# @problem P071
|
|
16
|
+
# @jtbd JTBD-001 (enforce governance without slowing down — discoverable surface)
|
|
17
|
+
# @jtbd JTBD-101 (extend the suite with clear patterns — one skill per distinct user intent)
|
|
18
|
+
#
|
|
19
|
+
# Cross-reference:
|
|
20
|
+
# P071: docs/problems/071-argument-based-skill-subcommands-are-not-discoverable.open.md
|
|
21
|
+
# ADR-010 amended (Skill Granularity section) — split naming + forwarder contract
|
|
22
|
+
# ADR-022 — Verification Pending status conventions (review-problems owns the queue prompt)
|
|
23
|
+
# ADR-014 — governance skills commit their own work
|
|
24
|
+
# ADR-015 — commit-gate delegation pattern
|
|
25
|
+
# ADR-037 — contract-assertion bats pattern
|
|
26
|
+
|
|
27
|
+
setup() {
|
|
28
|
+
SKILL_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
|
|
29
|
+
SKILL_FILE="${SKILL_DIR}/SKILL.md"
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@test "SKILL.md exists and has frontmatter" {
|
|
33
|
+
[ -f "$SKILL_FILE" ]
|
|
34
|
+
run head -1 "$SKILL_FILE"
|
|
35
|
+
[ "$status" -eq 0 ]
|
|
36
|
+
[ "$output" = "---" ]
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@test "SKILL.md frontmatter name is wr-itil:review-problems (P071 + ADR-010 amended)" {
|
|
40
|
+
# Split naming convention per ADR-010 amendment: <verb>-<object> pair.
|
|
41
|
+
# The new skill's name must match the phased-landing plan pinned in P071.
|
|
42
|
+
run grep -n "^name: wr-itil:review-problems$" "$SKILL_FILE"
|
|
43
|
+
[ "$status" -eq 0 ]
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@test "SKILL.md frontmatter description names the review intent (P071)" {
|
|
47
|
+
# Description must name "re-assess" or "review" + "problem" so
|
|
48
|
+
# Claude Code autocomplete surfaces the user intent rather than a
|
|
49
|
+
# generic name.
|
|
50
|
+
run grep -inE "^description:.*(re-assess|review).*problem|^description:.*problem.*(re-assess|review)" "$SKILL_FILE"
|
|
51
|
+
[ "$status" -eq 0 ]
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@test "SKILL.md frontmatter allowed-tools includes Write + Edit (owns README refresh)" {
|
|
55
|
+
# Review owns the README cache write and auto-transition Edits.
|
|
56
|
+
# Unlike list-problems (pure read-only), this skill MUST carry Write
|
|
57
|
+
# and Edit so the commit gate contract from ADR-014 holds.
|
|
58
|
+
run grep -nE "^allowed-tools:.*Write" "$SKILL_FILE"
|
|
59
|
+
[ "$status" -eq 0 ]
|
|
60
|
+
run grep -nE "^allowed-tools:.*Edit" "$SKILL_FILE"
|
|
61
|
+
[ "$status" -eq 0 ]
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@test "SKILL.md frontmatter allowed-tools includes Skill (commit-gate fallback)" {
|
|
65
|
+
# Step 6 commit-gate fallback invokes /wr-risk-scorer:assess-release
|
|
66
|
+
# when the pipeline subagent is unavailable. That fallback requires
|
|
67
|
+
# the Skill tool per ADR-015.
|
|
68
|
+
run grep -nE "^allowed-tools:.*Skill" "$SKILL_FILE"
|
|
69
|
+
[ "$status" -eq 0 ]
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
@test "SKILL.md frontmatter allowed-tools includes AskUserQuestion (Verification prompt)" {
|
|
73
|
+
# Step 4 fires AskUserQuestion for every .verifying.md ticket per
|
|
74
|
+
# ADR-022. The AFK branch degrades gracefully (ADR-013 Rule 6) but
|
|
75
|
+
# the primary path requires the tool.
|
|
76
|
+
run grep -nE "^allowed-tools:.*AskUserQuestion" "$SKILL_FILE"
|
|
77
|
+
[ "$status" -eq 0 ]
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
@test "SKILL.md documents the re-scoring scan scope (P071)" {
|
|
81
|
+
# The skill reads .open.md and .known-error.md files and writes back
|
|
82
|
+
# Priority + Effort + WSJF. .verifying.md and .parked.md are NOT
|
|
83
|
+
# re-scored (multiplier 0) but are shown in dedicated sections.
|
|
84
|
+
# The SKILL.md must name all four glob patterns so the contract is legible.
|
|
85
|
+
run grep -inE "\.open\.md" "$SKILL_FILE"
|
|
86
|
+
[ "$status" -eq 0 ]
|
|
87
|
+
run grep -inE "\.known-error\.md" "$SKILL_FILE"
|
|
88
|
+
[ "$status" -eq 0 ]
|
|
89
|
+
run grep -inE "\.verifying\.md" "$SKILL_FILE"
|
|
90
|
+
[ "$status" -eq 0 ]
|
|
91
|
+
run grep -inE "\.parked\.md" "$SKILL_FILE"
|
|
92
|
+
[ "$status" -eq 0 ]
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
@test "SKILL.md owns the README.md refresh write (P062 + ownership boundary)" {
|
|
96
|
+
# Review is the canonical writer of docs/problems/README.md. The
|
|
97
|
+
# sibling list-problems skill explicitly defers here. If this
|
|
98
|
+
# contract drifts (e.g. list-problems starts writing the README or
|
|
99
|
+
# review stops writing it), the fast-path cache goes stale.
|
|
100
|
+
run grep -inE "docs/problems/README\.md" "$SKILL_FILE"
|
|
101
|
+
[ "$status" -eq 0 ]
|
|
102
|
+
run grep -inE "(rewrite|write[ /]+overwrite|refresh|rewrites).*README\.md|README\.md.*(rewrite|refresh|overwrite|write)" "$SKILL_FILE"
|
|
103
|
+
[ "$status" -eq 0 ]
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
@test "SKILL.md fires the Verification Queue prompt per ADR-022 (Step 4)" {
|
|
107
|
+
# Step 4 is the structured path that transitions Verification Pending
|
|
108
|
+
# → Closed. Without it, verifyings accumulate forever. The prompt
|
|
109
|
+
# MUST include a fix summary per ADR-022 (not just ID + title +
|
|
110
|
+
# version).
|
|
111
|
+
run grep -inE "Verification (Queue|Pending)|verifying\.md" "$SKILL_FILE"
|
|
112
|
+
[ "$status" -eq 0 ]
|
|
113
|
+
run grep -inE "Fix Released|fix summary" "$SKILL_FILE"
|
|
114
|
+
[ "$status" -eq 0 ]
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
@test "SKILL.md declares the auto-transition path (Open → Known Error)" {
|
|
118
|
+
# Step 2.10 auto-transitions Open tickets with documented root cause
|
|
119
|
+
# + workaround to Known Error. This is a defining behaviour of the
|
|
120
|
+
# review skill; drift here means the backlog lingers in Open forever.
|
|
121
|
+
run grep -inE "Auto-transition|auto.transition|Open.+Known Error|known-error" "$SKILL_FILE"
|
|
122
|
+
[ "$status" -eq 0 ]
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
@test "SKILL.md satisfies the commit gate per ADR-014 + ADR-015" {
|
|
126
|
+
# Review is a governance skill per ADR-014: it commits its own work
|
|
127
|
+
# after satisfying the commit gate. Per ADR-015 the gate has two
|
|
128
|
+
# paths (primary subagent delegation + fallback assess-release
|
|
129
|
+
# skill). Both MUST be documented so P035 stays closed.
|
|
130
|
+
run grep -inE "wr-risk-scorer:pipeline|wr-risk-scorer:assess-release" "$SKILL_FILE"
|
|
131
|
+
[ "$status" -eq 0 ]
|
|
132
|
+
run grep -inE "ADR-014|ADR-015" "$SKILL_FILE"
|
|
133
|
+
[ "$status" -eq 0 ]
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
@test "SKILL.md cites the P057 staging trap on auto-transitions" {
|
|
137
|
+
# Any git mv + Edit combo in this skill (Step 2.10 auto-transition,
|
|
138
|
+
# Step 4 verification close) MUST re-stage explicitly. P057
|
|
139
|
+
# codifies this; drift here means content edits leak into later
|
|
140
|
+
# commits.
|
|
141
|
+
run grep -inE "staging trap|P057|re-stage" "$SKILL_FILE"
|
|
142
|
+
[ "$status" -eq 0 ]
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
@test "SKILL.md reuses the RISK-POLICY.md risk framework (no hardcoded scale)" {
|
|
146
|
+
# Step 1 reads RISK-POLICY.md for the current Impact/Likelihood
|
|
147
|
+
# scales and label bands. Hardcoding a scale causes drift when the
|
|
148
|
+
# policy is amended (ISO 31000 alignment axis).
|
|
149
|
+
run grep -inE "RISK-POLICY\.md" "$SKILL_FILE"
|
|
150
|
+
[ "$status" -eq 0 ]
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
@test "SKILL.md cites P071 and ADR-010 amended (P071 + ADR-025)" {
|
|
154
|
+
# ADR-025 inheritance per ADR-037: contract-assertion bats should
|
|
155
|
+
# reflect traceability cites on the skill spec document.
|
|
156
|
+
run grep -inE "P071|ADR-010" "$SKILL_FILE"
|
|
157
|
+
[ "$status" -eq 0 ]
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
@test "SKILL.md does not carry a deprecated-arguments frontmatter flag (clean-split skill)" {
|
|
161
|
+
# Architect advisory: review-problems is a clean-split skill with no
|
|
162
|
+
# argument-subcommands itself. ADR-010 amendment's
|
|
163
|
+
# `deprecated-arguments: true` flag is only valid on host skills with
|
|
164
|
+
# forwarder routes — review-problems is the forwarder TARGET, not the
|
|
165
|
+
# host.
|
|
166
|
+
run grep -E "^deprecated-arguments:" "$SKILL_FILE"
|
|
167
|
+
[ "$status" -ne 0 ]
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
@test "SKILL.md does not use word-argument subcommand branching (P071 regression guard)" {
|
|
171
|
+
# The whole point of P071: Claude Code autocomplete does not surface
|
|
172
|
+
# arguments. A clean-split skill must not reintroduce word-arg
|
|
173
|
+
# subcommand routing. The SKILL.md must not contain `If arguments
|
|
174
|
+
# start with "list"` / `If arguments contain "work"` / etc. patterns.
|
|
175
|
+
run grep -inE "If arguments start with|If arguments contain" "$SKILL_FILE"
|
|
176
|
+
[ "$status" -ne 0 ]
|
|
177
|
+
}
|