@windyroad/itil 0.14.0-preview.154 → 0.15.0-preview.157
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/close-incident/SKILL.md +181 -0
- package/skills/close-incident/test/close-incident-contract.bats +146 -0
- package/skills/link-incident/SKILL.md +160 -0
- package/skills/link-incident/test/link-incident-contract.bats +125 -0
- package/skills/list-incidents/SKILL.md +81 -0
- package/skills/list-incidents/test/list-incidents-contract.bats +115 -0
- package/skills/manage-incident/SKILL.md +63 -60
- package/skills/manage-incident/test/manage-incident-close-forwarder.bats +67 -0
- package/skills/manage-incident/test/manage-incident-link-forwarder.bats +67 -0
- package/skills/manage-incident/test/manage-incident-list-forwarder.bats +68 -0
- package/skills/manage-incident/test/manage-incident-mitigate-forwarder.bats +66 -0
- package/skills/manage-incident/test/manage-incident-restore-forwarder.bats +66 -0
- package/skills/mitigate-incident/SKILL.md +211 -0
- package/skills/mitigate-incident/test/mitigate-incident-contract.bats +152 -0
- package/skills/restore-incident/SKILL.md +195 -0
- package/skills/restore-incident/test/restore-incident-contract.bats +142 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wr-itil:list-incidents
|
|
3
|
+
description: List active incidents from docs/incidents/ sorted by severity. Read-only display of the incident backlog — no edits, no interaction. Shown as a markdown table with ID, title, severity, and status columns.
|
|
4
|
+
allowed-tools: Read, Bash, Grep, Glob
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# List Incidents
|
|
8
|
+
|
|
9
|
+
Display the active incident backlog — investigating, mitigating, and restored incidents — sorted by severity (highest first). This skill is a pure read-only view of `docs/incidents/`; it does not edit, transition, close, or create incidents. For those operations, use the dedicated skills (`/wr-itil:manage-incident` to declare / update / mitigate / restore / close / link).
|
|
10
|
+
|
|
11
|
+
This skill is the P071 phased-landing split of `/wr-itil:manage-incident list` per ADR-010 amended Skill Granularity rule: one skill per distinct user intent. The original `/wr-itil:manage-incident 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/incidents/*.investigating.md` — symptoms reported, scope being established
|
|
17
|
+
- `docs/incidents/*.mitigating.md` — mitigation(s) in flight
|
|
18
|
+
- `docs/incidents/*.restored.md` — service verified restored, awaiting close gate
|
|
19
|
+
|
|
20
|
+
`docs/incidents/*.closed.md` is omitted entirely (the view is of active incidents, not the closed archive). Closed incidents remain readable by filename convention; this skill does not index them.
|
|
21
|
+
|
|
22
|
+
**Severity, not WSJF** — per ADR-011: incidents are time-bound events where the WSJF "effort" divisor is meaningless during a live event. Severity uses Impact × Likelihood from `RISK-POLICY.md`, interpreted as "right now, what's the live business impact?". The skill surfaces the severity score from each incident file's frontmatter directly — no re-scoring, no auto-transitioning.
|
|
23
|
+
|
|
24
|
+
## Steps
|
|
25
|
+
|
|
26
|
+
### 1. Live scan
|
|
27
|
+
|
|
28
|
+
Enumerate the active incident files via glob:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
ls docs/incidents/*.investigating.md docs/incidents/*.mitigating.md docs/incidents/*.restored.md 2>/dev/null
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
If the `docs/incidents/` directory does not exist or no active incidents are present, report "No active incidents." and exit.
|
|
35
|
+
|
|
36
|
+
For each matched file, read the `**Status**`, `**Severity**`, and the first-line `# Incident <I###>: <Title>` header. The severity line shape is:
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
**Severity**: <score> (<label>) — Impact: <label> (<n>) x Likelihood: <label> (<n>)
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Extract the numeric `<score>` for sorting. If severity is missing, treat the incident as severity 0 and flag it so the user knows the incident file is incomplete.
|
|
43
|
+
|
|
44
|
+
### 2. Display
|
|
45
|
+
|
|
46
|
+
Render one section:
|
|
47
|
+
|
|
48
|
+
**Active Incidents** — sorted by severity descending:
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
| Severity | ID | Title | Status |
|
|
52
|
+
|----------|------|-------|--------|
|
|
53
|
+
| <score> | I<NNN> | <title> | <status> |
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
If the section is empty (no active incidents), omit the table and print "No active incidents." instead.
|
|
57
|
+
|
|
58
|
+
### 3. Trailing suggestions
|
|
59
|
+
|
|
60
|
+
After the table, print one short pointer depending on what the output showed:
|
|
61
|
+
|
|
62
|
+
- When the table is non-empty: `Run /wr-itil:manage-incident <I###> to update a specific incident, or /wr-itil:manage-incident <I###> mitigate / restored / close to advance its lifecycle.`
|
|
63
|
+
- When the table is empty: (no pointer needed).
|
|
64
|
+
|
|
65
|
+
## Ownership boundary
|
|
66
|
+
|
|
67
|
+
`list-incidents` is read-only — it does not modify, rename, or commit any files. There is no README cache for incidents (unlike `docs/problems/README.md` which the `review-problems` skill maintains). Every invocation runs a live scan. If the output seems wrong, check the incident file frontmatter directly; there is no cache to refresh.
|
|
68
|
+
|
|
69
|
+
## Related
|
|
70
|
+
|
|
71
|
+
- **P071** (`docs/problems/071-argument-based-skill-subcommands-are-not-discoverable.open.md`) — originating ticket. This skill is slice 5 of the P071 phased-landing plan.
|
|
72
|
+
- **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.
|
|
73
|
+
- **ADR-011** (`docs/decisions/011-manage-incident-skill-wrapping.proposed.md`) — incident lifecycle file-suffix conventions (`.investigating.md` / `.mitigating.md` / `.restored.md` / `.closed.md`) + "Severity, not WSJF" rule.
|
|
74
|
+
- **ADR-037** (`docs/decisions/037-skill-testing-strategy.proposed.md`) — contract-assertion bats pattern applied to this skill.
|
|
75
|
+
- **JTBD-001** (`docs/jtbd/solo-developer/JTBD-001-enforce-governance.proposed.md`) — discoverable surface via `/wr-itil:` autocomplete.
|
|
76
|
+
- **JTBD-101** (`docs/jtbd/plugin-developer/JTBD-101-extend-suite.proposed.md`) — one skill per distinct user intent.
|
|
77
|
+
- **JTBD-201** (`docs/jtbd/tech-lead/JTBD-201-restore-service-fast.proposed.md`) — incident status visibility for audit trail.
|
|
78
|
+
- `packages/itil/skills/manage-incident/SKILL.md` — hosts the thin-router forwarder for the deprecated `manage-incident list` form.
|
|
79
|
+
- `packages/itil/skills/list-problems/SKILL.md` — slice 1 precedent; this skill mirrors its read-only display shape.
|
|
80
|
+
|
|
81
|
+
$ARGUMENTS
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
#!/usr/bin/env bats
|
|
2
|
+
# Contract assertions for /wr-itil:list-incidents (P071 split slice 5).
|
|
3
|
+
#
|
|
4
|
+
# This skill hosts the "list active incidents" user intent previously
|
|
5
|
+
# hidden behind /wr-itil:manage-incident list. It is a pure read-only
|
|
6
|
+
# 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
|
+
# @jtbd JTBD-201 (restore service fast with an audit trail — incident status visibility)
|
|
15
|
+
#
|
|
16
|
+
# Cross-reference:
|
|
17
|
+
# P071: docs/problems/071-argument-based-skill-subcommands-are-not-discoverable.open.md
|
|
18
|
+
# ADR-010 amended (Skill Granularity section) — split naming + forwarder contract
|
|
19
|
+
# ADR-011 — manage-incident skill-wrapping precedent (list-incidents mirrors its file conventions)
|
|
20
|
+
# ADR-037 — contract-assertion bats pattern
|
|
21
|
+
|
|
22
|
+
setup() {
|
|
23
|
+
SKILL_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
|
|
24
|
+
SKILL_FILE="${SKILL_DIR}/SKILL.md"
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@test "SKILL.md exists and has frontmatter" {
|
|
28
|
+
[ -f "$SKILL_FILE" ]
|
|
29
|
+
run head -1 "$SKILL_FILE"
|
|
30
|
+
[ "$status" -eq 0 ]
|
|
31
|
+
[ "$output" = "---" ]
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@test "SKILL.md frontmatter name is wr-itil:list-incidents (P071 + ADR-010 amended)" {
|
|
35
|
+
# Split naming convention per ADR-010 amendment: <verb>-<object> pair.
|
|
36
|
+
# The new skill's name must match the phased-landing plan pinned in P071.
|
|
37
|
+
run grep -n "^name: wr-itil:list-incidents$" "$SKILL_FILE"
|
|
38
|
+
[ "$status" -eq 0 ]
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@test "SKILL.md frontmatter description names the list intent (P071)" {
|
|
42
|
+
# Description must name "list" and "incident" so Claude Code autocomplete
|
|
43
|
+
# surfaces the user intent rather than a generic name.
|
|
44
|
+
run grep -inE "^description:.*list.*incident|^description:.*incident.*list" "$SKILL_FILE"
|
|
45
|
+
[ "$status" -eq 0 ]
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
@test "SKILL.md frontmatter allowed-tools is read-only (P071 — read-only list display)" {
|
|
49
|
+
# Pure read-only list display (mirrors list-problems slice 1). No Write,
|
|
50
|
+
# no Edit, no AskUserQuestion. This assertion is the enforceable contract —
|
|
51
|
+
# future maintainers cannot accidentally grow the tool surface past the
|
|
52
|
+
# intent.
|
|
53
|
+
run grep -nE "^allowed-tools:" "$SKILL_FILE"
|
|
54
|
+
[ "$status" -eq 0 ]
|
|
55
|
+
run grep -E "^allowed-tools:.*(Write|Edit|AskUserQuestion)" "$SKILL_FILE"
|
|
56
|
+
[ "$status" -ne 0 ]
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
@test "SKILL.md documents the read-only scan scope (P071 + ADR-011)" {
|
|
60
|
+
# The skill reads the three active incident statuses per ADR-011:
|
|
61
|
+
# .investigating.md, .mitigating.md, and .restored.md. Closed incidents
|
|
62
|
+
# are omitted (the view is active backlog, not archive). The SKILL.md
|
|
63
|
+
# must name all three glob patterns explicitly so the contract is
|
|
64
|
+
# legible.
|
|
65
|
+
run grep -inE "\.investigating\.md" "$SKILL_FILE"
|
|
66
|
+
[ "$status" -eq 0 ]
|
|
67
|
+
run grep -inE "\.mitigating\.md" "$SKILL_FILE"
|
|
68
|
+
[ "$status" -eq 0 ]
|
|
69
|
+
run grep -inE "\.restored\.md" "$SKILL_FILE"
|
|
70
|
+
[ "$status" -eq 0 ]
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@test "SKILL.md documents severity-sorted output (P071 + ADR-011)" {
|
|
74
|
+
# Unlike list-problems (WSJF-sorted), list-incidents is severity-sorted
|
|
75
|
+
# per ADR-011 "Severity, not WSJF" — incidents are time-bound events
|
|
76
|
+
# where effort divisor is meaningless. The SKILL.md must name severity
|
|
77
|
+
# as the sort key.
|
|
78
|
+
run grep -inE "severity" "$SKILL_FILE"
|
|
79
|
+
[ "$status" -eq 0 ]
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
@test "SKILL.md cites P071 and ADR-010 amended (P071 + ADR-025)" {
|
|
83
|
+
# ADR-025 inheritance per ADR-037: contract-assertion bats should reflect
|
|
84
|
+
# traceability cites on the skill spec document.
|
|
85
|
+
run grep -inE "P071|ADR-010" "$SKILL_FILE"
|
|
86
|
+
[ "$status" -eq 0 ]
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
@test "SKILL.md does not carry a deprecated-arguments frontmatter flag (clean-split skill)" {
|
|
90
|
+
# list-incidents is a clean-split skill with no argument-subcommands
|
|
91
|
+
# itself. ADR-010 amendment's `deprecated-arguments: true` flag is only
|
|
92
|
+
# valid on host skills with forwarder routes — list-incidents is the
|
|
93
|
+
# forwarder TARGET, not the host. It must NOT carry the flag.
|
|
94
|
+
run grep -E "^deprecated-arguments:" "$SKILL_FILE"
|
|
95
|
+
[ "$status" -ne 0 ]
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
@test "SKILL.md does not use word-argument subcommand branching (P071 regression guard)" {
|
|
99
|
+
# The whole point of P071: Claude Code autocomplete does not surface
|
|
100
|
+
# arguments. A clean-split skill must not reintroduce word-arg subcommand
|
|
101
|
+
# routing. The SKILL.md must not contain `If arguments start with "list"`
|
|
102
|
+
# / `If arguments contain "mitigate"` / etc. patterns.
|
|
103
|
+
run grep -inE "If arguments start with|If arguments contain" "$SKILL_FILE"
|
|
104
|
+
[ "$status" -ne 0 ]
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
@test "SKILL.md documents the ownership boundary — no README rewrite (P071)" {
|
|
108
|
+
# list-incidents displays active incidents but does NOT maintain a README
|
|
109
|
+
# cache (unlike list-problems which reads a README written by review-problems).
|
|
110
|
+
# For incidents, there is no README cache — the skill always runs a live
|
|
111
|
+
# scan. The SKILL.md must explicitly name the "read-only / no-edit" stance
|
|
112
|
+
# so the ownership boundary is legible to future maintainers.
|
|
113
|
+
run grep -inE "read-only|does not (edit|modify|rewrite|commit)" "$SKILL_FILE"
|
|
114
|
+
[ "$status" -eq 0 ]
|
|
115
|
+
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
name: wr-itil:manage-incident
|
|
3
3
|
description: Declare, triage, mitigate, and close an incident using an evidence-first workflow. Restores service first, then hands off to manage-problem for root-cause work.
|
|
4
4
|
allowed-tools: Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion, Skill
|
|
5
|
+
deprecated-arguments: true
|
|
5
6
|
---
|
|
6
7
|
|
|
7
8
|
# Incident Management Skill
|
|
@@ -71,10 +72,58 @@ Severity uses the Impact × Likelihood matrix from `RISK-POLICY.md`, interpreted
|
|
|
71
72
|
|
|
72
73
|
Determine the operation from `$ARGUMENTS`:
|
|
73
74
|
|
|
74
|
-
- If arguments start with "list" →
|
|
75
|
-
- If arguments
|
|
75
|
+
- If arguments start with "list" → **delegate to `/wr-itil:list-incidents`** via the Skill tool. See "Deprecated-argument forwarders" below.
|
|
76
|
+
- If arguments match `<I###> mitigate <action>` → **delegate to `/wr-itil:mitigate-incident <I###> <action>`** via the Skill tool. See "Deprecated-argument forwarders" below.
|
|
77
|
+
- If arguments match `<I###> restored` → **delegate to `/wr-itil:restore-incident <I###>`** via the Skill tool. See "Deprecated-argument forwarders" below.
|
|
78
|
+
- If arguments match `<I###> close` → **delegate to `/wr-itil:close-incident <I###>`** via the Skill tool. See "Deprecated-argument forwarders" below.
|
|
79
|
+
- If arguments match `<I###> link P<MMM>` → **delegate to `/wr-itil:link-incident <I###> P<MMM>`** via the Skill tool. See "Deprecated-argument forwarders" below.
|
|
80
|
+
- If arguments start with `I<NNN>` or a bare number → this is an update
|
|
76
81
|
- Otherwise → declare a new incident
|
|
77
82
|
|
|
83
|
+
#### Deprecated-argument forwarders (ADR-010 amended + P071)
|
|
84
|
+
|
|
85
|
+
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.
|
|
86
|
+
|
|
87
|
+
**Forwarder for `list`** (P071 split slice 5 — new skill `/wr-itil:list-incidents`):
|
|
88
|
+
|
|
89
|
+
When `$ARGUMENTS` contains the word `list` as a top-level argument (not inside an incident body edit), delegate to `/wr-itil:list-incidents` via the Skill tool and emit this systemMessage verbatim:
|
|
90
|
+
|
|
91
|
+
> `/wr-itil:manage-incident list is deprecated; use /wr-itil:list-incidents directly. This forwarder will be removed in @windyroad/itil's next major version.`
|
|
92
|
+
|
|
93
|
+
The forwarder does NOT re-implement the list logic locally — it invokes the Skill tool with `wr-itil:list-incidents` and returns the new skill's output verbatim. Duplicating the scan logic would harden the deprecation window into a permanent fork.
|
|
94
|
+
|
|
95
|
+
**Forwarder for `<I###> mitigate <action>`** (P071 split slice 6a — new skill `/wr-itil:mitigate-incident`):
|
|
96
|
+
|
|
97
|
+
When `$ARGUMENTS` matches the shape `<I###> mitigate <action>` (an incident ID followed by the literal word `mitigate` followed by a free-text action), delegate to `/wr-itil:mitigate-incident <I###> <action>` via the Skill tool and emit this systemMessage verbatim:
|
|
98
|
+
|
|
99
|
+
> `/wr-itil:manage-incident <I###> mitigate <action> is deprecated; use /wr-itil:mitigate-incident <I###> <action> directly. This forwarder will be removed in @windyroad/itil's next major version.`
|
|
100
|
+
|
|
101
|
+
The forwarder does NOT re-implement the mitigation logic locally — it invokes the Skill tool with `wr-itil:mitigate-incident`, passes `<I###> <action>` through as the data parameters, and returns the new skill's output verbatim. Duplicating the rename + evidence-gate + timeline-append logic would harden the deprecation window into a permanent fork. The data-parameter shape `<I###> <action>` is permitted under ADR-010 amended — only the verb word `mitigate` is being split out.
|
|
102
|
+
|
|
103
|
+
**Forwarder for `<I###> restored`** (P071 split slice 6b — new skill `/wr-itil:restore-incident`):
|
|
104
|
+
|
|
105
|
+
When `$ARGUMENTS` matches the shape `<I###> restored` (an incident ID followed by the literal word `restored`), delegate to `/wr-itil:restore-incident <I###>` via the Skill tool and emit this systemMessage verbatim:
|
|
106
|
+
|
|
107
|
+
> `/wr-itil:manage-incident <I###> restored is deprecated; use /wr-itil:restore-incident <I###> directly. This forwarder will be removed in @windyroad/itil's next major version.`
|
|
108
|
+
|
|
109
|
+
The forwarder does NOT re-implement the restore logic locally — it invokes the Skill tool with `wr-itil:restore-incident`, passes `<I###>` through as the data parameter, and returns the new skill's output verbatim. Duplicating the rename + verification-signal prompt + manage-problem handoff logic would harden the deprecation window into a permanent fork.
|
|
110
|
+
|
|
111
|
+
**Forwarder for `<I###> close`** (P071 split slice 6c — new skill `/wr-itil:close-incident`):
|
|
112
|
+
|
|
113
|
+
When `$ARGUMENTS` matches the shape `<I###> close` (an incident ID followed by the literal word `close`), delegate to `/wr-itil:close-incident <I###>` via the Skill tool and emit this systemMessage verbatim:
|
|
114
|
+
|
|
115
|
+
> `/wr-itil:manage-incident <I###> close is deprecated; use /wr-itil:close-incident <I###> directly. This forwarder will be removed in @windyroad/itil's next major version.`
|
|
116
|
+
|
|
117
|
+
The forwarder does NOT re-implement the close logic locally — it invokes the Skill tool with `wr-itil:close-incident`, passes `<I###>` through as the data parameter, and returns the new skill's output verbatim. Duplicating the linked-problem gate + rename logic would harden the deprecation window into a permanent fork.
|
|
118
|
+
|
|
119
|
+
**Forwarder for `<I###> link P<MMM>`** (P071 split slice 6d — new skill `/wr-itil:link-incident`):
|
|
120
|
+
|
|
121
|
+
When `$ARGUMENTS` matches the shape `<I###> link P<MMM>` (an incident ID followed by the literal word `link` followed by a problem ID), delegate to `/wr-itil:link-incident <I###> P<MMM>` via the Skill tool and emit this systemMessage verbatim:
|
|
122
|
+
|
|
123
|
+
> `/wr-itil:manage-incident <I###> link P<MMM> is deprecated; use /wr-itil:link-incident <I###> P<MMM> directly. This forwarder will be removed in @windyroad/itil's next major version.`
|
|
124
|
+
|
|
125
|
+
The forwarder does NOT re-implement the link logic locally — it invokes the Skill tool with `wr-itil:link-incident`, passes `<I###> P<MMM>` through as the data parameters, and returns the new skill's output verbatim. Duplicating the problem-file-lookup + Linked Problem section write logic would harden the deprecation window into a permanent fork. The data-parameter shape `<I###> P<MMM>` is permitted under ADR-010 amended — only the verb word `link` is being split out.
|
|
126
|
+
|
|
78
127
|
### 2. For new incidents: Check for duplicates FIRST
|
|
79
128
|
|
|
80
129
|
Before creating, search `docs/incidents/` for active (non-closed) incidents with overlapping symptoms or scope. The user may already have an incident open for this outage.
|
|
@@ -158,79 +207,33 @@ ls docs/incidents/<I###>-*.md 2>/dev/null
|
|
|
158
207
|
|
|
159
208
|
Append new observations, hypotheses, or timeline entries. **Every hypothesis must cite evidence.** If the user proposes a hypothesis without evidence, ask via `AskUserQuestion` what evidence supports it before writing.
|
|
160
209
|
|
|
161
|
-
### 7. For mitigate:
|
|
162
|
-
|
|
163
|
-
When the first mitigation attempt is made:
|
|
164
|
-
|
|
165
|
-
1. `git mv docs/incidents/<I###>-<title>.investigating.md docs/incidents/<I###>-<title>.mitigating.md`
|
|
166
|
-
2. Update the **Status** field to "Mitigating"
|
|
167
|
-
3. Append to **Mitigation attempts**: `[<timestamp> UTC] <action> → <outcome>` (outcome may be "pending verification" initially; update once the verification signal is known)
|
|
210
|
+
### 7. For mitigate: delegate to `/wr-itil:mitigate-incident` (P071 split slice 6a)
|
|
168
211
|
|
|
169
|
-
|
|
212
|
+
The `mitigate` subcommand is now hosted by the `/wr-itil:mitigate-incident` skill. This step exists as a thin-router forwarder — the Step 1 parser recognises the `<I###> mitigate <action>` shape and delegates via the Skill tool. This body is intentionally empty of implementation logic; the canonical documentation of the rename, Status update, evidence-gate pre-flight, and Mitigation attempts append lives in `/wr-itil:mitigate-incident`.
|
|
170
213
|
|
|
171
|
-
|
|
214
|
+
Do not re-implement the rename or the evidence gate here — delegate. See "Deprecated-argument forwarders" under Step 1 for the canonical systemMessage.
|
|
172
215
|
|
|
173
|
-
|
|
216
|
+
### 8. For restore: delegate to `/wr-itil:restore-incident` (P071 split slice 6b)
|
|
174
217
|
|
|
175
|
-
-
|
|
176
|
-
- [ ] A verification signal is captured (e.g., "error rate back to baseline per Datadog", "user reports normal", "synthetic probe passing")
|
|
218
|
+
The `restored` subcommand is now hosted by the `/wr-itil:restore-incident` skill. This step exists as a thin-router forwarder — the Step 1 parser recognises the `<I###> restored` shape and delegates via the Skill tool. This body is intentionally empty of implementation logic; the canonical documentation of the pre-flight checks, rename, Status update, Timeline append, and manage-problem handoff lives in `/wr-itil:restore-incident`.
|
|
177
219
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
1. `git mv docs/incidents/<I###>-<title>.mitigating.md docs/incidents/<I###>-<title>.restored.md`
|
|
181
|
-
2. Update the **Status** field to "Restored"
|
|
182
|
-
3. Append to **Timeline**: `[<timestamp> UTC] Service restored — <verification signal>`
|
|
183
|
-
|
|
184
|
-
Then perform the **handoff to problem management**:
|
|
185
|
-
|
|
186
|
-
1. Ask via `AskUserQuestion`: "Service restored. Should I create or update a problem record for the root cause? (a) yes — recommended, (b) no — document why (trivial/one-off)"
|
|
187
|
-
2. If yes, construct a handoff payload:
|
|
188
|
-
- Incident ID and title
|
|
189
|
-
- Timeline summary
|
|
190
|
-
- Top-ranked hypothesis + cited evidence
|
|
191
|
-
- Mitigation applied + verification signal
|
|
192
|
-
3. Invoke `wr-itil:manage-problem` via the `Skill` tool with the payload as arguments. The problem skill's existing dedupe flow handles new-vs-update.
|
|
193
|
-
4. Capture the returned `P<NNN>` and write a **Linked Problem** section into the incident file:
|
|
194
|
-
```markdown
|
|
195
|
-
## Linked Problem
|
|
196
|
-
P<NNN> (<title>) — <status>
|
|
197
|
-
```
|
|
198
|
-
5. If the user chose "no", write a **No Problem** section with the justification and skip the handoff:
|
|
199
|
-
```markdown
|
|
200
|
-
## No Problem
|
|
201
|
-
<reason — e.g. "one-off cosmic-bit-flip; not reproducible">
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
### 9. For close: Gate on linked problem status
|
|
205
|
-
|
|
206
|
-
The close operation checks the linked problem's file suffix:
|
|
207
|
-
|
|
208
|
-
```bash
|
|
209
|
-
linked_id=<extracted from Linked Problem section>
|
|
210
|
-
linked_file=$(ls docs/problems/${linked_id}-*.md 2>/dev/null | head -1)
|
|
211
|
-
```
|
|
220
|
+
Do not re-implement the rename or the problem handoff here — delegate. See "Deprecated-argument forwarders" under Step 1 for the canonical systemMessage.
|
|
212
221
|
|
|
213
|
-
|
|
214
|
-
- If `linked_file` ends with `.open.md` → close is blocked; report "Linked problem ${linked_id} is still Open. Transition it to Known Error first, or update the Linked Problem reference."
|
|
215
|
-
- If no linked problem and the file has a **No Problem** section → close is allowed
|
|
222
|
+
### 9. For close: delegate to `/wr-itil:close-incident` (P071 split slice 6c)
|
|
216
223
|
|
|
217
|
-
|
|
224
|
+
The `close` subcommand is now hosted by the `/wr-itil:close-incident` skill. This step exists as a thin-router forwarder — the Step 1 parser recognises the `<I###> close` shape and delegates via the Skill tool. This body is intentionally empty of implementation logic; the canonical documentation of the Linked-Problem gate (accepting `.known-error.md`, `.verifying.md`, and `.closed.md`), the No Problem bypass, and the rename lives in `/wr-itil:close-incident`.
|
|
218
225
|
|
|
219
|
-
|
|
220
|
-
2. Update the **Status** field to "Closed"
|
|
221
|
-
3. Append to **Timeline**: `[<timestamp> UTC] Incident closed`
|
|
226
|
+
Do not re-implement the close gate or the rename here — delegate. See "Deprecated-argument forwarders" under Step 1 for the canonical systemMessage.
|
|
222
227
|
|
|
223
228
|
### 10. For list: Show active incidents
|
|
224
229
|
|
|
225
230
|
Read all `.investigating.md`, `.mitigating.md`, and `.restored.md` files in `docs/incidents/`. Extract ID, title, severity, and status. Sort by severity (highest first). Display as a markdown table.
|
|
226
231
|
|
|
227
|
-
### 11. For link:
|
|
232
|
+
### 11. For link: delegate to `/wr-itil:link-incident` (P071 split slice 6d)
|
|
228
233
|
|
|
229
|
-
|
|
234
|
+
The `link` subcommand is now hosted by the `/wr-itil:link-incident` skill. This step exists as a thin-router forwarder — the Step 1 parser recognises the `<I###> link P<MMM>` shape and delegates via the Skill tool. This body is intentionally empty of implementation logic; the canonical documentation of the problem-file lookup and the `## Linked Problem` section write (including the retroactive-link-from-No-Problem case) lives in `/wr-itil:link-incident`.
|
|
230
235
|
|
|
231
|
-
|
|
232
|
-
2. Read or add the **Linked Problem** section with `P<MMM> (<title>) — <status>`
|
|
233
|
-
3. Report the link
|
|
236
|
+
Do not re-implement the link logic here — delegate. See "Deprecated-argument forwarders" under Step 1 for the canonical systemMessage.
|
|
234
237
|
|
|
235
238
|
### 12. Edge cases
|
|
236
239
|
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/usr/bin/env bats
|
|
2
|
+
# Contract assertions for manage-incident's `close` subcommand forwarder (P071 split slice 6c).
|
|
3
|
+
#
|
|
4
|
+
# Per ADR-010 amended (Skill Granularity section) + P071 phased plan:
|
|
5
|
+
# `/wr-itil:manage-incident <I> close` delegates to the new
|
|
6
|
+
# `/wr-itil:close-incident <I>` skill via a thin-router forwarder.
|
|
7
|
+
# Original skill already carries `deprecated-arguments: true` frontmatter
|
|
8
|
+
# (slice 5); forwarder emits a canonical one-line systemMessage
|
|
9
|
+
# deprecation notice.
|
|
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
|
+
# @jtbd JTBD-201 (restore service fast with an audit trail)
|
|
18
|
+
#
|
|
19
|
+
# Cross-reference:
|
|
20
|
+
# P071: docs/problems/071-argument-based-skill-subcommands-are-not-discoverable.open.md
|
|
21
|
+
# ADR-010 amended — split naming + forwarder contract + deprecated-arguments flag
|
|
22
|
+
# ADR-011 — manage-incident skill-wrapping precedent (close gate on linked problem)
|
|
23
|
+
# ADR-022 — problem lifecycle verification-pending status (.verifying.md allowance)
|
|
24
|
+
# ADR-013 Rule 1 — structured user interaction (forwarder emits systemMessage, not AskUserQuestion)
|
|
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 "manage-incident SKILL.md frontmatter has deprecated-arguments: true (ADR-010 amended)" {
|
|
33
|
+
# Already pinned by slice 5; slice 6c inherits. Guard against regression.
|
|
34
|
+
run grep -nE "^deprecated-arguments:[[:space:]]*true[[:space:]]*$" "$SKILL_FILE"
|
|
35
|
+
[ "$status" -eq 0 ]
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@test "manage-incident Step 1 forwards 'close' argument to /wr-itil:close-incident (P071)" {
|
|
39
|
+
# The forwarder names the target skill explicitly so the router is legible
|
|
40
|
+
# at the contract level. ADR-010's canonical shape: "invokes the new
|
|
41
|
+
# named skill via the Skill tool, not via re-prompting the user".
|
|
42
|
+
run grep -inE "/wr-itil:close-incident" "$SKILL_FILE"
|
|
43
|
+
[ "$status" -eq 0 ]
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@test "manage-incident Step 1 emits the canonical close deprecation notice (ADR-010 amended)" {
|
|
47
|
+
# ADR-010's canonical deprecation-notice template:
|
|
48
|
+
# "/wr-<plugin>:<old> <arg> is deprecated; use /wr-<plugin>:<new>
|
|
49
|
+
# directly. This forwarder will be removed in <plugin>'s next major
|
|
50
|
+
# version."
|
|
51
|
+
# The notice MUST be emitted as a systemMessage (not AskUserQuestion)
|
|
52
|
+
# because deprecation is informational, not decisional (ADR-013 Rule 1
|
|
53
|
+
# structured-interaction scope).
|
|
54
|
+
run grep -inE "is deprecated.*use /wr-itil:close-incident|deprecated.*close-incident|close.*removed in .* next major version" "$SKILL_FILE"
|
|
55
|
+
[ "$status" -eq 0 ]
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@test "manage-incident Step 1 close forwarder delegates via Skill tool (P071 regression guard)" {
|
|
59
|
+
# The forwarder must not duplicate the close logic — it must delegate.
|
|
60
|
+
# Per ADR-010: "thin-router forwarder re-invokes the new named skill
|
|
61
|
+
# via the Skill tool". If the forwarder grows its own gate + rename
|
|
62
|
+
# logic, the deprecation window will harden into a permanent fork.
|
|
63
|
+
# Guard against this by asserting the forwarder block mentions "delegate"
|
|
64
|
+
# or "Skill tool" language near the close-incident reference.
|
|
65
|
+
run grep -inE "delegate.*close-incident|Skill tool.*close-incident|close-incident.*Skill tool" "$SKILL_FILE"
|
|
66
|
+
[ "$status" -eq 0 ]
|
|
67
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/usr/bin/env bats
|
|
2
|
+
# Contract assertions for manage-incident's `link` subcommand forwarder (P071 split slice 6d).
|
|
3
|
+
#
|
|
4
|
+
# Per ADR-010 amended (Skill Granularity section) + P071 phased plan:
|
|
5
|
+
# `/wr-itil:manage-incident <I> link P<M>` delegates to the new
|
|
6
|
+
# `/wr-itil:link-incident <I> P<M>` skill via a thin-router forwarder.
|
|
7
|
+
# Original skill already carries `deprecated-arguments: true` frontmatter
|
|
8
|
+
# (slice 5); forwarder emits a canonical one-line systemMessage
|
|
9
|
+
# deprecation notice.
|
|
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
|
+
# @jtbd JTBD-201 (restore service fast with an audit trail)
|
|
18
|
+
#
|
|
19
|
+
# Cross-reference:
|
|
20
|
+
# P071: docs/problems/071-argument-based-skill-subcommands-are-not-discoverable.open.md
|
|
21
|
+
# ADR-010 amended — split naming + forwarder contract + deprecated-arguments flag
|
|
22
|
+
# ADR-011 — manage-incident skill-wrapping precedent (Linked Problem section)
|
|
23
|
+
# ADR-013 Rule 1 — structured user interaction (forwarder emits systemMessage, not AskUserQuestion)
|
|
24
|
+
# ADR-037 — contract-assertion bats pattern
|
|
25
|
+
|
|
26
|
+
setup() {
|
|
27
|
+
SKILL_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
|
|
28
|
+
SKILL_FILE="${SKILL_DIR}/SKILL.md"
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@test "manage-incident SKILL.md frontmatter has deprecated-arguments: true (ADR-010 amended)" {
|
|
32
|
+
# Already pinned by slice 5; slice 6d inherits. Guard against regression.
|
|
33
|
+
run grep -nE "^deprecated-arguments:[[:space:]]*true[[:space:]]*$" "$SKILL_FILE"
|
|
34
|
+
[ "$status" -eq 0 ]
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@test "manage-incident Step 1 forwards 'link' argument to /wr-itil:link-incident (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:link-incident" "$SKILL_FILE"
|
|
42
|
+
[ "$status" -eq 0 ]
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@test "manage-incident Step 1 emits the canonical link 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:link-incident|deprecated.*link-incident|link.*removed in .* next major version" "$SKILL_FILE"
|
|
54
|
+
[ "$status" -eq 0 ]
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@test "manage-incident Step 1 link forwarder delegates via Skill tool (P071 regression guard)" {
|
|
58
|
+
# The forwarder must not duplicate the link 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 problem-file-lookup
|
|
61
|
+
# + Linked Problem write logic, the deprecation window will harden into
|
|
62
|
+
# a permanent fork. Guard against this by asserting the forwarder block
|
|
63
|
+
# mentions "delegate" or "Skill tool" language near the link-incident
|
|
64
|
+
# reference.
|
|
65
|
+
run grep -inE "delegate.*link-incident|Skill tool.*link-incident|link-incident.*Skill tool" "$SKILL_FILE"
|
|
66
|
+
[ "$status" -eq 0 ]
|
|
67
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#!/usr/bin/env bats
|
|
2
|
+
# Contract assertions for manage-incident's `list` subcommand forwarder (P071 split slice 5).
|
|
3
|
+
#
|
|
4
|
+
# Per ADR-010 amended (Skill Granularity section) + P071 phased plan:
|
|
5
|
+
# `/wr-itil:manage-incident list` delegates to the new `/wr-itil:list-incidents`
|
|
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
|
+
# @jtbd JTBD-201 (restore service fast with an audit trail)
|
|
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-011 — manage-incident skill-wrapping precedent
|
|
22
|
+
# ADR-013 Rule 1 — structured user interaction (forwarder emits systemMessage, not AskUserQuestion)
|
|
23
|
+
# ADR-037 — contract-assertion bats pattern
|
|
24
|
+
|
|
25
|
+
setup() {
|
|
26
|
+
SKILL_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
|
|
27
|
+
SKILL_FILE="${SKILL_DIR}/SKILL.md"
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@test "manage-incident SKILL.md frontmatter has deprecated-arguments: true (ADR-010 amended)" {
|
|
31
|
+
# ADR-010 amendment pins the frontmatter flag name as `deprecated-arguments`.
|
|
32
|
+
# The host skill of any forwarder route must carry this flag so ADR-037
|
|
33
|
+
# cross-plugin contract assertions can find the opt-in during the
|
|
34
|
+
# deprecation window.
|
|
35
|
+
run grep -nE "^deprecated-arguments:[[:space:]]*true[[:space:]]*$" "$SKILL_FILE"
|
|
36
|
+
[ "$status" -eq 0 ]
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@test "manage-incident Step 1 forwards 'list' argument to /wr-itil:list-incidents (P071)" {
|
|
40
|
+
# The forwarder names the target skill explicitly so the router is legible
|
|
41
|
+
# at the contract level. ADR-010's canonical shape: "invokes the new
|
|
42
|
+
# named skill via the Skill tool, not via re-prompting the user".
|
|
43
|
+
run grep -inE "/wr-itil:list-incidents" "$SKILL_FILE"
|
|
44
|
+
[ "$status" -eq 0 ]
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@test "manage-incident Step 1 emits the canonical deprecation notice (ADR-010 amended)" {
|
|
48
|
+
# ADR-010's canonical deprecation-notice template:
|
|
49
|
+
# "/wr-<plugin>:<old> <arg> is deprecated; use /wr-<plugin>:<new>
|
|
50
|
+
# directly. This forwarder will be removed in <plugin>'s next major
|
|
51
|
+
# version."
|
|
52
|
+
# The notice MUST be emitted as a systemMessage (not AskUserQuestion)
|
|
53
|
+
# because deprecation is informational, not decisional (ADR-013 Rule 1
|
|
54
|
+
# structured-interaction scope).
|
|
55
|
+
run grep -inE "is deprecated.*use /wr-itil:list-incidents|deprecated.*list-incidents|removed in .* next major version" "$SKILL_FILE"
|
|
56
|
+
[ "$status" -eq 0 ]
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
@test "manage-incident Step 1 forwarder does not re-implement the list logic (P071 regression guard)" {
|
|
60
|
+
# The forwarder must not duplicate the list logic — it must delegate.
|
|
61
|
+
# Per ADR-010: "thin-router forwarder re-invokes the new named skill
|
|
62
|
+
# via the Skill tool". If the forwarder grows its own scan logic, the
|
|
63
|
+
# deprecation window will harden into a permanent fork. Guard against
|
|
64
|
+
# this by asserting the forwarder block mentions "delegate" or
|
|
65
|
+
# "Skill tool" language near the list-incidents reference.
|
|
66
|
+
run grep -inE "delegate.*list-incidents|Skill tool.*list-incidents|list-incidents.*Skill tool" "$SKILL_FILE"
|
|
67
|
+
[ "$status" -eq 0 ]
|
|
68
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#!/usr/bin/env bats
|
|
2
|
+
# Contract assertions for manage-incident's `mitigate` subcommand forwarder (P071 split slice 6a).
|
|
3
|
+
#
|
|
4
|
+
# Per ADR-010 amended (Skill Granularity section) + P071 phased plan:
|
|
5
|
+
# `/wr-itil:manage-incident <I> mitigate <action>` delegates to the new
|
|
6
|
+
# `/wr-itil:mitigate-incident <I> <action>` skill via a thin-router
|
|
7
|
+
# forwarder. Original skill already carries `deprecated-arguments: true`
|
|
8
|
+
# frontmatter (slice 5); forwarder emits a canonical one-line systemMessage
|
|
9
|
+
# deprecation notice.
|
|
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
|
+
# @jtbd JTBD-201 (restore service fast with an audit trail)
|
|
18
|
+
#
|
|
19
|
+
# Cross-reference:
|
|
20
|
+
# P071: docs/problems/071-argument-based-skill-subcommands-are-not-discoverable.open.md
|
|
21
|
+
# ADR-010 amended — split naming + forwarder contract + deprecated-arguments flag
|
|
22
|
+
# ADR-011 — manage-incident skill-wrapping precedent
|
|
23
|
+
# ADR-013 Rule 1 — structured user interaction (forwarder emits systemMessage, not AskUserQuestion)
|
|
24
|
+
# ADR-037 — contract-assertion bats pattern
|
|
25
|
+
|
|
26
|
+
setup() {
|
|
27
|
+
SKILL_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
|
|
28
|
+
SKILL_FILE="${SKILL_DIR}/SKILL.md"
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@test "manage-incident SKILL.md frontmatter has deprecated-arguments: true (ADR-010 amended)" {
|
|
32
|
+
# Already pinned by slice 5; slice 6a inherits. Guard against regression.
|
|
33
|
+
run grep -nE "^deprecated-arguments:[[:space:]]*true[[:space:]]*$" "$SKILL_FILE"
|
|
34
|
+
[ "$status" -eq 0 ]
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@test "manage-incident Step 1 forwards 'mitigate' argument to /wr-itil:mitigate-incident (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:mitigate-incident" "$SKILL_FILE"
|
|
42
|
+
[ "$status" -eq 0 ]
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@test "manage-incident Step 1 emits the canonical mitigate 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:mitigate-incident|deprecated.*mitigate-incident|mitigate.*removed in .* next major version" "$SKILL_FILE"
|
|
54
|
+
[ "$status" -eq 0 ]
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@test "manage-incident Step 1 mitigate forwarder delegates via Skill tool (P071 regression guard)" {
|
|
58
|
+
# The forwarder must not duplicate the mitigate 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 rename + evidence-gate
|
|
61
|
+
# logic, the deprecation window will harden into a permanent fork.
|
|
62
|
+
# Guard against this by asserting the forwarder block mentions "delegate"
|
|
63
|
+
# or "Skill tool" language near the mitigate-incident reference.
|
|
64
|
+
run grep -inE "delegate.*mitigate-incident|Skill tool.*mitigate-incident|mitigate-incident.*Skill tool" "$SKILL_FILE"
|
|
65
|
+
[ "$status" -eq 0 ]
|
|
66
|
+
}
|