@windyroad/itil 0.35.16-preview.432 → 0.36.0-preview.436
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/capture-problem/SKILL.md +1 -0
- package/skills/manage-problem/SKILL.md +15 -9
- package/skills/manage-problem/test/manage-problem-readme-tie-break-order.bats +102 -0
- package/skills/review-problems/SKILL.md +10 -9
- package/skills/work-problem/SKILL.md +2 -2
- package/skills/work-problems/SKILL.md +12 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@windyroad/itil",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.36.0-preview.436",
|
|
4
4
|
"description": "ITIL-aligned IT service management for Claude Code (problem, and future incident/change skills)",
|
|
5
5
|
"bin": {
|
|
6
6
|
"windyroad-itil": "./bin/install.mjs"
|
|
@@ -195,6 +195,7 @@ Log the renumber decision in the operation report if origin and local diverged.
|
|
|
195
195
|
**Status**: Open
|
|
196
196
|
**Reported**: <YYYY-MM-DD>
|
|
197
197
|
**Priority**: 3 (Medium) — Impact: 3 x Likelihood: 1 (deferred — re-rate at next /wr-itil:review-problems)
|
|
198
|
+
**Origin**: internal
|
|
198
199
|
**Effort**: M (deferred — re-rate at next /wr-itil:review-problems)
|
|
199
200
|
**Type**: <type_value>
|
|
200
201
|
**JTBD**: <jtbd_trace_value_as_comma_separated_list_OR_omit_line_when_empty>
|
|
@@ -453,6 +453,7 @@ Before writing the problem file, perform a concern-boundary analysis on the gath
|
|
|
453
453
|
**Status**: Open
|
|
454
454
|
**Reported**: <YYYY-MM-DD>
|
|
455
455
|
**Priority**: <score> (<label>) — Impact: <label> (<n>) x Likelihood: <label> (<n>)
|
|
456
|
+
**Origin**: internal
|
|
456
457
|
|
|
457
458
|
## Description
|
|
458
459
|
|
|
@@ -492,6 +493,11 @@ Before writing the problem file, perform a concern-boundary analysis on the gath
|
|
|
492
493
|
<links to related files, problems, ADRs>
|
|
493
494
|
```
|
|
494
495
|
|
|
496
|
+
**`**Origin**` field (ADR-076)** records where the problem came from and is an authoritative input to the ADR-076 reported-first ranking tier. Two values:
|
|
497
|
+
|
|
498
|
+
- `internal` — internally discovered (the default for tickets created by hand or by an internal observation).
|
|
499
|
+
- `inbound-reported (#NN)` — reported to us by an external user via an upstream channel, where `#NN` is the upstream issue/discussion number. Written by ADR-062's inbound-discovery safe-and-valid branch at ticket creation. This is the **inbound** direction and is distinct from the `## Reported Upstream` section (which records the **outbound** direction — a ticket *we* reported up to someone else). The `**Origin**` field, not the regenerable `.upstream-cache.json`, is the rank-determining source of truth (ADR-076). When backfilling existing tickets during a review, stamp reported ones with `inbound-reported (#NN)`; leave the rest `internal`.
|
|
500
|
+
|
|
495
501
|
The `## Dependencies` section uses **bare ticket IDs** (`P038`, not `[P038](./038-...)` link syntax) — review output renders to links on demand. An empty row is valid and explicit: `- **Blocked by**: (none)` reads better than omitting the row. The transitive-effort rule in the WSJF Prioritisation section consumes this section at review time.
|
|
496
502
|
|
|
497
503
|
**Concrete example** (for P073 referencing two upstreams):
|
|
@@ -510,7 +516,7 @@ After writing the new `.open.md` file, regenerate `docs/problems/README.md` to i
|
|
|
510
516
|
|
|
511
517
|
**Mechanism**: use the same rendering rules as Step 7's P062 block (glob `docs/problems/*.open.md` / `*.known-error.md` / `*.verifying.md` / `*.parked.md`; rank open/known-error by WSJF; list verifyings in the Verification Queue ordered by release age; list parkeds in the Parked section). The refresh is a **render, not a re-rank** — existing WSJF values on the other ticket files are trusted per P062's established discipline. Only the new ticket's own WSJF is consumed from its freshly-written file.
|
|
512
518
|
|
|
513
|
-
**WSJF Rankings tie-break sort (P138)**: rows
|
|
519
|
+
**WSJF Rankings tier + tie-break sort (P138 + ADR-076)**: rows render **tier-first** — Tier 0 Critical-bypass (Severity Very High ≥17 OR security-classified OR incident-linked) → Tier 1 Inbound-reported (`**Origin**: inbound-reported`) → Tier 2 Internal — and **within each tier** by the multi-key `(WSJF desc, Known-Error-first, Effort-divisor asc, Reported-date asc, ID asc)` so the rendered top-to-bottom row order matches `/wr-itil:work-problems` SKILL.md Step 3's selection 1:1. The ADR-076 tier partition sets the top-level order; within a tier WSJF desc sets the band, then the next three keys are the canonical tie-break ladder (Known Error before Open; smaller effort before larger; older Reported date before newer); ID asc is the deterministic final tiebreaker for full-tie cases. The table MUST include a `Reported` column so the third tie-break input is visible, and an `Origin` column so the Tier 1 partition is visible — without them, users cannot reconcile the rendered order against the orchestrator's selection. <!-- REPORTED-FIRST-TIER-SOURCE: /wr-itil:work-problems SKILL.md Step 3 (ADR-076) --> <!-- TIE-BREAK-LADDER-SOURCE: /wr-itil:work-problems SKILL.md Step 3 --> Any future change to the tie-break ladder OR the reported-first tier MUST update this render block, the Step 7 P062 block, the Step 9e template, AND `/wr-itil:review-problems` SKILL.md Step 3 / Step 5 — drift here re-opens P138 / ADR-076.
|
|
514
520
|
|
|
515
521
|
**Verification Queue sort direction (P150)**: rows in the Verification Queue table are sorted by `Released date ASC` (oldest at row 1; same-day releases tiebreak by ID ASC) per ADR-022 + P048 user-task semantics — older entries are the most likely-verified candidates the user wants to surface first when closing the queue. Newest-first ordering pushes those actionable closure candidates below the fold and contradicts the section header. <!-- VQ-SORT-DIRECTION: oldest-first per ADR-022 --> Any future change to the VQ sort direction MUST update this render block, the Step 7 P062 block, the Step 9c presentation block, the Step 9e template, AND `/wr-itil:review-problems` + `/wr-itil:transition-problem` + `/wr-itil:transition-problems` + `/wr-itil:reconcile-readme` + `/wr-itil:list-problems` — drift here re-opens P150.
|
|
516
522
|
|
|
@@ -679,7 +685,7 @@ Every Step 7 status transition (Open → Known Error, Known Error → Verificati
|
|
|
679
685
|
|
|
680
686
|
The refresh uses the same rendering rules as Step 9e (dual-tolerant glob per RFC-002 migration window: `docs/problems/*.open.md docs/problems/open/*.md` / `*.known-error.md` + `known-error/*.md` / `*.verifying.md` + `verifying/*.md` / `*.parked.md` + `parked/*.md`; rank open/known-error by WSJF; list verifyings in the Verification Queue ordered by release age; list parkeds in the Parked section) but skips the full re-scoring pass — existing WSJF values on the ticket files are trusted. The refresh is a render, not a re-rank.
|
|
681
687
|
|
|
682
|
-
**WSJF Rankings tie-break sort (P138)**: rows
|
|
688
|
+
**WSJF Rankings tier + tie-break sort (P138 + ADR-076)**: rows render **tier-first** — Tier 0 Critical-bypass (Severity Very High ≥17 OR security-classified OR incident-linked) → Tier 1 Inbound-reported (`**Origin**: inbound-reported`) → Tier 2 Internal — and **within each tier** by the multi-key `(WSJF desc, Known-Error-first, Effort-divisor asc, Reported-date asc, ID asc)` so the rendered top-to-bottom row order matches `/wr-itil:work-problems` SKILL.md Step 3's selection 1:1. Within each tier, rows are ordered by the canonical tie-break ladder: Known Error before Open, smaller Effort before larger, older Reported date before newer. The table MUST include a `Reported` column so the third tie-break input is visible, and an `Origin` column so the Tier 1 partition is visible. <!-- REPORTED-FIRST-TIER-SOURCE: /wr-itil:work-problems SKILL.md Step 3 (ADR-076) --> <!-- TIE-BREAK-LADDER-SOURCE: /wr-itil:work-problems SKILL.md Step 3 --> Any future change to the tie-break ladder OR the reported-first tier MUST update this render block, the Step 5 P094 block, the Step 9e template, AND `/wr-itil:review-problems` SKILL.md Step 3 / Step 5 — drift here re-opens P138 / ADR-076.
|
|
683
689
|
|
|
684
690
|
**Verification Queue sort direction (P150)**: rows in the Verification Queue table are sorted by `Released date ASC` (oldest at row 1; same-day releases tiebreak by ID ASC) per ADR-022 + P048 user-task semantics — older entries are the most likely-verified candidates the user wants to surface first when closing the queue. Newest-first ordering pushes those actionable closure candidates below the fold and contradicts the section header. <!-- VQ-SORT-DIRECTION: oldest-first per ADR-022 --> Any future change to the VQ sort direction MUST update this render block, the Step 5 P094 block, the Step 9c presentation block, the Step 9e template, AND `/wr-itil:review-problems` + `/wr-itil:transition-problem` + `/wr-itil:transition-problems` + `/wr-itil:reconcile-readme` + `/wr-itil:list-problems` — drift here re-opens P150.
|
|
685
691
|
|
|
@@ -775,10 +781,10 @@ The re-rate pass is part of Step 9b's output — a re-rate row appears in the st
|
|
|
775
781
|
|
|
776
782
|
**Step 9c: Present summary and select problem to work**
|
|
777
783
|
|
|
778
|
-
After reviewing all problems, present a WSJF-ranked table for open/known-error problems (the main dev-work queue). Sort rows by `(WSJF desc, Known-Error-first, Effort-divisor asc, Reported-date asc, ID asc)` so row order matches `/wr-itil:work-problems` Step 3
|
|
784
|
+
After reviewing all problems, present a WSJF-ranked table for open/known-error problems (the main dev-work queue). Sort rows **tier-first** (Tier 0 Critical-bypass [Severity Very High ≥17 OR security-classified OR incident-linked] → Tier 1 Inbound-reported [`**Origin**: inbound-reported`] → Tier 2 Internal), then within each tier by `(WSJF desc, Known-Error-first, Effort-divisor asc, Reported-date asc, ID asc)` so row order matches `/wr-itil:work-problems` Step 3 selection 1:1 (P138 + ADR-076): <!-- REPORTED-FIRST-TIER-SOURCE: /wr-itil:work-problems SKILL.md Step 3 (ADR-076) -->
|
|
779
785
|
|
|
780
|
-
| WSJF | ID | Title | Severity | Status | Effort | Reported | Notes |
|
|
781
|
-
|
|
786
|
+
| WSJF | ID | Title | Severity | Status | Effort | Reported | Origin | Notes |
|
|
787
|
+
|------|-----|-------|----------|--------|--------|----------|--------|-------|
|
|
782
788
|
|
|
783
789
|
Then present a separate **Verification Queue** section for `.verifying.md` files (per ADR-022 — ranked by release age, oldest first; no WSJF because the multiplier is 0). Sort key + direction is the canonical `Released date ASC` (oldest at row 1; same-day releases tiebreak by ID ASC) — drift here re-opens P150. <!-- VQ-SORT-DIRECTION: oldest-first per ADR-022 --> The final `Likely verified?` column carries an **evidence-first** cell (per P186 — supersedes the original P048 Candidate 4 14-day heuristic). <!-- LIKELY-VERIFIED-CELL-SHAPE: evidence-based per P186 --> Three canonical values:
|
|
784
790
|
|
|
@@ -824,7 +830,7 @@ When evidence is **ambiguous, contested, or absent** (no specific in-session cit
|
|
|
824
830
|
|
|
825
831
|
Edit each problem file where the priority changed. Then write/overwrite `docs/problems/README.md` with the current ranked table so future `work` invocations can skip the full re-scan.
|
|
826
832
|
|
|
827
|
-
**WSJF Rankings tie-break sort (P138)**: rows
|
|
833
|
+
**WSJF Rankings tier + tie-break sort (P138 + ADR-076)**: rows render **tier-first** — Tier 0 Critical-bypass (Severity Very High ≥17 OR security-classified OR incident-linked) → Tier 1 Inbound-reported (`**Origin**: inbound-reported`) → Tier 2 Internal — and **within each tier** by the multi-key `(WSJF desc, Known-Error-first, Effort-divisor asc, Reported-date asc, ID asc)` so the rendered top-to-bottom row order matches `/wr-itil:work-problems` SKILL.md Step 3's selection 1:1. Within a tier, rows are ordered by the canonical tie-break ladder: Known Error before Open, smaller Effort before larger, older Reported date before newer. The `Reported` column MUST appear so the third tie-break input is visible, and an `Origin` column so the Tier 1 partition is visible. <!-- REPORTED-FIRST-TIER-SOURCE: /wr-itil:work-problems SKILL.md Step 3 (ADR-076) --> <!-- TIE-BREAK-LADDER-SOURCE: /wr-itil:work-problems SKILL.md Step 3 --> Any future change to the tie-break ladder OR the reported-first tier MUST update this template, the Step 5 P094 block, the Step 7 P062 block, AND `/wr-itil:review-problems` SKILL.md Step 3 / Step 5 — drift here re-opens P138 / ADR-076.
|
|
828
834
|
|
|
829
835
|
```markdown
|
|
830
836
|
# Problem Backlog
|
|
@@ -834,9 +840,9 @@ Edit each problem file where the priority changed. Then write/overwrite `docs/pr
|
|
|
834
840
|
|
|
835
841
|
## WSJF Rankings
|
|
836
842
|
|
|
837
|
-
| WSJF | ID | Title | Severity | Status | Effort | Reported |
|
|
838
|
-
|
|
839
|
-
| <score> | P<NNN> | <title> | <severity> | <status> | <effort> | <YYYY-MM-DD> |
|
|
843
|
+
| WSJF | ID | Title | Severity | Status | Effort | Reported | Origin |
|
|
844
|
+
|------|-----|-------|----------|--------|--------|----------|--------|
|
|
845
|
+
| <score> | P<NNN> | <title> | <severity> | <status> | <effort> | <YYYY-MM-DD> | <internal / inbound-reported (#NN)> |
|
|
840
846
|
...
|
|
841
847
|
|
|
842
848
|
## Verification Queue
|
|
@@ -5,6 +5,14 @@
|
|
|
5
5
|
# the table must include a Reported date column so the third tie-break
|
|
6
6
|
# input is visible to README readers.
|
|
7
7
|
#
|
|
8
|
+
# ADR-076: selection partitions into three tiers ABOVE the WSJF ladder —
|
|
9
|
+
# Tier 0 Critical-bypass (Severity >=17 OR security OR incident-linked)
|
|
10
|
+
# Tier 1 Inbound-reported (**Origin**: inbound-reported)
|
|
11
|
+
# Tier 2 Internal
|
|
12
|
+
# The tier dominates WSJF; within each tier the existing P138 ladder
|
|
13
|
+
# applies unchanged. Each render site carries a REPORTED-FIRST-TIER-SOURCE
|
|
14
|
+
# marker and an Origin column. Drift re-opens P138 / ADR-076.
|
|
15
|
+
#
|
|
8
16
|
# Hybrid coverage per ADR-005 + ADR-037:
|
|
9
17
|
# - Structural contract-assertions (Permitted Exception per ADR-005 /
|
|
10
18
|
# contract-assertion pattern per ADR-037): each of the five render-
|
|
@@ -214,3 +222,97 @@ EOF
|
|
|
214
222
|
T_low: KE M low-WSJF"
|
|
215
223
|
[ "$sorted" = "$expected" ]
|
|
216
224
|
}
|
|
225
|
+
|
|
226
|
+
# ---------------------------------------------------------------------------
|
|
227
|
+
# ADR-076 structural contract-assertions — reported-first tier
|
|
228
|
+
# ---------------------------------------------------------------------------
|
|
229
|
+
|
|
230
|
+
@test "manage-problem render blocks carry the REPORTED-FIRST-TIER-SOURCE marker (ADR-076)" {
|
|
231
|
+
# Each WSJF Rankings render block must carry the greppable tier marker
|
|
232
|
+
# pointing back to /wr-itil:work-problems Step 3 (the canonical tier
|
|
233
|
+
# source). Drift across render sites re-opens ADR-076.
|
|
234
|
+
run grep -F '<!-- REPORTED-FIRST-TIER-SOURCE: /wr-itil:work-problems SKILL.md Step 3 (ADR-076) -->' "$MANAGE_SKILL"
|
|
235
|
+
[ "$status" -eq 0 ]
|
|
236
|
+
# Step 5 P094, Step 7 P062, Step 9c presentation, Step 9e template.
|
|
237
|
+
count=$(grep -c -F '<!-- REPORTED-FIRST-TIER-SOURCE: /wr-itil:work-problems SKILL.md Step 3 (ADR-076) -->' "$MANAGE_SKILL")
|
|
238
|
+
[ "$count" -ge 3 ]
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
@test "review-problems carries the REPORTED-FIRST-TIER-SOURCE marker (ADR-076)" {
|
|
242
|
+
run grep -F '<!-- REPORTED-FIRST-TIER-SOURCE: /wr-itil:work-problems SKILL.md Step 3 (ADR-076) -->' "$REVIEW_SKILL"
|
|
243
|
+
[ "$status" -eq 0 ]
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
@test "work-problems carries the REPORTED-FIRST-TIER-SOURCE marker (ADR-076)" {
|
|
247
|
+
run grep -F '<!-- REPORTED-FIRST-TIER-SOURCE: /wr-itil:work-problems SKILL.md Step 3 (ADR-076) -->' "$WORK_SKILL"
|
|
248
|
+
[ "$status" -eq 0 ]
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
@test "manage-problem + review-problems README templates include the Origin column (ADR-076)" {
|
|
252
|
+
# Tier 1 (inbound-reported) membership must be visible to README readers,
|
|
253
|
+
# mirroring the Reported-column rationale for the third tie-break level.
|
|
254
|
+
run grep -F '| WSJF | ID | Title | Severity | Status | Effort | Reported | Origin |' "$MANAGE_SKILL"
|
|
255
|
+
[ "$status" -eq 0 ]
|
|
256
|
+
run grep -F '| WSJF | ID | Title | Severity | Status | Effort | Reported | Origin |' "$REVIEW_SKILL"
|
|
257
|
+
[ "$status" -eq 0 ]
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
@test "manage-problem ticket template defines the Origin field (ADR-076)" {
|
|
261
|
+
run grep -F '**Origin**: internal' "$MANAGE_SKILL"
|
|
262
|
+
[ "$status" -eq 0 ]
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
@test "render blocks warn that drift re-opens ADR-076" {
|
|
266
|
+
count=$(grep -c -F 're-opens P138 / ADR-076' "$MANAGE_SKILL")
|
|
267
|
+
[ "$count" -ge 3 ]
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
# ---------------------------------------------------------------------------
|
|
271
|
+
# ADR-076 behavioural fixture: tier partition dominates the WSJF ladder
|
|
272
|
+
# ---------------------------------------------------------------------------
|
|
273
|
+
|
|
274
|
+
@test "behavioural: tier partition outranks WSJF — critical-bypass + reported beat higher-WSJF internal" {
|
|
275
|
+
# Fixture columns: tier WSJF KE_flag Effort Reported ID Title
|
|
276
|
+
# tier: 0=critical-bypass, 1=inbound-reported, 2=internal
|
|
277
|
+
#
|
|
278
|
+
# The full selection key is tier ASC (k1) dominating, then the existing
|
|
279
|
+
# P138 ladder within tier: WSJF desc (k2), KE-first (k3), Effort asc (k4),
|
|
280
|
+
# Reported asc (k5), ID asc (k6).
|
|
281
|
+
#
|
|
282
|
+
# Tickets:
|
|
283
|
+
# C: critical-bypass, WSJF 2.0 (Severity 20 Open XL) — lowest WSJF
|
|
284
|
+
# R: inbound-reported, WSJF 3.0 (Severity 6 Open M)
|
|
285
|
+
# I: internal, WSJF 16.0 (Severity 8 KE S) — highest WSJF
|
|
286
|
+
#
|
|
287
|
+
# Without the tier, I (WSJF 16.0) would top the queue. With ADR-076 the
|
|
288
|
+
# tier dominates: C → R → I. This is the regression guard that the most
|
|
289
|
+
# critical issues come first and reported beats internal regardless of WSJF.
|
|
290
|
+
fixture_in="$TEST_TMP/fixture-tier.tsv"
|
|
291
|
+
cat >"$fixture_in" <<'EOF'
|
|
292
|
+
2 16.0 0 1 2026-05-20 502 I: internal high-WSJF
|
|
293
|
+
0 2.0 1 8 2026-05-10 501 C: critical low-WSJF
|
|
294
|
+
1 3.0 1 2 2026-05-15 503 R: reported mid-WSJF
|
|
295
|
+
EOF
|
|
296
|
+
|
|
297
|
+
# k1 tier asc; k2 WSJF desc; k3 KE_flag asc; k4 Effort asc; k5 Reported asc; k6 ID asc
|
|
298
|
+
sorted=$(sort -t$'\t' -k1,1n -k2,2nr -k3,3n -k4,4n -k5,5 -k6,6n "$fixture_in" | cut -f7)
|
|
299
|
+
expected="C: critical low-WSJF
|
|
300
|
+
R: reported mid-WSJF
|
|
301
|
+
I: internal high-WSJF"
|
|
302
|
+
[ "$sorted" = "$expected" ]
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
@test "behavioural: within a tier, the existing WSJF + tie-break ladder still applies (ADR-076)" {
|
|
306
|
+
# Two inbound-reported tickets in the same tier must order by the
|
|
307
|
+
# unchanged within-tier ladder: higher WSJF first, then KE-first.
|
|
308
|
+
fixture_in="$TEST_TMP/fixture-within-tier.tsv"
|
|
309
|
+
cat >"$fixture_in" <<'EOF'
|
|
310
|
+
1 6.0 1 1 2026-05-12 601 R_low: reported WSJF 6
|
|
311
|
+
1 12.0 0 2 2026-05-11 602 R_high: reported WSJF 12
|
|
312
|
+
EOF
|
|
313
|
+
|
|
314
|
+
sorted=$(sort -t$'\t' -k1,1n -k2,2nr -k3,3n -k4,4n -k5,5 -k6,6n "$fixture_in" | cut -f7)
|
|
315
|
+
expected="R_high: reported WSJF 12
|
|
316
|
+
R_low: reported WSJF 6"
|
|
317
|
+
[ "$sorted" = "$expected" ]
|
|
318
|
+
}
|
|
@@ -38,7 +38,7 @@ For each open / known-error ticket (dual-tolerant enumeration spans `docs/proble
|
|
|
38
38
|
1. Read the problem file.
|
|
39
39
|
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.
|
|
40
40
|
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?"
|
|
41
|
-
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
|
+
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?" **Inbound-report evidence (ADR-076):** if the ticket carries `**Origin**: inbound-reported`, an external user actually hit this failure — that is legitimate "previously observed failure mode" evidence and may justify Likelihood up to level 5 *on its own merits*. This is honest risk-keeping, **NOT a ranking lever**: do not inflate Likelihood to push reported tickets up the queue. The reported-first **tier** in Step 3 does the prioritisation; the risk axes stay honest because the risk-scorer release-risk gate reads the same Likelihood scale (ADR-026 grounding).
|
|
42
42
|
5. **Calculate Severity** = Impact × Likelihood.
|
|
43
43
|
6. **Look up Label** from the risk matrix label bands.
|
|
44
44
|
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.
|
|
@@ -49,6 +49,7 @@ For each open / known-error ticket (dual-tolerant enumeration spans `docs/proble
|
|
|
49
49
|
- Update the Status field to "Known Error".
|
|
50
50
|
- Re-stage explicitly per the P057 staging trap: `git add <new-path>` after the Edit.
|
|
51
51
|
- This happens automatically — do not ask the user. The transition's fix-strategy is documented; only the shipping is outstanding.
|
|
52
|
+
11. **Confirm the `**Origin**` field (ADR-076)** — this is where "checking for items reported upstream to us" lands during a review. If the ticket originated from an external inbound report, set `**Origin**: inbound-reported (#NN)` (NN = the upstream issue/discussion number); cross-check `docs/problems/.upstream-cache.json` (`matched_local_ticket`) and any acknowledgement comment to confirm. Otherwise set/leave `**Origin**: internal`. Tickets predating ADR-076 carry no Origin field and default to `internal` until stamped here. This field — not the regenerable cache — drives the Step 3 reported-first tier, so stamping it during the review is what makes reported tickets rank ahead on the refreshed ranking.
|
|
52
53
|
|
|
53
54
|
### 2.5. Dependency-graph traversal — propagate transitive effort (P076)
|
|
54
55
|
|
|
@@ -66,11 +67,11 @@ Re-read the WSJF Prioritisation → "Transitive dependencies (P076)" subsection
|
|
|
66
67
|
|
|
67
68
|
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):
|
|
68
69
|
|
|
69
|
-
**WSJF Rankings** — dev-work queue (open + known-error),
|
|
70
|
+
**WSJF Rankings** — dev-work queue (open + known-error), rendered **tier-first** — Tier 0 Critical-bypass (Severity Very High ≥17 OR security-classified OR incident-linked) → Tier 1 Inbound-reported (`**Origin**: inbound-reported`) → Tier 2 Internal — and **within each tier** by the multi-key `(WSJF desc, Known-Error-first, Effort-divisor asc, Reported-date asc, ID asc)` so rendered top-to-bottom row order matches `/wr-itil:work-problems` SKILL.md Step 3 selection 1:1 (P138 + ADR-076). Within each tier, rows follow the canonical tie-break ladder: Known Error before Open, smaller Effort before larger, older Reported date before newer. The `Reported` column MUST appear so the third tie-break input is visible, and an `Origin` column so the Tier 1 partition is visible. <!-- REPORTED-FIRST-TIER-SOURCE: /wr-itil:work-problems SKILL.md Step 3 (ADR-076) --> <!-- TIE-BREAK-LADDER-SOURCE: /wr-itil:work-problems SKILL.md Step 3 --> Any change to the tie-break ladder OR the reported-first tier MUST update this rendering block, Step 5's README template, AND `/wr-itil:manage-problem` SKILL.md Step 5 P094 / Step 7 P062 / Step 9e — drift re-opens P138 / ADR-076.
|
|
70
71
|
|
|
71
72
|
```
|
|
72
|
-
| WSJF | ID | Title | Severity | Status | Effort | Reported | Notes |
|
|
73
|
-
|
|
73
|
+
| WSJF | ID | Title | Severity | Status | Effort | Reported | Origin | Notes |
|
|
74
|
+
|------|-----|-------|----------|--------|--------|----------|--------|-------|
|
|
74
75
|
```
|
|
75
76
|
|
|
76
77
|
**Verification Queue** — `.verifying.md` tickets, sorted by `Released date ASC` (oldest at row 1; same-day releases tiebreak by ID ASC) per ADR-022 + P048 user-task semantics. Older entries are the most likely-verified candidates the user wants to surface first when closing the queue; newest-first ordering pushes those actionable closure candidates below the fold and contradicts the section header. <!-- VQ-SORT-DIRECTION: oldest-first per ADR-022 --> Any change to the VQ sort direction MUST update this rendering block, Step 5's README template, AND `/wr-itil:manage-problem` SKILL.md Step 5 P094 / Step 7 P062 / Step 9c / Step 9e + `/wr-itil:transition-problem` + `/wr-itil:transition-problems` + `/wr-itil:reconcile-readme` + `/wr-itil:list-problems` — drift re-opens P150. The `Likely verified?` column carries an **evidence-first** cell (per P186 — supersedes the age-based heuristic). <!-- LIKELY-VERIFIED-CELL-SHAPE: evidence-based per P186 --> Three canonical values:
|
|
@@ -189,7 +190,7 @@ For each unmatched fresh report, run these steps in order; record the outcome in
|
|
|
189
190
|
|
|
190
191
|
5. **Clear-malicious branch**: post a brief gated verdict comment (JTBD-301 acknowledgement contract — silent close is forbidden per ADR-062 Decision Drivers row 1). Comment body names the policy-violation classification verbatim from the `wr-risk-scorer:inbound-report` verdict. External-comms gates ride. Then close the upstream issue via `gh issue close <id>`. Append the reporter handle + classification to `docs/audits/inbound-discovery-log.md` for P123 block-list consumption when that ticket lands. Cache entry classification: `clear-malicious-closed`. **Gate-denial sub-branch**: if the verdict-comment gate denies, record `cache_audit_note: gate-denied-clear-malicious-pre-close` and do NOT close the upstream issue (silent close is forbidden — preserve the report for the next pass).
|
|
191
192
|
|
|
192
|
-
6. **Safe-and-valid branch**: invoke `/wr-itil:capture-problem --no-prompt <report-body-verbatim>` to create the local ticket. The `--no-prompt` flag defaults to `type=technical`; the maintainer re-classifies at next interactive `review-problems` re-rate. Rationale: a default of `user-business` would mis-classify security-advisory-channel reports as user-business when they're often deep technical bugs; the maintainer-re-classify path is the safety net. Verbatim body preservation honors JTBD-301 persona constraint "capture context faithfully without cognitive re-shaping" and JTBD-201 audit-trail fidelity. Then post a gated `gh issue comment` acknowledgement carrying the new local-ticket reference. Cache entry classification: `safe-and-valid-local-ticket-created`; populate `matched_local_ticket: P<NNN>` with the freshly-allocated ID. **Gate-denial sub-branch**: if the acknowledgement comment gate denies, the local ticket already exists — record `cache_audit_note: gate-denied-safe-and-valid-acknowledgement` and continue. The acknowledgement comment will retry on the next discovery pass.
|
|
193
|
+
6. **Safe-and-valid branch**: invoke `/wr-itil:capture-problem --no-prompt <report-body-verbatim>` to create the local ticket. The `--no-prompt` flag defaults to `type=technical`; the maintainer re-classifies at next interactive `review-problems` re-rate. **Stamp the inbound origin (ADR-076)**: the skeleton writes `**Origin**: internal` by default — Edit it on the freshly-created ticket to `**Origin**: inbound-reported (#<id>)` (the upstream issue/discussion `<id>` polled this pass) so the ADR-076 reported-first tier ranks it ahead of internal tickets. The on-ticket `**Origin**` field, not the regenerable cache, is the authoritative rank input (ADR-076); the cache's `matched_local_ticket` remains the audit/replay record. Rationale: a default of `user-business` would mis-classify security-advisory-channel reports as user-business when they're often deep technical bugs; the maintainer-re-classify path is the safety net. Verbatim body preservation honors JTBD-301 persona constraint "capture context faithfully without cognitive re-shaping" and JTBD-201 audit-trail fidelity. Then post a gated `gh issue comment` acknowledgement carrying the new local-ticket reference. Cache entry classification: `safe-and-valid-local-ticket-created`; populate `matched_local_ticket: P<NNN>` with the freshly-allocated ID. **Gate-denial sub-branch**: if the acknowledgement comment gate denies, the local ticket already exists — record `cache_audit_note: gate-denied-safe-and-valid-acknowledgement` and continue. The acknowledgement comment will retry on the next discovery pass.
|
|
193
194
|
|
|
194
195
|
#### 4.5f. Audit-log append
|
|
195
196
|
|
|
@@ -219,11 +220,11 @@ Write / overwrite `docs/problems/README.md` with the refreshed ranking so future
|
|
|
219
220
|
|
|
220
221
|
## WSJF Rankings
|
|
221
222
|
|
|
222
|
-
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. Rows
|
|
223
|
+
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. Rows render **tier-first** (Tier 0 Critical-bypass [Severity Very High ≥17 OR security-classified OR incident-linked] → Tier 1 Inbound-reported [`**Origin**: inbound-reported`] → Tier 2 Internal), then within each tier by `(WSJF desc, Known-Error-first, Effort-divisor asc, Reported-date asc, ID asc)` so top-to-bottom order matches `/wr-itil:work-problems` Step 3 selection 1:1 (P138 + ADR-076). The `Reported` and `Origin` columns MUST appear. <!-- REPORTED-FIRST-TIER-SOURCE: /wr-itil:work-problems SKILL.md Step 3 (ADR-076) -->
|
|
223
224
|
|
|
224
|
-
| WSJF | ID | Title | Severity | Status | Effort | Reported |
|
|
225
|
-
|
|
226
|
-
| <score> | P<NNN> | <title> | <severity> | <status> | <effort> | <YYYY-MM-DD> |
|
|
225
|
+
| WSJF | ID | Title | Severity | Status | Effort | Reported | Origin |
|
|
226
|
+
|------|-----|-------|----------|--------|--------|----------|--------|
|
|
227
|
+
| <score> | P<NNN> | <title> | <severity> | <status> | <effort> | <YYYY-MM-DD> | <internal / inbound-reported (#NN)> |
|
|
227
228
|
...
|
|
228
229
|
|
|
229
230
|
## Verification Queue
|
|
@@ -6,7 +6,7 @@ allowed-tools: Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion, Skill, Agen
|
|
|
6
6
|
|
|
7
7
|
# Work Problem — Pick-and-Run
|
|
8
8
|
|
|
9
|
-
Pick the highest-WSJF ticket from the current backlog and work it end-to-end. This is the **singular** entry point — one ticket per invocation. Selection is **framework-mediated** per ADR-044's Framework-Mediated Surface (Prioritisation row): the agent applies the WSJF formula + documented tie-break ladder mechanically and reports the chosen ticket + the rung that decided. The user retains direct override via `/wr-itil:work-problem <NNN>` invocation and via mid-flow correction (ADR-044 category 6).
|
|
9
|
+
Pick the highest-WSJF ticket from the current backlog and work it end-to-end. This is the **singular** entry point — one ticket per invocation. Selection is **framework-mediated** per ADR-044's Framework-Mediated Surface (Prioritisation row): the agent applies the ADR-076 tier partition (Critical-bypass → Inbound-reported → Internal) then the WSJF formula + documented within-tier tie-break ladder mechanically, and reports the chosen ticket + its tier + the rung that decided. The user retains direct override via `/wr-itil:work-problem <NNN>` invocation and via mid-flow correction (ADR-044 category 6).
|
|
10
10
|
|
|
11
11
|
This skill is the P071 phased-landing split of `/wr-itil:manage-problem work` per ADR-010 amended Skill Granularity rule: one skill per distinct user intent. The original `/wr-itil:manage-problem work` 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
12
|
|
|
@@ -21,7 +21,7 @@ Both names coexist intentionally per P071's out-of-scope note on the naming coex
|
|
|
21
21
|
|
|
22
22
|
**In scope:**
|
|
23
23
|
- Read `docs/problems/README.md` when fresh; otherwise delegate the refresh to `/wr-itil:review-problems` first (never re-implement the re-scoring logic locally — same anti-fork discipline as the list-problems cache path).
|
|
24
|
-
- Pick the highest-
|
|
24
|
+
- Pick the highest-priority ticket via the framework-mediated selection: first by ADR-076 **tier** (Tier 0 Critical-bypass [Severity Very High ≥17 OR security-classified OR incident-linked] → Tier 1 Inbound-reported [`**Origin**: inbound-reported`] → Tier 2 Internal), then within the highest non-empty tier by the tie-break ladder (Known Error > Open; smaller effort first; older reported date; ticket number ascending) per ADR-044 Framework-Mediated Surface. Report the chosen ticket + its tier + the rung that decided. No `AskUserQuestion` fires for selection.
|
|
25
25
|
- Honour the user-override path `/wr-itil:work-problem <NNN>` — when the user names a ticket directly, skip the ladder and proceed to Step 3 with the named ticket.
|
|
26
26
|
- Delegate the actual work to `/wr-itil:manage-problem <NNN>` via the Skill tool so the investigation / known-error transition / fix / closure flow stays hosted on a single authoritative workflow (ADR-010 thin-router discipline applied to the work path).
|
|
27
27
|
- Scope-expansion prompt (ADR-013 Rule 1; ADR-044 category-2 deviation-approval surface) when the selected ticket's effort grows during work — same three-option structure as `/wr-itil:manage-problem`'s Working a Problem section.
|
|
@@ -192,7 +192,7 @@ After Step 0b completes (whether dispatched or silent-passed), proceed to Step 1
|
|
|
192
192
|
|
|
193
193
|
Read `docs/problems/README.md` if it exists and is fresh (check via git history — see manage-problem step 9 for the cache freshness check). If stale or missing, scan all open + known-error tickets via the dual-tolerant pattern `ls docs/problems/*.open.md docs/problems/*.known-error.md docs/problems/open/*.md docs/problems/known-error/*.md 2>/dev/null` (RFC-002 migration window — covers BOTH the flat `<NNN>-<title>.<state>.md` filename-suffix layout AND the per-state subdir `<state>/<NNN>-<title>.md` layout), extract their WSJF scores, and rank them.
|
|
194
194
|
|
|
195
|
-
**README row order matches Step 3 tie-break selection (P138)**:
|
|
195
|
+
**README row order matches Step 3 tier + tie-break selection (P138 + ADR-076)**: the README's WSJF Rankings table is rendered tier-first — rows partition into Tier 0 Critical-bypass (Severity ≥17 OR security-classified OR incident-linked) → Tier 1 Inbound-reported (`**Origin**: inbound-reported`) → Tier 2 Internal, and within each tier by the multi-key sort `(WSJF desc, Known-Error-first, Effort-divisor asc, Reported-date asc, ID asc)`. The cache-fresh path can therefore read the rendered table top-to-bottom and the first row is the orchestrator's pick — no in-memory tier/tie-break re-application needed. The slow path scan must apply the same tier partition then multi-key sort. <!-- REPORTED-FIRST-TIER-SOURCE: /wr-itil:work-problems SKILL.md Step 3 (ADR-076) --> <!-- TIE-BREAK-LADDER-SOURCE: /wr-itil:work-problems SKILL.md Step 3 -->
|
|
196
196
|
|
|
197
197
|
Exclude:
|
|
198
198
|
- `.closed.md` files (done)
|
|
@@ -253,12 +253,21 @@ Step 2.5b is the single source of truth for routing accumulated user-answerable
|
|
|
253
253
|
|
|
254
254
|
**Cross-skill principle (architect FLAG, P122 + P126)**: orchestrator main turns default to `AskUserQuestion` when available; the AFK persona (JTBD-006) is served by the **subprocess-boundary contract under ADR-032** (iteration subprocess workers are AFK by construction via `claude -p` — they exit at `ITERATION_SUMMARY` and never reach the orchestrator's stop or halt surfaces), NOT by suppressing `AskUserQuestion` at the orchestrator layer. Step 5's iteration-prompt template carries the per-subprocess AFK contract (constraint: "Do not call `AskUserQuestion`"); the orchestrator's stop and halt surfaces fire only in the main turn where the user is presumed present. P122 established this principle at Step 2.5; P126 extends it to every halt path that emits a final AFK summary (the principle: **halt-paths-must-route-design-questions-through-Step-2.5b** — every halt path that fires after iters have accumulated user-answerable skips MUST run Step 2.5b before emitting its summary).
|
|
255
255
|
|
|
256
|
-
### Step 3: Pick the highest-WSJF problem
|
|
256
|
+
### Step 3: Pick the highest-WSJF problem in the highest non-empty tier
|
|
257
257
|
|
|
258
|
-
|
|
258
|
+
Selection partitions the backlog into three **tiers** and works the highest non-empty tier first; the WSJF tie-break ladder applies **within** a tier, not across tiers. Tiers, highest first (ADR-076):
|
|
259
|
+
|
|
260
|
+
1. **Tier 0 — Critical bypass**: Severity Very High (≥17) OR security-classified OR incident-linked. The most critical issues always come first, regardless of origin.
|
|
261
|
+
2. **Tier 1 — Inbound-reported**: ticket carries `**Origin**: inbound-reported` (reported to us by an external user; ADR-062). Worked ahead of internal tickets — customer-service / feedback-signal preservation: ignored reporters stop reporting and churn.
|
|
262
|
+
3. **Tier 2 — Internal**: everything else (`**Origin**: internal` or no Origin field).
|
|
263
|
+
|
|
264
|
+
Within the highest non-empty tier, select the problem with the highest WSJF score. If there's a tie, prefer:
|
|
259
265
|
1. Known Errors over Open problems (they have a confirmed fix path — less risk of wasted effort)
|
|
260
266
|
2. Smaller effort over larger (faster throughput)
|
|
261
267
|
3. Older reported date (longer wait = higher urgency)
|
|
268
|
+
4. Lower ID (deterministic final tiebreaker)
|
|
269
|
+
|
|
270
|
+
The full selection order is therefore: **tier** (Critical-bypass → Inbound-reported → Internal), then the within-tier ladder `(WSJF desc, Known-Error-first, Effort-divisor asc, Reported-date asc, ID asc)`. <!-- REPORTED-FIRST-TIER-SOURCE: /wr-itil:work-problems SKILL.md Step 3 (ADR-076) -->
|
|
262
271
|
|
|
263
272
|
### Step 4: Classify each problem
|
|
264
273
|
|