@windyroad/itil 0.2.0-preview.61

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.
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "wr-itil",
3
+ "version": "0.1.0",
4
+ "description": "ITIL-aligned IT service management for Claude Code"
5
+ }
package/README.md ADDED
@@ -0,0 +1,62 @@
1
+ # @windyroad/itil
2
+
3
+ **ITIL-aligned IT service management for Claude Code.** Track recurring incidents, perform root cause analysis, and prioritise fixes using WSJF -- all inside your coding sessions.
4
+
5
+ Part of [Windy Road Agent Plugins](../../README.md).
6
+
7
+ ## What It Does
8
+
9
+ Bugs recur. Incidents repeat. Without a problem management process, you fix symptoms instead of causes. This plugin brings lightweight ITIL problem management to your AI coding workflow:
10
+
11
+ - **Create problem tickets** when incidents or failures surface during a session
12
+ - **Track root cause analysis** as investigation progresses
13
+ - **Transition status** through a structured lifecycle: Open, Known Error, Closed
14
+ - **Prioritise** using Weighted Shortest Job First (WSJF) to focus on the highest-value fixes
15
+
16
+ Problem tickets live in `docs/problems/` as markdown files -- version-controlled and always accessible.
17
+
18
+ Room is reserved for peer ITIL skills (incident, change) under the same plugin as they are added.
19
+
20
+ ## Install
21
+
22
+ ```bash
23
+ npx @windyroad/itil
24
+ ```
25
+
26
+ Restart Claude Code after installing.
27
+
28
+ > **Requires:** [`@windyroad/risk-scorer`](../risk-scorer/). The installer warns if it's missing.
29
+ >
30
+ > **Renamed from `@windyroad/problem`** — see [ADR-010](../../docs/decisions/010-rename-wr-problem-to-wr-itil.proposed.md). If you had the old package installed, uninstall it (`npx @windyroad/problem --uninstall`) before installing `@windyroad/itil`.
31
+
32
+ ## Usage
33
+
34
+ **Create or update a problem ticket:**
35
+
36
+ ```
37
+ /wr-itil:manage-problem
38
+ ```
39
+
40
+ This supports:
41
+
42
+ - Creating new problems from an incident or observed failure
43
+ - Updating root cause analysis with investigation findings
44
+ - Transitioning status (Open -> Known Error -> Closed)
45
+ - Closing problems with resolution details
46
+
47
+ ## How It Works
48
+
49
+ | Hook | Trigger | What it does |
50
+ |------|---------|-------------|
51
+ | `check-deps.sh` | Session start | Verifies that `wr-risk-scorer` is installed |
52
+
53
+ ## Updating and Uninstalling
54
+
55
+ ```bash
56
+ npx @windyroad/itil --update
57
+ npx @windyroad/itil --uninstall
58
+ ```
59
+
60
+ ## Licence
61
+
62
+ [MIT](../../LICENSE)
@@ -0,0 +1,65 @@
1
+ #!/bin/bash
2
+ # Shared dependency checker for windyroad-plugins marketplace.
3
+ # Called by each plugin's SessionStart hook with a list of required plugins.
4
+ #
5
+ # Usage: check-deps.sh <this-plugin-name> <required-plugin-1> [required-plugin-2] ...
6
+ #
7
+ # Checks if required sibling plugins are installed by looking for their
8
+ # .claude-plugin/plugin.json in the plugin cache. Outputs a warning to
9
+ # stderr (which surfaces as hook output) if any are missing.
10
+
11
+ set -euo pipefail
12
+
13
+ PLUGIN_NAME="${1:?Usage: check-deps.sh <plugin-name> <dep1> [dep2] ...}"
14
+ shift
15
+
16
+ MISSING=()
17
+
18
+ for DEP in "$@"; do
19
+ # Check if the dependency plugin is installed by looking for its marker.
20
+ # Installed plugins have their hooks loaded, so we check if the dep's
21
+ # hooks are present in the session. Simplest check: look for the plugin
22
+ # name in the installed plugins list.
23
+ FOUND=false
24
+
25
+ # Method 1: Check installed_plugins.json
26
+ if [ -f "$HOME/.claude/plugins/installed_plugins.json" ]; then
27
+ if python3 -c "
28
+ import json, sys
29
+ data = json.load(open('$HOME/.claude/plugins/installed_plugins.json'))
30
+ plugins = data.get('plugins', {})
31
+ for key in plugins:
32
+ if key.startswith('${DEP}@'):
33
+ sys.exit(0)
34
+ sys.exit(1)
35
+ " 2>/dev/null; then
36
+ FOUND=true
37
+ fi
38
+ fi
39
+
40
+ # Method 2: Check if plugin dir exists in cache
41
+ if [ "$FOUND" = false ]; then
42
+ for dir in "$HOME/.claude/plugins/cache/"*/"$DEP"/*/; do
43
+ if [ -f "${dir}.claude-plugin/plugin.json" ] 2>/dev/null; then
44
+ FOUND=true
45
+ break
46
+ fi
47
+ done
48
+ fi
49
+
50
+ # Method 3: Check if loaded via --plugin-dir (plugin hooks would be active)
51
+ # We can't easily check this, so we rely on methods 1 and 2.
52
+
53
+ if [ "$FOUND" = false ]; then
54
+ MISSING+=("$DEP")
55
+ fi
56
+ done
57
+
58
+ if [ ${#MISSING[@]} -gt 0 ]; then
59
+ echo ""
60
+ echo "WARNING: Plugin '$PLUGIN_NAME' requires the following plugins that may not be installed:"
61
+ for m in "${MISSING[@]}"; do
62
+ echo " - $m (install with: /plugin install $m@windyroad-plugins)"
63
+ done
64
+ echo ""
65
+ fi
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { resolve, dirname } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+
6
+ const __dirname = dirname(fileURLToPath(import.meta.url));
7
+ const utils = await import(resolve(__dirname, "../lib/install-utils.mjs"));
8
+
9
+ const PLUGIN = "wr-itil";
10
+ const DEPS = ["wr-risk-scorer"];
11
+
12
+ const flags = utils.parseStandardArgs(process.argv);
13
+
14
+ if (flags.help) {
15
+ console.log(`
16
+ Usage: npx @windyroad/itil [options]
17
+
18
+ ITIL-aligned problem management with WSJF prioritisation
19
+
20
+ Options:
21
+ --update Update this plugin and its skills
22
+ --uninstall Remove this plugin
23
+ --scope Installation scope: project (default) or user
24
+ --dry-run Show what would be done without executing
25
+ --help, -h Show this help
26
+ `);
27
+ process.exit(0);
28
+ }
29
+
30
+ if (flags.dryRun) {
31
+ utils.setDryRun(true);
32
+ console.log("[dry-run mode — no commands will be executed]\n");
33
+ }
34
+
35
+ utils.checkPrerequisites();
36
+
37
+ if (flags.uninstall) {
38
+ utils.uninstallPackage(PLUGIN);
39
+ } else if (flags.update) {
40
+ utils.updatePackage(PLUGIN);
41
+ } else {
42
+ utils.installPackage(PLUGIN, { deps: DEPS, scope: flags.scope });
43
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "hooks": {
3
+ "SessionStart": [
4
+ { "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/bin/check-deps.sh wr-itil wr-risk-scorer" }] }
5
+ ]
6
+ }
7
+ }
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Shared install utilities for @windyroad/* packages.
3
+ * Used by both per-plugin installers and the meta-installer.
4
+ */
5
+
6
+ import { execSync } from "node:child_process";
7
+
8
+ const MARKETPLACE_REPO = "windyroad/agent-plugins";
9
+ const MARKETPLACE_NAME = "windyroad";
10
+
11
+ let _dryRun = false;
12
+
13
+ export { MARKETPLACE_REPO, MARKETPLACE_NAME };
14
+
15
+ export function setDryRun(value) {
16
+ _dryRun = value;
17
+ }
18
+
19
+ export function isDryRun() {
20
+ return _dryRun;
21
+ }
22
+
23
+ export function run(cmd, label) {
24
+ console.log(` ${label}...`);
25
+ if (_dryRun) {
26
+ console.log(` [dry-run] ${cmd}`);
27
+ return true;
28
+ }
29
+ try {
30
+ execSync(cmd, { stdio: "inherit" });
31
+ return true;
32
+ } catch {
33
+ console.error(` FAILED: ${label}`);
34
+ return false;
35
+ }
36
+ }
37
+
38
+ export function checkPrerequisites() {
39
+ if (_dryRun) return;
40
+
41
+ try {
42
+ execSync("claude --version", { stdio: "pipe" });
43
+ } catch {
44
+ console.error(
45
+ "Error: 'claude' CLI not found. Install Claude Code first:\n https://docs.anthropic.com/en/docs/claude-code\n"
46
+ );
47
+ process.exit(1);
48
+ }
49
+ }
50
+
51
+ export function addMarketplace() {
52
+ return run(
53
+ `claude plugin marketplace add ${MARKETPLACE_REPO}`,
54
+ `Marketplace: ${MARKETPLACE_NAME}`
55
+ );
56
+ }
57
+
58
+ export function installPlugin(pluginName, { scope = "project" } = {}) {
59
+ return run(
60
+ `claude plugin install ${pluginName}@${MARKETPLACE_NAME} --scope ${scope}`,
61
+ pluginName
62
+ );
63
+ }
64
+
65
+ export function updatePlugin(pluginName) {
66
+ return run(`claude plugin update ${pluginName}`, pluginName);
67
+ }
68
+
69
+ export function uninstallPlugin(pluginName) {
70
+ return run(`claude plugin uninstall ${pluginName}`, `Removing ${pluginName}`);
71
+ }
72
+
73
+ /**
74
+ * Install a single package: marketplace add + plugin install.
75
+ */
76
+ export function installPackage(pluginName, { deps = [], scope = "project" } = {}) {
77
+ console.log(`\nInstalling @windyroad/${pluginName.replace("wr-", "")} (${scope} scope)...\n`);
78
+
79
+ addMarketplace();
80
+ installPlugin(pluginName, { scope });
81
+
82
+ if (deps.length > 0) {
83
+ console.log(`\nNote: This plugin works best with:`);
84
+ for (const dep of deps) {
85
+ console.log(` - @windyroad/${dep.replace("wr-", "")} (npx @windyroad/${dep.replace("wr-", "")})`);
86
+ }
87
+ }
88
+
89
+ console.log(
90
+ `\nDone! Restart Claude Code to activate.\n`
91
+ );
92
+ }
93
+
94
+ /**
95
+ * Update a single package.
96
+ */
97
+ export function updatePackage(pluginName) {
98
+ console.log(`\nUpdating @windyroad/${pluginName.replace("wr-", "")}...\n`);
99
+
100
+ run(
101
+ `claude plugin marketplace update ${MARKETPLACE_NAME}`,
102
+ "Updating marketplace"
103
+ );
104
+ updatePlugin(pluginName);
105
+
106
+ console.log("\nDone! Restart Claude Code to apply updates.\n");
107
+ }
108
+
109
+ /**
110
+ * Uninstall a single package.
111
+ */
112
+ export function uninstallPackage(pluginName) {
113
+ console.log(`\nUninstalling @windyroad/${pluginName.replace("wr-", "")}...\n`);
114
+
115
+ uninstallPlugin(pluginName);
116
+
117
+ console.log("\nDone. Restart Claude Code to apply changes.\n");
118
+ }
119
+
120
+ /**
121
+ * Parse standard flags used by all per-plugin installers.
122
+ */
123
+ export function parseStandardArgs(argv) {
124
+ const args = argv.slice(2);
125
+ const flags = {
126
+ help: args.includes("--help") || args.includes("-h"),
127
+ uninstall: args.includes("--uninstall"),
128
+ update: args.includes("--update"),
129
+ dryRun: args.includes("--dry-run"),
130
+ scope: "project",
131
+ };
132
+ const scopeIdx = args.indexOf("--scope");
133
+ if (scopeIdx !== -1 && args[scopeIdx + 1]) {
134
+ const val = args[scopeIdx + 1];
135
+ if (["project", "user", "local"].includes(val)) {
136
+ flags.scope = val;
137
+ } else {
138
+ console.error("--scope requires: project, user, or local");
139
+ process.exit(1);
140
+ }
141
+ }
142
+ return flags;
143
+ }
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@windyroad/itil",
3
+ "version": "0.2.0-preview.61",
4
+ "description": "ITIL-aligned IT service management for Claude Code (problem, and future incident/change skills)",
5
+ "bin": {
6
+ "windyroad-itil": "./bin/install.mjs"
7
+ },
8
+ "type": "module",
9
+ "license": "MIT",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/windyroad/agent-plugins.git",
13
+ "directory": "packages/itil"
14
+ },
15
+ "keywords": [
16
+ "claude-code",
17
+ "claude-code-plugin",
18
+ "ai-agent",
19
+ "ai-coding",
20
+ "itil"
21
+ ],
22
+ "files": [
23
+ "bin/",
24
+ "agents/",
25
+ "hooks/",
26
+ "skills/",
27
+ ".claude-plugin/",
28
+ "lib/"
29
+ ]
30
+ }
@@ -0,0 +1,287 @@
1
+ ---
2
+ name: wr-itil:manage-problem
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
5
+ ---
6
+
7
+ # Problem Management Skill
8
+
9
+ Create, update, or transition problem tickets following an ITIL-aligned problem management process. This skill is the authoritative definition of the problem management workflow — no separate process document is needed.
10
+
11
+ ## Operations
12
+
13
+ - **Create**: `problem <title or description>` — creates a new open problem
14
+ - **Update**: `problem <NNN> <update details>` — updates an existing problem (add root cause, evidence, fix strategy)
15
+ - **Transition**: `problem <NNN> known-error` — moves to known-error when root cause is confirmed
16
+ - **List**: `problem list` — shows all open problems sorted by priority
17
+ - **Work**: `problem work` — runs a review first, then begins working the highest-WSJF problem
18
+ - **Review**: `problem review` — re-assess all open problems: update priorities per RISK-POLICY.md, estimate effort, calculate WSJF, and update files
19
+
20
+ **Closing problems:** Problems are closed ONLY after the user verifies the fix in production — not when the fix is committed or released. The workflow:
21
+ 1. When the fix is released: add a `## Fix Released` section to the known-error file (e.g., `Deployed in v0.26.X. Awaiting user verification.`). Keep the file as `.known-error.md`.
22
+ 2. When the user explicitly confirms ("it's fixed", "verified", "working"): `git mv` to `.closed.md`, update the Status field, and reference the problem in the commit message (e.g., "Closes P008").
23
+ 3. Never assume the fix works — always wait for explicit user confirmation before closing.
24
+
25
+ ## Problem Lifecycle
26
+
27
+ | Status | File suffix | Meaning | Entry criteria |
28
+ |--------|-----------|---------|----------------|
29
+ | **Open** | `.open.md` | Reported, under investigation | New problem identified |
30
+ | **Known Error** | `.known-error.md` | Root cause confirmed, fix path clear | Root cause documented, reproduction test exists, workaround in place |
31
+ | **Closed** | `.closed.md` | Fix verified in production | Fix released AND user explicitly confirms it works |
32
+
33
+ **Test-driven resolution:** When root cause is identified, create a failing test that reproduces the problem. Skip/disable the test if a feature-disabling workaround is applied. Re-enable the test when the permanent fix is implemented — the test passing confirms resolution.
34
+
35
+ ## WSJF Prioritisation
36
+
37
+ Problems are ranked using Weighted Shortest Job First (WSJF):
38
+
39
+ **WSJF = (Severity × Status Multiplier) / Effort**
40
+
41
+ **Severity** = Impact × Likelihood (1-25) from `RISK-POLICY.md`. Read the impact levels, likelihood levels, and risk matrix from the policy — do not hardcode them here.
42
+
43
+ **Status Multiplier** (known-errors have confirmed root cause and clear fix path — higher value per unit of work):
44
+
45
+ | Status | Multiplier |
46
+ |--------|-----------|
47
+ | Known Error | 2.0 |
48
+ | Open | 1.0 |
49
+
50
+ **Effort** (estimated fix size — smaller effort = higher priority):
51
+
52
+ | Effort | Divisor | Description |
53
+ |--------|---------|-------------|
54
+ | S | 1 | < 1 hour, single file, quick fix |
55
+ | M | 2 | 1-4 hours, few files, moderate change |
56
+ | L | 4 | > 4 hours, multiple files, significant change |
57
+
58
+ **Example**: A Known Error with severity 8 (Impact 4 × Likelihood 2) and Small effort:
59
+ WSJF = (8 × 2.0) / 1 = **16.0** — do this first.
60
+
61
+ An Open problem with severity 6 (Impact 3 × Likelihood 2) and Large effort:
62
+ WSJF = (6 × 1.0) / 4 = **1.5** — lower priority despite medium severity.
63
+
64
+ When estimating effort, read the problem's root cause analysis and fix strategy. If effort is unknown, default to M (2).
65
+
66
+ ## Working a Problem
67
+
68
+ What "work" means depends on the problem's status:
69
+
70
+ **Open problem (no confirmed root cause):**
71
+ 1. Read the problem description and any preliminary hypotheses
72
+ 2. Investigate the root cause — read relevant source code, run experiments, query prod data. Do NOT guess.
73
+ 3. Document findings in the Root Cause Analysis section with evidence
74
+ 4. Create a failing reproduction test (can be skipped/disabled)
75
+ 5. Identify a workaround (even "delete and re-enter" counts)
76
+ 6. Update the problem file with all findings
77
+ 7. **Transition to Known Error immediately** — once root cause and workaround are documented, `git mv` the file to `.known-error.md` and update the Status field. Do not wait for a separate review.
78
+ 8. If the fix is small enough, continue straight to implementing it (becoming a Known Error → Closed flow in one session)
79
+
80
+ **Known Error (root cause confirmed, fix path clear):**
81
+ 1. Read the root cause analysis and fix strategy
82
+ 2. Implement the fix following the project's development workflow (plan if needed, architect review, tests, etc.)
83
+ 3. Include the problem doc closure in the fix commit (`git mv` to `.closed.md`, update Status)
84
+ 4. Push, create changeset, release per the lean release principle
85
+
86
+ **In both cases:** After completing work on one problem, run `problem work` again to pick up the next highest-WSJF problem. Keep going until the user says stop or no more problems are actionable.
87
+
88
+ ## Steps
89
+
90
+ ### 1. Parse the request
91
+
92
+ Determine the operation from `$ARGUMENTS`:
93
+ - If arguments start with a number (e.g., "011"), this is an update or transition
94
+ - If arguments contain "list", show a summary of all open problems
95
+ - If arguments contain "work", run a **review** first (step 9), then begin working the highest-WSJF problem
96
+ - If arguments contain "review", run the review (step 9) only
97
+ - Otherwise, this is a new problem creation
98
+
99
+ ### 2. For new problems: Check for duplicates FIRST
100
+
101
+ Before creating, search existing problems for similar issues. The user may not know a problem already exists.
102
+
103
+ 1. Extract keywords from the description/title (e.g., "foul drawn", "checkpoint", "delete", "stuck saving")
104
+ 2. Search all files in `docs/problems/` for those keywords using Grep
105
+ 3. Read the title and status of each match
106
+ 4. If matches are found, present them to the user via `AskUserQuestion`:
107
+ - "I found existing problems that may be related: P011 (stuck saving, CLOSED), P023 (foul drawn garbled, OPEN). Would you like to: (a) Update an existing problem, (b) Create a new problem anyway, (c) Cancel?"
108
+ 5. If the user chooses to update, switch to the update flow for that problem ID
109
+ 6. If no matches found, proceed to create
110
+
111
+ **Search strategy**: Search problem filenames AND file content. A match on the filename (kebab-case title) or the Description/Symptoms sections counts. Cast a wide net — false positives are cheap (user chooses), but false negatives mean duplicate problems.
112
+
113
+ ### 3. For new problems: Assign the next ID
114
+
115
+ Scan `docs/problems/` for existing files. Extract the highest numeric ID and increment by 1. Zero-pad to 3 digits.
116
+
117
+ ```bash
118
+ ls docs/problems/*.md 2>/dev/null | sed 's/.*\///' | grep -oE '^[0-9]+' | sort -n | tail -1
119
+ ```
120
+
121
+ ### 4. For new problems: Gather information
122
+
123
+ If the arguments contain a description, extract what you can. For anything missing, use `AskUserQuestion` to gather:
124
+
125
+ - **Title**: Short kebab-case-friendly description
126
+ - **Description**: What is happening? What should happen instead?
127
+ - **Priority**: Impact (1-5) × Likelihood (1-5) per RISK-POLICY.md
128
+
129
+ Do NOT ask for fields that can be inferred:
130
+ - **Reported date**: Use today's date
131
+ - **Status**: Always "Open" for new problems
132
+ - **Symptoms**: Infer from description if possible
133
+ - **Workaround**: Default to "None identified yet." unless obvious from context
134
+
135
+ ### 5. For new problems: Write the problem file
136
+
137
+ **File path**: `docs/problems/<NNN>-<kebab-case-title>.open.md`
138
+
139
+ **Template**:
140
+
141
+ ```markdown
142
+ # Problem <NNN>: <Title>
143
+
144
+ **Status**: Open
145
+ **Reported**: <YYYY-MM-DD>
146
+ **Priority**: <score> (<label>) — Impact: <label> (<n>) x Likelihood: <label> (<n>)
147
+
148
+ ## Description
149
+
150
+ <description>
151
+
152
+ ## Symptoms
153
+
154
+ <bullet list of observable symptoms>
155
+
156
+ ## Workaround
157
+
158
+ <workaround or "None identified yet.">
159
+
160
+ ## Impact Assessment
161
+
162
+ - **Who is affected**: <personas>
163
+ - **Frequency**: <when/how often>
164
+ - **Severity**: <High/Medium/Low — reason>
165
+ - **Analytics**: <data source or N/A>
166
+
167
+ ## Root Cause Analysis
168
+
169
+ ### Investigation Tasks
170
+
171
+ - [ ] Investigate root cause
172
+ - [ ] Create reproduction test
173
+ - [ ] Create INVEST story for permanent fix
174
+
175
+ ## Related
176
+
177
+ <links to related files, problems, ADRs>
178
+ ```
179
+
180
+ ### 6. For updates: Edit the existing file
181
+
182
+ Find the file matching the problem ID:
183
+ ```bash
184
+ ls docs/problems/<NNN>-*.md 2>/dev/null
185
+ ```
186
+
187
+ Apply the update — this could be:
188
+ - Adding root cause evidence to the "Root Cause Analysis" section
189
+ - Checking off investigation tasks
190
+ - Adding a "Fix Strategy" section
191
+ - Adding "Related" links
192
+ - Updating priority based on new information
193
+
194
+ ### 7. For status transitions
195
+
196
+ **Open → Known Error** (rename file, update content):
197
+
198
+ Pre-flight checks before allowing transition:
199
+ - [ ] Root cause is documented (not just "Preliminary Hypothesis")
200
+ - [ ] At least one investigation task is checked off
201
+ - [ ] A reproduction test exists or is referenced
202
+ - [ ] A workaround is documented (even if "feature disabled")
203
+
204
+ If any check fails, report which checks failed and ask the user to address them before transitioning.
205
+
206
+ ```bash
207
+ git mv docs/problems/<NNN>-<title>.open.md docs/problems/<NNN>-<title>.known-error.md
208
+ ```
209
+
210
+ Update the "Status" field in the file to "Known Error".
211
+
212
+ **Closing** requires user verification in production — see "Closing problems" above. When the fix is released, add a `## Fix Released` section but keep as `.known-error.md`. Only close when the user confirms.
213
+
214
+ ### 8. For list: Show summary
215
+
216
+ Read all `.open.md` and `.known-error.md` files in `docs/problems/`. Extract ID, title, priority, and status. Sort by priority (highest first). Display as a markdown table.
217
+
218
+ ### 9. For review: Re-assess all open problems
219
+
220
+ This is a batch operation that reviews every open/known-error problem and updates it.
221
+
222
+ **Step 9a: Read the risk framework**
223
+
224
+ 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 use outdated scales.
225
+
226
+ **Step 9b: For each open/known-error problem:**
227
+
228
+ 1. Read the problem file
229
+ 2. Read the codebase context — check if the problem's root cause has been investigated, if there are related fixes in git history, or if the problem is stale
230
+ 3. **Re-assess Impact** (1-5) using the product-specific impact levels from RISK-POLICY.md. Ask: "If this problem occurs during a live game, what is the worst business consequence?"
231
+ 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?"
232
+ 5. **Calculate Severity** = Impact × Likelihood
233
+ 6. **Look up Label** from the risk matrix label bands
234
+ 7. **Estimate Effort** (S/M/L) by reading the root cause analysis and fix strategy. Consider: how many files, how complex, does it need planning?
235
+ 8. **Calculate WSJF** = (Severity × Status Multiplier) / Effort Divisor
236
+ 9. **Update the Priority line** in the problem file if the score changed
237
+ 10. **Auto-transition to Known Error**: If an open problem has confirmed root cause AND a workaround documented (even "feature disabled"), automatically transition it to known-error:
238
+ - `git mv docs/problems/<NNN>-<title>.open.md docs/problems/<NNN>-<title>.known-error.md`
239
+ - Update the Status field to "Known Error"
240
+ - This happens automatically — do not ask the user
241
+
242
+ **Step 9c: Present summary**
243
+
244
+ After reviewing all problems, present a WSJF-ranked table:
245
+
246
+ | WSJF | ID | Title | Severity | Status | Effort | Notes |
247
+ |------|-----|-------|----------|--------|--------|-------|
248
+
249
+ Highlight:
250
+ - Problems whose priority changed (↑ or ↓)
251
+ - Problems that were auto-transitioned to known-error
252
+ - Problems that may be stale (reported > 2 weeks ago with no investigation progress)
253
+ - Problems that have been fixed but not closed (check git history for fix commits)
254
+ - Known errors with a `## Fix Released` section (pending user verification)
255
+
256
+ **Step 9d: Check for pending verifications**
257
+
258
+ For each known-error that has a `## Fix Released` section, use `AskUserQuestion` to ask the user if the fix has been verified in production. If the user confirms, close the problem (`git mv` to `.closed.md`, update Status). If the user says no or is unsure, leave it as known-error.
259
+
260
+ **Step 9e: Update files**
261
+
262
+ Edit each problem file where the priority changed. Do not commit — the user will commit when ready.
263
+
264
+ ### 10. Quality checks
265
+
266
+ After creating or updating a problem file, verify:
267
+
268
+ - **ID uniqueness**: No duplicate IDs in `docs/problems/`
269
+ - **Naming convention**: File matches `<NNN>-<kebab-case>.<status>.md`
270
+ - **Required sections**: Description, Impact Assessment, and Investigation Tasks exist
271
+ - **Priority calculation**: Score = Impact × Likelihood, label matches score
272
+ - **No orphaned references**: If the problem references other problems by number, verify those files exist
273
+ - **Status consistency**: The Status field in the frontmatter matches the filename suffix
274
+
275
+ **Priority label mapping**: Read the label bands from `RISK-POLICY.md` — do not hardcode them here.
276
+
277
+ ### 11. Report
278
+
279
+ After any operation, report:
280
+ - The file path created/modified
281
+ - The problem ID and title
282
+ - The current status
283
+ - Any quality check warnings
284
+
285
+ Do not commit. The user will commit when ready.
286
+
287
+ $ARGUMENTS