@windyroad/itil 1.2.0 → 2.0.0-preview.1111
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/.agents/plugins/marketplace.json +12 -0
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +42 -0
- package/README.md +34 -25
- package/agents/hang-off-check.md +34 -34
- package/bin/install.mjs +71 -5
- package/bin/wr-itil-catchup-scan +4 -4
- package/bin/wr-itil-check-deferred-placeholder-staleness +4 -4
- package/bin/wr-itil-check-fail-soft-skip-discipline +4 -4
- package/bin/wr-itil-check-fix-rfc-trace +4 -4
- package/bin/wr-itil-check-locale-discipline +4 -4
- package/bin/wr-itil-check-outbound-responses-staleness +4 -4
- package/bin/wr-itil-check-problems-readme-budget +4 -4
- package/bin/wr-itil-check-rfc-has-stories +4 -4
- package/bin/wr-itil-check-rfc-stories-ratified +4 -4
- package/bin/wr-itil-check-ticket-jtbd-ratification +4 -4
- package/bin/wr-itil-check-upstream-cache-staleness +4 -4
- package/bin/wr-itil-check-upstream-responses +4 -4
- package/bin/wr-itil-classify-readme-drift +4 -4
- package/bin/wr-itil-derive-release-vehicle +4 -4
- package/bin/wr-itil-detect-unratified-stories-maps +4 -4
- package/bin/wr-itil-effort-tally +4 -4
- package/bin/wr-itil-enumerate-postrelease-kv-candidates +4 -4
- package/bin/wr-itil-evaluate-relevance +4 -4
- package/bin/wr-itil-mark-create-gate +4 -4
- package/bin/wr-itil-mark-story-oversight-confirmed +4 -4
- package/bin/wr-itil-migrate-problems-layout +4 -4
- package/bin/wr-itil-migrate-story-status-mirror +4 -4
- package/bin/wr-itil-next-rfc-id +4 -4
- package/bin/wr-itil-plugin-exercise-index +4 -4
- package/bin/wr-itil-plugin-maturity-populate +4 -4
- package/bin/wr-itil-plugin-maturity-render +4 -4
- package/bin/wr-itil-plugin-validate-ci-gate +4 -4
- package/bin/wr-itil-reconcile-readme +4 -4
- package/bin/wr-itil-reconcile-rfcs +4 -4
- package/bin/wr-itil-reconcile-stories +4 -4
- package/bin/wr-itil-reconcile-story-maps +4 -4
- package/bin/wr-itil-render-story-map +4 -4
- package/bin/wr-itil-resolve-governance-plugin-dirs +4 -4
- package/bin/wr-itil-skill-invocations +4 -4
- package/bin/wr-itil-story-map-edit +4 -4
- package/bin/wr-itil-story-map-query +4 -4
- package/bin/wr-itil-update-jtbd-references-section +4 -4
- package/bin/wr-itil-update-problem-references-section +4 -4
- package/bin/wr-itil-update-problem-rfcs-section +4 -4
- package/bin/wr-itil-update-rfc-commits-section +4 -4
- package/bin/wr-itil-update-rfc-references-section +4 -4
- package/bin/wr-itil-verify-iter-summary +4 -4
- package/hooks/itil-assistant-output-gate.sh +3 -3
- package/hooks/itil-assistant-output-review.sh +5 -5
- package/hooks/itil-bash-polling-antipattern-detect.sh +11 -11
- package/hooks/itil-changeset-discipline.sh +24 -24
- package/hooks/itil-claude-space-protection.sh +21 -14
- package/hooks/itil-codex-dispatch.sh +164 -0
- package/hooks/itil-commit-trailer-transition-advisory.sh +11 -11
- package/hooks/itil-correction-detect.sh +8 -8
- package/hooks/itil-deferral-cadence-gate.sh +23 -23
- package/hooks/itil-fictional-defer-detect.sh +16 -16
- package/hooks/itil-fix-title-lifecycle-advisory.sh +11 -11
- package/hooks/itil-mid-loop-ask-detect.sh +14 -14
- package/hooks/itil-no-implement-draft-gate.sh +18 -18
- package/hooks/itil-pending-questions-surface.sh +11 -11
- package/hooks/itil-readme-refresh-discipline.sh +27 -27
- package/hooks/itil-rfc-oversight-nudge.sh +7 -7
- package/hooks/itil-rfc-trailer-advisory.sh +28 -28
- package/hooks/itil-runtime-sid-marker.sh +11 -11
- package/hooks/itil-story-mirror-migration-nudge.sh +7 -7
- package/hooks/lib/block-list.sh +17 -17
- package/hooks/lib/changeset-detect.sh +27 -27
- package/hooks/lib/claude-space-gate.sh +23 -15
- package/hooks/lib/command-detect.sh +12 -12
- package/hooks/lib/create-gate.sh +9 -39
- package/hooks/lib/detectors.sh +12 -12
- package/hooks/lib/readme-refresh-detect.sh +51 -51
- package/hooks/lib/runtime-sid.sh +12 -12
- package/hooks/lib/session-id.sh +28 -28
- package/hooks/lib/session-marker.sh +1 -1
- package/hooks/lib/staging-detect.sh +13 -13
- package/hooks/manage-problem-enforce-create.sh +16 -27
- package/hooks/p057-staging-trap-detect.sh +18 -18
- package/hooks/pre-publish-intake-gate.sh +5 -5
- package/hooks/staleness-check.sh +6 -6
- package/hooks-codex/hooks.json +57 -0
- package/lib/check-deferred-placeholder-staleness.sh +10 -10
- package/lib/check-outbound-responses-staleness.sh +2 -2
- package/lib/check-upstream-cache-staleness.sh +2 -2
- package/lib/derive-first-dispatch.sh +19 -19
- package/lib/enumerate-postrelease-kv-candidates.sh +18 -18
- package/lib/migrate-problems-layout.sh +12 -12
- package/lib/story-oversight.sh +27 -27
- package/package.json +16 -3
- package/scripts/catchup-scan.sh +25 -25
- package/scripts/check-fail-soft-skip-discipline.sh +10 -10
- package/scripts/check-fix-rfc-trace.sh +8 -8
- package/scripts/check-locale-discipline.sh +13 -13
- package/scripts/check-problems-readme-budget.sh +12 -12
- package/scripts/check-rfc-has-stories.sh +7 -7
- package/scripts/check-rfc-rejected-alternatives.sh +11 -11
- package/scripts/check-rfc-stories-ratified.sh +9 -9
- package/scripts/check-ticket-jtbd-ratification.sh +10 -10
- package/scripts/check-upstream-responses.sh +22 -22
- package/scripts/classify-readme-drift.sh +13 -13
- package/scripts/codex-agent.mjs +104 -0
- package/scripts/derive-release-vehicle.sh +23 -23
- package/scripts/detect-unoversighted-rfcs.sh +3 -3
- package/scripts/detect-unratified-stories-maps.sh +5 -5
- package/scripts/effort-tally.sh +10 -10
- package/scripts/evaluate-relevance.sh +16 -16
- package/scripts/mark-create-gate.sh +4 -4
- package/scripts/mark-story-oversight-confirmed.sh +14 -14
- package/scripts/migrate-story-status-mirror.sh +6 -6
- package/scripts/next-rfc-id.sh +5 -5
- package/scripts/plugin-exercise-index.sh +26 -26
- package/scripts/plugin-maturity-populate.sh +38 -38
- package/scripts/plugin-maturity-render.sh +26 -26
- package/scripts/plugin-validate-ci-gate.sh +14 -14
- package/scripts/reconcile-readme.sh +23 -23
- package/scripts/reconcile-rfcs.sh +13 -13
- package/scripts/reconcile-stories.sh +12 -12
- package/scripts/reconcile-story-maps.sh +6 -6
- package/scripts/render-story-map.mjs +24 -24
- package/scripts/render-story-map.sh +3 -3
- package/scripts/resolve-governance-plugin-dirs.sh +10 -10
- package/scripts/run-check-deferred-placeholder-staleness.sh +3 -3
- package/scripts/run-check-outbound-responses-staleness.sh +3 -3
- package/scripts/run-check-upstream-cache-staleness.sh +3 -3
- package/scripts/run-enumerate-postrelease-kv-candidates.sh +3 -3
- package/scripts/run-migrate-problems-layout.sh +3 -3
- package/scripts/skill-invocations.sh +29 -29
- package/scripts/story-map-edit.mjs +6 -6
- package/scripts/story-map-edit.sh +3 -3
- package/scripts/story-map-query.mjs +8 -8
- package/scripts/story-map-query.sh +3 -3
- package/scripts/update-jtbd-references-section.sh +8 -8
- package/scripts/update-problem-references-section.sh +12 -12
- package/scripts/update-problem-rfcs-section.sh +9 -9
- package/scripts/update-rfc-commits-section.sh +7 -7
- package/scripts/update-rfc-references-section.sh +3 -3
- package/scripts/update-story-references-section.sh +5 -5
- package/scripts/verify-iter-summary.sh +3 -3
- package/skills/capture-problem/REFERENCE.md +33 -33
- package/skills/capture-problem/SKILL.md +108 -108
- package/skills/capture-problem/agents/openai.yaml +3 -0
- package/skills/capture-rfc/SKILL.md +21 -323
- package/skills/capture-rfc/agents/openai.yaml +3 -0
- package/skills/capture-story/SKILL.md +65 -65
- package/skills/capture-story/agents/openai.yaml +3 -0
- package/skills/capture-story-map/SKILL.md +31 -31
- package/skills/capture-story-map/agents/openai.yaml +3 -0
- package/skills/check-upstream-responses/SKILL.md +38 -38
- package/skills/check-upstream-responses/agents/openai.yaml +3 -0
- package/skills/close-incident/SKILL.md +25 -25
- package/skills/close-incident/agents/openai.yaml +3 -0
- package/skills/link-incident/SKILL.md +22 -22
- package/skills/link-incident/agents/openai.yaml +3 -0
- package/skills/list-incidents/SKILL.md +9 -9
- package/skills/list-incidents/agents/openai.yaml +3 -0
- package/skills/list-problems/SKILL.md +17 -17
- package/skills/list-problems/agents/openai.yaml +3 -0
- package/skills/list-stories/SKILL.md +23 -23
- package/skills/list-stories/agents/openai.yaml +3 -0
- package/skills/list-story-maps/SKILL.md +9 -9
- package/skills/list-story-maps/agents/openai.yaml +3 -0
- package/skills/manage-incident/SKILL.md +59 -59
- package/skills/manage-incident/agents/openai.yaml +3 -0
- package/skills/manage-problem/SKILL.md +222 -222
- package/skills/manage-problem/agents/openai.yaml +3 -0
- package/skills/manage-rfc/SKILL.md +62 -62
- package/skills/manage-rfc/agents/openai.yaml +3 -0
- package/skills/manage-story/SKILL.md +49 -49
- package/skills/manage-story/agents/openai.yaml +3 -0
- package/skills/manage-story-map/SKILL.md +30 -30
- package/skills/manage-story-map/agents/openai.yaml +3 -0
- package/skills/mitigate-incident/SKILL.md +40 -40
- package/skills/mitigate-incident/agents/openai.yaml +3 -0
- package/skills/reconcile-readme/SKILL.md +28 -28
- package/skills/reconcile-readme/agents/openai.yaml +3 -0
- package/skills/reconcile-stories/SKILL.md +17 -17
- package/skills/reconcile-stories/agents/openai.yaml +3 -0
- package/skills/reconcile-story-maps/SKILL.md +11 -11
- package/skills/reconcile-story-maps/agents/openai.yaml +3 -0
- package/skills/report-upstream/SKILL.md +73 -73
- package/skills/report-upstream/agents/openai.yaml +3 -0
- package/skills/restore-incident/SKILL.md +28 -28
- package/skills/restore-incident/agents/openai.yaml +3 -0
- package/skills/review-problems/SKILL.md +129 -129
- package/skills/review-problems/agents/openai.yaml +3 -0
- package/skills/scaffold-intake/SKILL.md +26 -26
- package/skills/scaffold-intake/agents/openai.yaml +3 -0
- package/skills/transition-problem/SKILL.md +85 -85
- package/skills/transition-problem/agents/openai.yaml +3 -0
- package/skills/transition-problems/SKILL.md +69 -69
- package/skills/transition-problems/agents/openai.yaml +3 -0
- package/skills/update-upstream/SKILL.md +97 -97
- package/skills/update-upstream/agents/openai.yaml +3 -0
- package/skills/work-problem/SKILL.md +42 -42
- package/skills/work-problem/agents/openai.yaml +3 -0
- package/skills/work-problems/SKILL.md +327 -327
- package/skills/work-problems/agents/openai.yaml +3 -0
- package/skills-codex/capture-problem/REFERENCE.md +139 -0
- package/skills-codex/capture-problem/SKILL.md +438 -0
- package/skills-codex/capture-problem/agents/openai.yaml +3 -0
- package/skills-codex/capture-rfc/SKILL.md +45 -0
- package/skills-codex/capture-rfc/agents/openai.yaml +3 -0
- package/skills-codex/capture-story/SKILL.md +407 -0
- package/skills-codex/capture-story/agents/openai.yaml +3 -0
- package/skills-codex/capture-story-map/SKILL.md +286 -0
- package/skills-codex/capture-story-map/agents/openai.yaml +3 -0
- package/skills-codex/check-upstream-responses/SKILL.md +160 -0
- package/skills-codex/check-upstream-responses/agents/openai.yaml +3 -0
- package/skills-codex/close-incident/SKILL.md +192 -0
- package/skills-codex/close-incident/agents/openai.yaml +3 -0
- package/skills-codex/link-incident/SKILL.md +173 -0
- package/skills-codex/link-incident/agents/openai.yaml +3 -0
- package/skills-codex/list-incidents/SKILL.md +92 -0
- package/skills-codex/list-incidents/agents/openai.yaml +3 -0
- package/skills-codex/list-problems/SKILL.md +126 -0
- package/skills-codex/list-problems/agents/openai.yaml +3 -0
- package/skills-codex/list-stories/SKILL.md +170 -0
- package/skills-codex/list-stories/agents/openai.yaml +3 -0
- package/skills-codex/list-story-maps/SKILL.md +104 -0
- package/skills-codex/list-story-maps/agents/openai.yaml +3 -0
- package/skills-codex/manage-incident/SKILL.md +378 -0
- package/skills-codex/manage-incident/agents/openai.yaml +3 -0
- package/skills-codex/manage-problem/SKILL.md +1180 -0
- package/skills-codex/manage-problem/agents/openai.yaml +3 -0
- package/skills-codex/manage-rfc/SKILL.md +314 -0
- package/skills-codex/manage-rfc/agents/openai.yaml +3 -0
- package/skills-codex/manage-story/SKILL.md +284 -0
- package/skills-codex/manage-story/agents/openai.yaml +3 -0
- package/skills-codex/manage-story-map/SKILL.md +198 -0
- package/skills-codex/manage-story-map/agents/openai.yaml +3 -0
- package/skills-codex/mitigate-incident/SKILL.md +239 -0
- package/skills-codex/mitigate-incident/agents/openai.yaml +3 -0
- package/skills-codex/reconcile-readme/SKILL.md +175 -0
- package/skills-codex/reconcile-readme/agents/openai.yaml +3 -0
- package/skills-codex/reconcile-stories/SKILL.md +124 -0
- package/skills-codex/reconcile-stories/agents/openai.yaml +3 -0
- package/skills-codex/reconcile-story-maps/SKILL.md +81 -0
- package/skills-codex/reconcile-story-maps/agents/openai.yaml +3 -0
- package/skills-codex/report-upstream/SKILL.md +716 -0
- package/skills-codex/report-upstream/agents/openai.yaml +3 -0
- package/skills-codex/restore-incident/SKILL.md +216 -0
- package/skills-codex/restore-incident/agents/openai.yaml +3 -0
- package/skills-codex/review-problems/SKILL.md +524 -0
- package/skills-codex/review-problems/agents/openai.yaml +3 -0
- package/skills-codex/scaffold-intake/SKILL.md +209 -0
- package/skills-codex/scaffold-intake/agents/openai.yaml +3 -0
- package/skills-codex/scaffold-intake/templates/CONTRIBUTING.md.tmpl +31 -0
- package/skills-codex/scaffold-intake/templates/SECURITY.md.tmpl +39 -0
- package/skills-codex/scaffold-intake/templates/SUPPORT.md.tmpl +32 -0
- package/skills-codex/scaffold-intake/templates/config.yml.tmpl +8 -0
- package/skills-codex/scaffold-intake/templates/problem-report.yml.tmpl +114 -0
- package/skills-codex/transition-problem/SKILL.md +371 -0
- package/skills-codex/transition-problem/agents/openai.yaml +3 -0
- package/skills-codex/transition-problems/SKILL.md +310 -0
- package/skills-codex/transition-problems/agents/openai.yaml +3 -0
- package/skills-codex/update-upstream/SKILL.md +583 -0
- package/skills-codex/update-upstream/agents/openai.yaml +3 -0
- package/skills-codex/work-problem/SKILL.md +160 -0
- package/skills-codex/work-problem/agents/openai.yaml +3 -0
- package/skills-codex/work-problems/SKILL.md +58 -0
- package/skills-codex/work-problems/agents/openai.yaml +3 -0
- package/templates/story-map.css +1 -1
- package/bin/wr-itil-mark-rfc-capture-gate +0 -51
- package/scripts/mark-rfc-capture-gate.sh +0 -32
|
@@ -11,13 +11,13 @@ Create, update, or transition problem tickets following an ITIL-aligned problem
|
|
|
11
11
|
|
|
12
12
|
## Output Formatting
|
|
13
13
|
|
|
14
|
-
When referencing problem IDs, ADR IDs, or JTBD IDs in prose output, always include the human-readable title on first mention. Use the format `
|
|
14
|
+
When referencing problem IDs, ADR IDs, or JTBD IDs in prose output, always include the human-readable title on first mention. Use the format `the "Problem 029: Edit gate overhead disproportionate for governance documentation changes" problem (Edit gate overhead for governance docs)`, not bare `the "Problem 029: Edit gate overhead disproportionate for governance documentation changes" problem`. Tables with separate ID and Title columns are fine as-is.
|
|
15
15
|
|
|
16
|
-
**Brief-before-ID discipline at `AskUserQuestion` surfaces (
|
|
16
|
+
**Brief-before-ID discipline at `AskUserQuestion` surfaces (the "agent surfaces decisions to user using opaque IDs (P-numbers, ADR-numbers, JTBD-numbers) without explaining what they mean — empathy gap" problem).** Title-on-first-mention is the minimum for prose output. For `AskUserQuestion` question/option/description text the rule is stricter: brief the artefact's purpose and substance BEFORE naming it by ID. `P-NNN` / `ADR-NNN` / `JTBD-NNN` / `RFC-NNN` references are audit-trail annotations, NEVER carriers of meaning — the user reads the prompt without project filesystem access (mobile clients, accessibility tooling, notification surfaces) and cannot follow links. Every option's substance MUST be self-contained in the briefing prose + the option `label` and `description`; IDs may appear ONLY after a self-contained explanation. Mirrors the canonical `/wr-architect:create-adr` Step 5 § 5a Rule 3 ("No IDs as explainers"). Applies to Step 4b's fix-strategy and verification dispatches and any other `AskUserQuestion` site emitted by this skill. See also session memory `feedback_brief_before_id.md`.
|
|
17
17
|
|
|
18
|
-
## First-run intake-scaffold pointer (
|
|
18
|
+
## First-run intake-scaffold pointer (the "Problem 065: No skill scaffolds intake files (ISSUE_TEMPLATE, SECURITY.md, CONTRIBUTING.md, SUPPORT.md) in downstream projects" problem / the "Scaffold downstream OSS intake — skill + layered triggers" architecture rule)
|
|
19
19
|
|
|
20
|
-
This skill is one of the two host skills wired to surface the [`/wr-itil:scaffold-intake`](../scaffold-intake/SKILL.md) skill on first invocation in a project that has not yet adopted the OSS intake surface. The contract is documented in [
|
|
20
|
+
This skill is one of the two host skills wired to surface the [`/wr-itil:scaffold-intake`](../scaffold-intake/SKILL.md) skill on first invocation in a project that has not yet adopted the OSS intake surface. The contract is documented in [the "Scaffold downstream OSS intake — skill + layered triggers" architecture rule](../../../../docs/decisions/036-scaffold-downstream-oss-intake.proposed.md) (Scaffold downstream OSS intake — skill + layered triggers).
|
|
21
21
|
|
|
22
22
|
**Preamble check** (run before Step 0 of any operation):
|
|
23
23
|
|
|
@@ -29,10 +29,10 @@ If any intake file is missing AND both markers are absent, surface the scaffold-
|
|
|
29
29
|
|
|
30
30
|
| Mode | Behaviour |
|
|
31
31
|
|---|---|
|
|
32
|
-
| **Foreground (interactive)** | Fire one-shot `AskUserQuestion` per
|
|
33
|
-
| **AFK orchestrator (Rule 6 fail-safe)** | Do **not** fire `AskUserQuestion`. Append a one-line `"pending intake scaffold"` note to the iteration's `ITERATION_SUMMARY` notes field. Do **not** auto-scaffold —
|
|
32
|
+
| **Foreground (interactive)** | Fire one-shot `AskUserQuestion` per the "Structured User Interaction for Governance-Skill Decisions" architecture rule Rule 1: header `"Scaffold OSS intake?"`, three options — **Scaffold now** (delegate to `/wr-itil:scaffold-intake`), **Not now (ask again next session)** (no marker; re-prompt next time), **Decline (never prompt in this project)** (write `.claude/.intake-scaffold-declined`). |
|
|
33
|
+
| **AFK orchestrator (Rule 6 fail-safe)** | Do **not** fire `AskUserQuestion`. Append a one-line `"pending intake scaffold"` note to the iteration's `ITERATION_SUMMARY` notes field. Do **not** auto-scaffold — the ": Progress the Backlog While I'm Away" user outcome forbids the agent from making this judgement call. The user catches up on next interactive session. |
|
|
34
34
|
|
|
35
|
-
The preamble check is a one-shot; the `.intake-scaffold-done` and `.intake-scaffold-declined` markers (
|
|
35
|
+
The preamble check is a one-shot; the `.intake-scaffold-done` and `.intake-scaffold-declined` markers (the "Gate Marker Lifecycle: TTL + Drift, Not Stop-Hook Reset" architecture rule persistent-marker semantics) suppress re-prompts in subsequent sessions without TTL expiry.
|
|
36
36
|
|
|
37
37
|
## Operations
|
|
38
38
|
|
|
@@ -43,12 +43,12 @@ The preamble check is a one-shot; the `.intake-scaffold-done` and `.intake-scaff
|
|
|
43
43
|
- **Work**: `problem work` — runs a review first, then begins working the highest-WSJF problem
|
|
44
44
|
- **Review**: `problem review` — re-assess all open problems: update priorities per RISK-POLICY.md, estimate effort, calculate WSJF, and update files
|
|
45
45
|
|
|
46
|
-
**Closing problems:** Problems are closed ONLY after the user verifies the fix in production — not when the fix is committed or released. The workflow (per
|
|
47
|
-
1. When the fix is released: `git mv` the file from `.known-error.md` to `.verifying.md`, update the Status field to "Verification Pending", AND add a `## Fix Released` section (e.g., `Deployed in v0.26.X. Awaiting user verification.`). All three edits land in the same commit per
|
|
48
|
-
2. When the user explicitly confirms ("it's fixed", "verified", "working"): `git mv` from `.verifying.md` to `.closed.md`, update the Status field to "Closed", and reference the problem in the commit message (e.g., "Closes
|
|
46
|
+
**Closing problems:** Problems are closed ONLY after the user verifies the fix in production — not when the fix is committed or released. The workflow (per the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule):
|
|
47
|
+
1. When the fix is released: `git mv` the file from `.known-error.md` to `.verifying.md`, update the Status field to "Verification Pending", AND add a `## Fix Released` section (e.g., `Deployed in v0.26.X. Awaiting user verification.`). All three edits land in the same commit per the "Governance Skills Commit Their Own Completed Work" architecture rule.
|
|
48
|
+
2. When the user explicitly confirms ("it's fixed", "verified", "working"): `git mv` from `.verifying.md` to `.closed.md`, update the Status field to "Closed", and reference the problem in the commit message (e.g., "Closes the "Problem 008: AskUserQuestion Unavailable When --channels Is Active" problem").
|
|
49
49
|
3. Never assume the fix works — always wait for explicit user confirmation before closing.
|
|
50
50
|
|
|
51
|
-
The `.verifying.md` suffix distinguishes "fix released, awaiting user verification" from "root cause identified AND workaround documented; fix not yet proposed" (the Known Error meaning per
|
|
51
|
+
The `.verifying.md` suffix distinguishes "fix released, awaiting user verification" from "root cause identified AND workaround documented; fix not yet proposed" (the Known Error meaning per the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule corrected semantics, 2026-06-08 amendment; the fix proposal happens AFTER Known Error and draws a release row on a story map). See the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule for rationale.
|
|
52
52
|
|
|
53
53
|
## Problem Lifecycle
|
|
54
54
|
|
|
@@ -56,12 +56,12 @@ The `.verifying.md` suffix distinguishes "fix released, awaiting user verificati
|
|
|
56
56
|
|--------|-----------|---------|----------------|
|
|
57
57
|
| **Open** | `.open.md` | Reported, under investigation | New problem identified |
|
|
58
58
|
| **Known Error** | `.known-error.md` | Root cause identified AND workaround documented; **fix not yet proposed** (the fix proposal draws a release row on a story map) | Root cause documented, reproduction test exists, workaround in place |
|
|
59
|
-
| **Verification Pending** | `.verifying.md` | Fix released, awaiting user verification (
|
|
59
|
+
| **Verification Pending** | `.verifying.md` | Fix released, awaiting user verification (the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule) | Fix shipped; `## Fix Released` section written; user action remaining |
|
|
60
60
|
| **Parked** | `.parked.md` | Blocked on upstream or suspended by user decision | Upstream blocker identified, or user explicitly suspends; reason and un-park trigger documented |
|
|
61
|
-
| **Closed** | `.closed.md` | Fix verified in production OR ticket determined no longer relevant via evidence | (a) User explicitly confirms the released fix works (canonical Verifying → Closed path), OR (b) auto-closed by `/wr-itil:review-problems` Step 4.6 relevance-close pass per ADR-
|
|
61
|
+
| **Closed** | `.closed.md` | Fix verified in production OR ticket determined no longer relevant via evidence | (a) User explicitly confirms the released fix works (canonical Verifying → Closed path), OR (b) auto-closed by `/wr-itil:review-problems` Step 4.6 relevance-close pass per the "Evidence-based relevance-close pass for the problem backlog (Phase 1: file-no-longer-exists; Phase 2: ADR-shipped-confirmed + named-skill-exists + self-marker-in-body + driver-child-closed + Phase 1 false-positive fixes)" architecture rule Phase 1 + Phase 2 evidence shapes — `file-no-longer-exists` / `ADR-shipped-confirmed` / `named-skill-or-feature-exists` / `self-marker-in-body` / `driver-child-ticket-closed` (cumulative; multi-shape matches emit comma-joined) with `## Closed as no longer relevant` audit section per the "Agent output grounding — no fabricated quantitative estimates, cite + persist + uncertainty" architecture rule grounding (extends the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule lifecycle: Open\|Known Error → Closed bypasses Verifying when no fix was released). Partial-scope umbrellas emit `CLOSE-CANDIDATE-WITH-CAVEAT` and ride the maintainer's `AskUserQuestion` surface-batch-confirm path. |
|
|
62
62
|
|
|
63
63
|
**Parked problems** are excluded from WSJF ranking and work selection. They are listed separately in review output so users can see them without them polluting the backlog. To park a problem:
|
|
64
|
-
1. **If the park reason is `upstream-blocked`**, run the external-root-cause detection block at Step 7 first (see "External-root-cause detection (
|
|
64
|
+
1. **If the park reason is `upstream-blocked`**, run the external-root-cause detection block at Step 7 first (see "External-root-cause detection (the "Problem 063: manage-problem does not trigger /wr-itil:report-upstream when root cause is external" problem)"). Park without recording the upstream dependency in `## Related` would be the canonical audit-trail gap this block closes.
|
|
65
65
|
2. `git mv docs/problems/<current>/<NNN>-<title>.md docs/problems/parked/<NNN>-<title>.md`
|
|
66
66
|
3. Update the Status field to "Parked"
|
|
67
67
|
4. Add a `## Parked` section with: reason for parking, expected trigger to un-park, date parked
|
|
@@ -70,7 +70,7 @@ To un-park: `git mv` back to `docs/problems/open/<NNN>-<title>.md` (or `docs/pro
|
|
|
70
70
|
|
|
71
71
|
**Verification Pending problems** are also excluded from WSJF ranking — their remaining work is user-side verification, not dev effort. They appear in a dedicated "Verification Queue" section in review output so the user can see what's waiting on them without mixing with dev-work ranking. See step 9c for the queue layout.
|
|
72
72
|
|
|
73
|
-
**Allowed optional appendages**: a problem ticket file may carry a `## Reported Upstream` section appended after the standard sections. This is written by the `/wr-itil:report-upstream` skill (per
|
|
73
|
+
**Allowed optional appendages**: a problem ticket file may carry a `## Reported Upstream` section appended after the standard sections. This is written by the `/wr-itil:report-upstream` skill (per the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule Confirmation criterion 3a) and records the upstream URL — an issue, a pull request (per the "Prefer an upstream pull request over an issue when the upstream accepts pull requests" architecture rule), or an advisory — plus the matched template and the disclosure path. The presence or absence of this section does not affect WSJF ranking or status transitions.
|
|
74
74
|
|
|
75
75
|
**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.
|
|
76
76
|
|
|
@@ -91,7 +91,7 @@ Problems are ranked using Weighted Shortest Job First (WSJF):
|
|
|
91
91
|
| Verification Pending | 0 (excluded) |
|
|
92
92
|
| Parked | 0 (excluded) |
|
|
93
93
|
|
|
94
|
-
`Verification Pending` and `Parked` tickets are excluded from the main dev-work ranking per
|
|
94
|
+
`Verification Pending` and `Parked` tickets are excluded from the main dev-work ranking per the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule (verification) and the Parked policy above. `Verification Pending` remaining work is user-side confirmation, not dev effort, so mixing it into the dev-work queue would distort WSJF. Both are surfaced in dedicated sections (see step 9c) — not in the ranked table.
|
|
95
95
|
|
|
96
96
|
**Effort** (estimated fix size — smaller effort = higher priority):
|
|
97
97
|
|
|
@@ -113,9 +113,9 @@ WSJF = (8 × 1.0) / 8 = **1.0** — defer until severity climbs or scope shrinks
|
|
|
113
113
|
|
|
114
114
|
When estimating effort, read the problem's root cause analysis and fix strategy. If effort is unknown, default to M (2). Effort is a **live estimate**, not a set-once label: re-rate it when root cause is confirmed, when architect review narrows or expands scope, and during each `manage-problem review`. A note capturing the reason for any bucket change makes the ranking audit-able (see steps 7 and 9b).
|
|
115
115
|
|
|
116
|
-
### Transitive dependencies (
|
|
116
|
+
### Transitive dependencies (the "Problem 076: WSJF scoring in manage-problem does not model transitive dependencies" problem)
|
|
117
117
|
|
|
118
|
-
> **Serves**:
|
|
118
|
+
> **Serves**: the ": Enforce Governance Without Slowing Down" user outcome (enforce governance without slowing down — queue must not lie), the ": Progress the Backlog While I'm Away" user outcome (progress the backlog while I'm away — AFK orchestrator iterates top-down on a trustworthy rank), the "Restore Service Fast with an Audit Trail" user outcome (restore service fast with an audit trail — ranking decisions must be defensible post-hoc).
|
|
119
119
|
|
|
120
120
|
Effort is scored per-ticket as a **marginal** estimate (the work this ticket adds on top of its upstream dependencies). When a ticket has upstream dependencies — other tickets that must close first before this one can reach "done" — the ticket's effective effort for WSJF purposes is the **transitive closure** of its marginal effort plus all blocking upstreams, not the marginal alone.
|
|
121
121
|
|
|
@@ -136,22 +136,22 @@ A dependent ticket cannot reach its "done" state without the upstream work happe
|
|
|
136
136
|
|
|
137
137
|
**Upstream status carve-out**: an upstream ticket in `.closed.md`, `.verifying.md`, or `.parked.md` contributes **0** to the transitive closure. Closed upstream work is done; verifying upstream work is user-side (not dev effort and excluded from dev ranking per the WSJF multiplier table); parked upstream work is suspended (excluded from ranking until un-parked). Without this carve-out, a ticket blocked by a closed ticket would inherit XL forever.
|
|
138
138
|
|
|
139
|
-
**Cycle handling**: when two or more tickets mutually block each other (e.g., shared gate-surface tickets that each list the other under `**Blocked by**`), treat the strongly-connected component as a **bundle**. The bundle's effective effort is `max{ marginal | members }`. All bundle members surface the same WSJF in review output — the shared WSJF is a **computed artefact** of the rendering, not written as a field into individual ticket files. Bundle members retain their individual Status suffixes and individual ticket files (
|
|
139
|
+
**Cycle handling**: when two or more tickets mutually block each other (e.g., shared gate-surface tickets that each list the other under `**Blocked by**`), treat the strongly-connected component as a **bundle**. The bundle's effective effort is `max{ marginal | members }`. All bundle members surface the same WSJF in review output — the shared WSJF is a **computed artefact** of the rendering, not written as a field into individual ticket files. Bundle members retain their individual Status suffixes and individual ticket files (the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule suffix-based lifecycle).
|
|
140
140
|
|
|
141
141
|
**Re-rate on upstream status change**: when a dependency transitions to `.closed.md` / `.verifying.md` / `.parked.md`, the dependent ticket's transitive closure shrinks and the effort drops accordingly. Step 9b catches this automatically — no transition-time graph re-walk is required.
|
|
142
142
|
|
|
143
|
-
**Worked example**:
|
|
143
|
+
**Worked example**: the "Problem 073: No voice-and-tone check or risk assessment on changeset bodies (which populate CHANGELOG.md, Release PRs, GitHub Releases, and npm release notes)" problem has marginal effort S (one surface-row add). the "Problem 073: No voice-and-tone check or risk assessment on changeset bodies (which populate CHANGELOG.md, Release PRs, GitHub Releases, and npm release notes)" problem is blocked by the "Problem 038: No voice-and-tone gate on external communications" problem (XL). Then:
|
|
144
144
|
|
|
145
145
|
```
|
|
146
|
-
Effort(
|
|
147
|
-
WSJF(
|
|
146
|
+
Effort(the "Problem 073: No voice-and-tone check or risk assessment on changeset bodies (which populate CHANGELOG.md, Release PRs, GitHub Releases, and npm release notes)" problem)_transitive = max(S=1, Effort(the "Problem 038: No voice-and-tone gate on external communications" problem)_transitive) = max(1, 8) = 8
|
|
147
|
+
WSJF(the "Problem 073: No voice-and-tone check or risk assessment on changeset bodies (which populate CHANGELOG.md, Release PRs, GitHub Releases, and npm release notes)" problem) = (Severity(the "Problem 073: No voice-and-tone check or risk assessment on changeset bodies (which populate CHANGELOG.md, Release PRs, GitHub Releases, and npm release notes)" problem) × 1.0) / 8 = 12 / 8 = 1.5
|
|
148
148
|
```
|
|
149
149
|
|
|
150
|
-
|
|
150
|
+
the "Problem 073: No voice-and-tone check or risk assessment on changeset bodies (which populate CHANGELOG.md, Release PRs, GitHub Releases, and npm release notes)" problem's WSJF matches the "Problem 038: No voice-and-tone gate on external communications" problem's by construction — the "Problem 073: No voice-and-tone check or risk assessment on changeset bodies (which populate CHANGELOG.md, Release PRs, GitHub Releases, and npm release notes)" problem cannot out-rank the ticket whose work is strictly contained within it. Contrast with the marginal-only (incorrect) computation: `12 / 2 = 6.0`, which would mis-rank the "Problem 073: No voice-and-tone check or risk assessment on changeset bodies (which populate CHANGELOG.md, Release PRs, GitHub Releases, and npm release notes)" problem as "top of queue" despite being blocked.
|
|
151
151
|
|
|
152
152
|
**Determinism**: the rule is deterministic from the graph — no `AskUserQuestion` branch is required when Step 9b re-rates a ticket. The re-rate fires silently and is logged in the review output per the Step 9b re-rate message format.
|
|
153
153
|
|
|
154
|
-
**Reassessment criteria**: this rule lives inline in manage-problem's SKILL.md (following
|
|
154
|
+
**Reassessment criteria**: this rule lives inline in manage-problem's SKILL.md (following the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule's precedent for inline WSJF additions). If a second skill (e.g., manage-incident or a future cross-plugin `work-backlog` orchestrator) adopts the `## Dependencies` section and the transitive-effort rule, extract to a sibling ADR at that point — wider adoption justifies the ADR cost that today's single-skill scope does not.
|
|
155
155
|
|
|
156
156
|
## Working a Problem
|
|
157
157
|
|
|
@@ -169,24 +169,24 @@ What "work" means depends on the problem's status:
|
|
|
169
169
|
|
|
170
170
|
**Known Error (root cause identified AND workaround documented; ready for fix proposal):**
|
|
171
171
|
|
|
172
|
-
**Substance-confirm-before-build guard (
|
|
172
|
+
**Substance-confirm-before-build guard (the ": Confirm a decision's substance before building dependent work on it" architecture rule — propose-fix surface, the "Problem-RFC-Story framework with mandatory problem-trace and unified problem ontology" architecture rule I13).** BEFORE implementing any fix step below, check whether the fix builds on a genuine decision whose **substance is unconfirmed**. This closes the "Agent implements dependent work on genuine new decisions before human-confirming their SUBSTANCE — surfaces only meta-questions" problem (dependent work built on a born-`proposed` decision the user later rejects):
|
|
173
173
|
|
|
174
174
|
1. Collect the decisions this fix builds on: the `ADR-NNN` references in the problem's `## Fix Strategy` section PLUS the `adrs:` frontmatter array (and body `ADR-NNN` mentions) of each referenced RFC.
|
|
175
|
-
2. For each, run the predicate (PATH shim per
|
|
175
|
+
2. For each, run the predicate (PATH shim per the "Plugin-bundled scripts invoked from SKILL.md resolve via `bin/` on `$PATH`" architecture rule — adopter-safe, never source repo-relative lib files):
|
|
176
176
|
```bash
|
|
177
177
|
wr-architect-is-decision-unconfirmed ADR-<NNN> docs/decisions
|
|
178
178
|
```
|
|
179
179
|
Exit 0 = unconfirmed (born without `human-oversight: confirmed`, not superseded) → the guard fires for that ADR. Exit 1 = confirmed or superseded → OK to build. Exit 2 = not found → treat as not-a-blocker (surface in the report).
|
|
180
180
|
3. **If any referenced decision is unconfirmed**: do NOT implement yet. Surface its **substance** (the chosen option the ADR records — not a grain/meta question) for human confirmation:
|
|
181
|
-
- **Interactive**: `AskUserQuestion` presenting the ADR's Decision Outcome + Considered Options so the user confirms / amends / rejects the substantive choice. On confirm, the recording skill writes the `human-oversight: confirmed` marker (
|
|
182
|
-
- **AFK** (`/wr-itil:work-problems` orchestrator): NEVER ask mid-loop — queue the substance to the iteration's `outstanding_questions` (
|
|
183
|
-
4. This ask is **
|
|
181
|
+
- **Interactive**: `AskUserQuestion` presenting the ADR's Decision Outcome + Considered Options so the user confirms / amends / rejects the substantive choice. On confirm, the recording skill writes the `human-oversight: confirmed` marker (the ": Human-oversight marker + `/wr-architect:review-decisions` drain for recorded decisions" architecture rule) before the build proceeds.
|
|
182
|
+
- **AFK** (`/wr-itil:work-problems` orchestrator): NEVER ask mid-loop — queue the substance to the iteration's `outstanding_questions` (the "— Decision-Delegation Contract: when agents act on the framework vs ask the user" architecture rule AFK carve-out) and skip the build; do not guess. This is the **queue-and-continue** universal default per the "Structured User Interaction for Governance-Skill Decisions" architecture rule Rule 6 (the "AFK iter default when a skill needs to ask a question and AskUserQuestion is unavailable — should queue the question and move to the next iteration (not halt, not silently skip)" problem, 2026-06-06 amendment): the iter queues the substance + advances; the orchestrator main turn surfaces the queued question at loop end via the Step 2.5 batched AskUserQuestion.
|
|
183
|
+
4. This ask is **the "— Decision-Delegation Contract: when agents act on the framework vs ask the user" architecture rule category-1 direction-setting** and is EXCLUDED from the lazy-AskUserQuestion regression metric (it is legitimate, not lazy). The trigger is narrow — detection is mechanical (the predicate); only genuine unconfirmed decisions about to be built on fire it. Do NOT over-fire on confirmed/superseded/obvious decisions (inverse-the "Problem 078: Assistant does not offer to capture a problem ticket when the user delivers strong-signal correction" problem / the "Agents over-ask in interactive sessions — conflating mechanical-stages with user-interactive-stages of multi-stage skill contracts (inverse-)" problem guard). A born-`proposed` marker is fine for *recording*; it is not a licence to *build* (the ": Human-oversight marker + `/wr-architect:review-decisions` drain for recorded decisions" architecture rule carve-out).
|
|
184
184
|
|
|
185
|
-
**I13 propose-fix trace gate (RFC-
|
|
185
|
+
**I13 propose-fix trace gate (the ": RFC-first trace invariant not enforced at fix-time" release design B3/B4).** BEFORE the traversal below, enforce the fix-time trace invariant: a fix proposed on a Known Error requires a fix vehicle that traces the problem (the "Every fix goes through an RFC" architecture rule unconditional; the "RFC required at the propose-fix step on a Known Error" architecture rule places the gate here, conforming to the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule Known Error semantics — the fix is proposed *after* Known Error).
|
|
186
186
|
|
|
187
187
|
**A fix proposal is a release row on a story map. It is never a new document under `docs/rfcs/`.** The row carries the RFC identity, and the map is where a person approves the work; a fix written up as its own document reaches neither. The documents already on disk stay readable and keep working — they simply stop being the thing a fix proposal creates, and each converts to a row when its own problem is next worked.
|
|
188
188
|
|
|
189
|
-
Run the load-bearing predicate (
|
|
189
|
+
Run the load-bearing predicate (the "Plugin-bundled scripts invoked from SKILL.md resolve via `bin/` on `$PATH`" architecture rule `$PATH` shim — never repo-relative from a SKILL):
|
|
190
190
|
|
|
191
191
|
```bash
|
|
192
192
|
wr-itil-check-fix-rfc-trace <problem-file>
|
|
@@ -196,12 +196,12 @@ wr-itil-check-fix-rfc-trace <problem-file>
|
|
|
196
196
|
- **Exit 3** (the predicate refuses to answer, and says which of two reasons on stdout):
|
|
197
197
|
- **A map was edited without being re-rendered.** Mechanical, and nobody is asked about it: re-render the maps the directive names with `wr-itil-render-story-map <map.html>`, then run the predicate again. Escalate only if a clean re-render still refuses.
|
|
198
198
|
- **The repository holds no story maps at all.** Drawing the first map for a journey decides what that journey *is*, so it needs a person and must not be created automatically. Record **one** item — draw a story map covering this work — and carry on to the next problem. Interactively that is an `AskUserQuestion`; under the AFK orchestrator it is a single `outstanding_questions` entry. Do not stop the loop.
|
|
199
|
-
- **Exit 0, non-empty stdout** (directive `no-rfc-trace: P<NNN> …`): nothing proposes a fix yet. The predicate has confirmed only that *no row and no document names this PID* — it has NOT decided that no fix vehicle exists. Distinguish **two sub-cases** before acting (
|
|
199
|
+
- **Exit 0, non-empty stdout** (directive `no-rfc-trace: P<NNN> …`): nothing proposes a fix yet. The predicate has confirmed only that *no row and no document names this PID* — it has NOT decided that no fix vehicle exists. Distinguish **two sub-cases** before acting (the "manage-problem I13 propose-fix gate auto-creates a new RFC instead of wiring an existing fix-vehicle's trace edge" problem — the auto-draw below is intended ONLY when no fix vehicle exists, NOT when an existing vehicle merely lacks the trace edge — architect-confirmed):
|
|
200
200
|
- **(a) Existing-vehicle-untraced — a vehicle is already this ticket's fix but just hasn't wired the trace edge.** Read the ticket's `## Fix Strategy` / `## Resolution` / `## Dependencies` / `## Related` sections for an RFC cited as the **fix vehicle** — i.e. the fix IS that RFC's task set (the recurring shape: a rework / follow-on Known Error whose fix is an existing vehicle's remaining tasks, so that vehicle's trace names the *original driver* problem, not this ticket). This is a **judgement read of the citation context, NOT a blind "any cited RFC" match**: an RFC named only as context / `composes with` / `**Related**` background is NOT a fix vehicle — wiring its trace edge would pollute its trace. If a genuine existing fix vehicle is found:
|
|
201
201
|
- **If it is a release row**, add a story card to that row for this ticket's fix and make the card's story file name `P<NNN>` in its own `problems:` list. That card IS the trace edge; the link from a row to a problem is read through its cards, so there is nothing else to wire.
|
|
202
202
|
- **If it is a legacy document**, wire this problem into its frontmatter `problems:` array (Edit the `problems: [...]` line to include `P<NNN>` + a short inline `**Problems**:` body annotation noting the edge was wired because the vehicle already exists). This is the one edit a legacy document still takes, and only because the vehicle predates the row model; do not author new scope into it.
|
|
203
|
-
Then run `wr-itil-update-problem-rfcs-section <problem-file>` so the ticket's derived `## RFCs` section reflects the wired trace, re-run the predicate (now empty) and proceed. Do **NOT** draw a second vehicle — a duplicate fragments the fix across two traces (the exact
|
|
204
|
-
- **(b) No-vehicle — nothing is this ticket's fix vehicle yet. Draw the release row.** Do NOT block, do NOT skip, and do NOT ask: this is framework-mediated, not direction-setting, and drawing a row onto a map a person has already approved inherits that approval rather than needing a fresh one. NO `AskUserQuestion` consent gate fires on this path (
|
|
203
|
+
Then run `wr-itil-update-problem-rfcs-section <problem-file>` so the ticket's derived `## RFCs` section reflects the wired trace, re-run the predicate (now empty) and proceed. Do **NOT** draw a second vehicle — a duplicate fragments the fix across two traces (the exact the "manage-problem I13 propose-fix gate auto-creates a new RFC instead of wiring an existing fix-vehicle's trace edge" problem defect). Structured-log the wire event (e.g. `I13: wired P<NNN> trace edge into existing fix vehicle <ID>`) to the iter summary `notes` for the ": Progress the Backlog While I'm Away" user outcome audit trail.
|
|
204
|
+
- **(b) No-vehicle — nothing is this ticket's fix vehicle yet. Draw the release row.** Do NOT block, do NOT skip, and do NOT ask: this is framework-mediated, not direction-setting, and drawing a row onto a map a person has already approved inherits that approval rather than needing a fresh one. NO `AskUserQuestion` consent gate fires on this path (the "Agents over-ask in interactive sessions — conflating mechanical-stages with user-interactive-stages of multi-stage skill contracts (inverse-)" problem / inverse-the "Problem 078: Assistant does not offer to capture a problem ticket when the user delivers strong-signal correction" problem; the "— Decision-Delegation Contract: when agents act on the framework vs ask the user" architecture rule framework-resolution boundary).
|
|
205
205
|
|
|
206
206
|
1. Pick a story map that **already covers this journey** — right persona, and its job traces already include the job this fix's story serves.
|
|
207
207
|
2. Take the identity the predicate's directive named. Do not compute one yourself: `wr-itil-next-rfc-id` is the single definition, and it is the only rule that sees rows, documents and git history at once. A rule that reads only the document directory re-issues an identity a row already holds.
|
|
@@ -221,22 +221,22 @@ wr-itil-check-fix-rfc-trace <problem-file>
|
|
|
221
221
|
|
|
222
222
|
Interactively, surface the queued item via `AskUserQuestion`. Under the AFK orchestrator, queue it at `outstanding_questions` and move to the next problem — never ask mid-loop.
|
|
223
223
|
|
|
224
|
-
The predicate is the load-bearing detection half (committed shell + behavioural bats per
|
|
224
|
+
The predicate is the load-bearing detection half (committed shell + behavioural bats per the "Behavioural-tests-default for skill testing" architecture rule: `packages/itil/scripts/test/check-fix-rfc-trace.bats`), and it reads BOTH tiers — a release row's cards and a legacy document's `problems:` array — so repointing it cannot hard-stop work that used to proceed. This gate fires at **every** fix-time surface; the AFK `/wr-itil:work-problems` orchestrator dispatches its fix work *through this same manage-problem traversal*, so the gate covers the AFK surface transitively.
|
|
225
225
|
|
|
226
|
-
The Phase 2 working-the-problem traversal makes "implement the fix" concretely traceable via stories (per
|
|
226
|
+
The Phase 2 working-the-problem traversal makes "implement the fix" concretely traceable via stories (per the "Problem-RFC-Story framework with mandatory problem-trace and unified problem ontology" architecture rule lines 300-320). Replaces the prior vague "implement the fix following the project's development workflow" with a deterministic problem → RFC → story dispatch:
|
|
227
227
|
|
|
228
228
|
1. **Read the problem's `## Fix Strategy` section** — extract referenced RFC IDs (anchor links / inline references like `RFC-NNN`). The I13 gate above has already guaranteed a vehicle traces the problem; if the `## Fix Strategy` prose itself references none (a row drawn moments ago may not yet be cited inline), fall through to the legacy direct-implementation path (step 6 below) using the row the gate just drew, or the vehicle it found.
|
|
229
|
-
2. **For each referenced RFC** (in the order they appear in the Fix Strategy section), read its frontmatter `stories:` array (per
|
|
229
|
+
2. **For each referenced RFC** (in the order they appear in the Fix Strategy section), read its frontmatter `stories:` array (per the "Problem-RFC-Story framework with mandatory problem-trace and unified problem ontology" architecture rule line 259, the array is ORDERED — array position IS execution sequence):
|
|
230
230
|
- **Non-empty `stories:` array** (story-decomposed RFC): pick the first story whose lifecycle status is `accepted` or `in-progress` — skip `done` stories that already shipped, skip `draft` stories that aren't ready (the `manage-story <NNN> accepted` gate enforces INVEST shape; a draft story is structurally unready). Continue to step 3.
|
|
231
|
-
- **Empty `stories: []`** (a **legacy** pre-
|
|
231
|
+
- **Empty `stories: []`** (a **legacy** pre-the "Every RFC has at least one story" architecture rule RFC, or one not yet decomposed): per **the "Every RFC has at least one story" architecture rule** every RFC has ≥1 story — an empty `stories:` is a **back-fill** state, NOT a legitimate atomic shape. Back-fill the fix's story onto the RFC's story map (add ≥1 story, transition it `accepted` via `manage-story`), then re-traverse from step 2. The empty-stories atomic fallback is removed — do NOT close the problem on a story-less RFC.
|
|
232
232
|
3. **Read the picked story's body** — `## User value` statement (INVEST Valuable), `## Acceptance criteria` (INVEST Testable observable behaviours), `## Implementation notes` (architecture sketches, library decisions). The story's frontmatter `estimated-effort` field (set at `manage-story accepted` transition per I10 INVEST Estimable) sets the appetite for the iteration.
|
|
233
|
-
4. **Implement the story scope** — follow the project's standard development workflow (plan if needed, architect/JTBD review, behavioural tests per
|
|
234
|
-
5. **Commit with the `Refs: STORY-<NNN>` trailer** (single-trailer vocabulary per
|
|
235
|
-
6. **Story `done` auto-transition**: when ALL acceptance-criteria checkboxes in the story body are ticked AND the linked RFC reaches `closed`, `/wr-itil:manage-story` auto-transitions the story `in-progress → done`. (When a story's RFC is still `in-progress` but the acceptance criteria are all ticked, the story stays at `in-progress` until the RFC closes — this preserves the trace coupling per
|
|
233
|
+
4. **Implement the story scope** — follow the project's standard development workflow (plan if needed, architect/JTBD review, behavioural tests per the "Behavioural-tests-default for skill testing" architecture rule, single-commit grain per the "Governance Skills Commit Their Own Completed Work" architecture rule). Confine the implementation to the picked story's acceptance criteria; deviating into adjacent unscoped work is a scope-expansion signal — surface it via the `## Scope expansion` AskUserQuestion below.
|
|
234
|
+
5. **Commit with the `Refs: STORY-<NNN>` trailer** (single-trailer vocabulary per the "Problem-RFC-Story framework with mandatory problem-trace and unified problem ontology" architecture rule line 307 + amendment 2026-05-10 nitpick N2 — same trailer verb whether the commit is the story's first implementation commit or a continuation). On the FIRST commit AFTER the capture commit (subject prefix discriminates: `feat(itil): capture STORY-NNN ...` is the capture; any other subject prefix is an implementation commit), `/wr-itil:manage-story` auto-transitions the story `draft → in-progress`. As acceptance criteria checkboxes are ticked across multiple commits, the same trailer continues to attribute the work.
|
|
235
|
+
6. **Story `done` auto-transition**: when ALL acceptance-criteria checkboxes in the story body are ticked AND the linked RFC reaches `closed`, `/wr-itil:manage-story` auto-transitions the story `in-progress → done`. (When a story's RFC is still `in-progress` but the acceptance criteria are all ticked, the story stays at `in-progress` until the RFC closes — this preserves the trace coupling per the "Problem-RFC-Story framework with mandatory problem-trace and unified problem ontology" architecture rule line 309.)
|
|
236
236
|
7. **Pick the next not-done story** from the RFC's `stories:` array. Repeat from step 3.
|
|
237
|
-
8. **When all stories under all referenced RFCs are done** — the problem is fix-released. Include the problem doc closure in the final commit (`git mv` to `.verifying.md`, update Status) per
|
|
237
|
+
8. **When all stories under all referenced RFCs are done** — the problem is fix-released. Include the problem doc closure in the final commit (`git mv` to `.verifying.md`, update Status) per the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule. Push, create changeset, release per the lean release principle.
|
|
238
238
|
|
|
239
|
-
**Legacy empty-stories back-fill (per
|
|
239
|
+
**Legacy empty-stories back-fill (per the "Every RFC has at least one story" architecture rule)**: a pre-the "Every RFC has at least one story" architecture rule RFC whose `stories:` is empty is a **back-fill** case, not an atomic fallback — the "Every RFC has at least one story" architecture rule requires ≥1 story, so the empty-stories atomic dispatch is removed. Decompose the fix into ≥1 story on the RFC's story map (add the story, transition it `accepted`), then traverse it via the normal story path above. The `Refs: RFC-<NNN>` trailer remains valid for **cross-cutting RFC work with no single story** (e.g. an RFC-level enforcement change spanning several files); it is no longer an atomic-empty-stories fallback. Legacy on-disk RFCs still carrying `stories: []` are surfaced for back-fill by `wr-itil-check-rfc-has-stories` at their next `manage-rfc accepted` transition.
|
|
240
240
|
|
|
241
241
|
**Legacy direct-implementation path** (step 1 no-RFCs case): a Phase 1-shape Known Error whose Fix Strategy references no RFCs continues to work via the pre-Phase-2 flow — read the root cause analysis and fix strategy, implement the fix following the project's development workflow, include the problem doc closure in the fix commit (`git mv` to `.verifying.md`, update Status), push + changeset + release. This preserves backwards compatibility with all existing Known Error problems (which were captured before the RFC framework was Phase-1-graduated).
|
|
242
242
|
|
|
@@ -250,7 +250,7 @@ The Phase 2 working-the-problem traversal makes "implement the fix" concretely t
|
|
|
250
250
|
|
|
251
251
|
## Steps
|
|
252
252
|
|
|
253
|
-
### 0a. Auto-migrate adopter layout (
|
|
253
|
+
### 0a. Auto-migrate adopter layout (the "Problem tickets strain as fixes decompose into multiple coordinated changes — need an RFC framework that ties all changes back to problems (and unifies technical with user/business problems)" problem / the ": docs/problems/ flat layout migration — per-state subdirs + adopter auto-migration" release design / the "Problem-ticket directory layout — per-state subdirectories under `docs/problems/`" architecture rule)
|
|
254
254
|
|
|
255
255
|
Before the README-reconciliation preflight (Step 0) and any other layout-dependent logic, source the shared shell migration routine and call the idempotent entrypoint:
|
|
256
256
|
|
|
@@ -258,40 +258,40 @@ Before the README-reconciliation preflight (Step 0) and any other layout-depende
|
|
|
258
258
|
wr-itil-migrate-problems-layout "$PWD"
|
|
259
259
|
```
|
|
260
260
|
|
|
261
|
-
`wr-itil-migrate-problems-layout` is the
|
|
261
|
+
`wr-itil-migrate-problems-layout` is the "Plugin-bundled scripts invoked from SKILL.md resolve via `bin/` on `$PATH`" architecture rule `$PATH` shim (adopter-safe — resolves the canonical `lib/migrate-problems-layout.sh` relative to the script, NOT cwd; the "capture-problem / capture-rfc / manage-problem Step 2 create-gate marker step sources repo-relative `packages/itil/hooks/lib/*.sh` — fails in adopter installs (recurring published-path class: //)" problem/the ": Adopter-safe path resolution in shipped SKILLs ( — 24 repo-relative references)" release design) that internalises the former inline `source packages/itil/lib/migrate-problems-layout.sh; migrate_problems_to_per_state_layout "$PWD"`. NEVER `source packages/...` repo-relative from a SKILL — those paths only resolve in the source monorepo, not adopter installs.
|
|
262
262
|
|
|
263
263
|
The routine is **idempotent and partial-migration-safe**. It no-ops when no flat-layout files (`docs/problems/*.<state>.md` at the top level of `docs/problems/`) are detected — the common case in this monorepo (post-Slice-5 T5a 2026-05-10) and in freshly-migrated adopter repos.
|
|
264
264
|
|
|
265
|
-
On a flat-layout adopter repo (first invocation post-update —
|
|
265
|
+
On a flat-layout adopter repo (first invocation post-update — the "Extend the Suite with New Plugins" user outcome plugin-developer auto-migration path), the routine:
|
|
266
266
|
|
|
267
267
|
1. Creates the five state subdirectories (`docs/problems/open/`, `/known-error/`, `/verifying/`, `/parked/`, `/closed/`).
|
|
268
268
|
2. Runs `git mv docs/problems/<NNN>-<slug>.<state>.md docs/problems/<state>/<NNN>-<slug>.md` for every existing ticket. `nullglob` is enabled so partial-migration tails don't trip on literal-glob expansion.
|
|
269
|
-
3. Emits a standalone commit (per
|
|
269
|
+
3. Emits a standalone commit (per the "Problem-ticket directory layout — per-state subdirectories under `docs/problems/`" architecture rule § Backward Compatibility line 124 "not folded into other work — so adopters can audit / revert in isolation") with subject `docs(problems): auto-migrate to per-state subdirectory layout (the "Problem-ticket directory layout — per-state subdirectories under `docs/problems/`" architecture rule)` and footer trailer `RISK_BYPASS: adr-031-migration` (recognised by the commit-gate hook per T11; allows the migration to skip the full risk-score overhead while preserving the audit trail).
|
|
270
270
|
|
|
271
|
-
**AFK authorisation per
|
|
271
|
+
**AFK authorisation per the "Structured User Interaction for Governance-Skill Decisions" architecture rule Rule 6**: this fires unconditionally even in AFK / non-interactive / orchestrated mode. Pure-rename + pure-mkdir + standalone-commit actions are policy-authorised under the "AFK orchestrator preflight: get the repo into a clean state before starting" architecture rule precedent — they are fully reversible (`git revert`), have no external-comms surface, no secrets, no destructive overwrite. No `AskUserQuestion` gate.
|
|
272
272
|
|
|
273
|
-
**First-fire signal (
|
|
273
|
+
**First-fire signal (the ": Progress the Backlog While I'm Away" user outcome AFK transparency per T8 jtbd-review nitpick c)**: the routine emits a single stderr line `migrate-problems-layout: relocated N tickets to per-state subdirs (the "Problem-ticket directory layout — per-state subdirectories under `docs/problems/`" architecture rule)` on the migrating invocation; silent on no-op re-invocations.
|
|
274
274
|
|
|
275
275
|
After Step 0a completes (whether no-op or migration), proceed to Step 0 README reconciliation preflight. The reconcile-readme script reads the post-migration layout; the in-flow Step 5 / Step 7 README refresh paths re-render the README from the per-state subdir shape.
|
|
276
276
|
|
|
277
|
-
### 0. README reconciliation preflight (
|
|
277
|
+
### 0. README reconciliation preflight (the "`docs/problems/README.md` drifts from filesystem truth across sessions despite (refresh-on-create) and (refresh-on-transition) both Closed" problem)
|
|
278
278
|
|
|
279
|
-
Before parsing the request, run the diagnose-only reconciliation check. The contract here catches **cross-session drift** that per-operation refresh paths (
|
|
279
|
+
Before parsing the request, run the diagnose-only reconciliation check. The contract here catches **cross-session drift** that per-operation refresh paths (the "Problem 094: `/wr-itil:manage-problem` does not refresh `docs/problems/README.md` on ticket creation" problem refresh-on-create + the "Problem 062: `manage-problem` does not refresh `docs/problems/README.md` on single-ticket transitions; fast-path cache goes stale silently" problem refresh-on-transition) cannot retroactively see — if any past session committed a ticket change without staging the README refresh, the next manage-problem invocation reads a stale README that lies about what is open / verifying / closed.
|
|
280
280
|
|
|
281
281
|
```bash
|
|
282
282
|
wr-itil-reconcile-readme docs/problems
|
|
283
283
|
```
|
|
284
284
|
|
|
285
|
-
The `wr-itil-reconcile-readme` command is a `$PATH`-resolved shim shipped in `packages/itil/bin/` that dispatches the canonical `packages/itil/scripts/reconcile-readme.sh` body.
|
|
285
|
+
The `wr-itil-reconcile-readme` command is a `$PATH`-resolved shim shipped in `packages/itil/bin/` that dispatches the canonical `packages/itil/scripts/reconcile-readme.sh` body. the "Plugin-bundled scripts invoked from SKILL.md resolve via `bin/` on `$PATH`" architecture rule — never invoke the canonical script via repo-relative path; the path does not resolve in adopter trees.
|
|
286
286
|
|
|
287
287
|
Exit-code routing:
|
|
288
288
|
- **Exit 0 (clean)**: continue to Step 1.
|
|
289
|
-
- **Exit 1 (drift detected)**: structured diff lines printed to stdout, one per drift entry (≤150 bytes per
|
|
290
|
-
- **Exit 2 (parse error)**: README missing or malformed. Halt with the parse-error message; this needs investigation, not mechanical reconciliation. AFK orchestrators halt-with-report per
|
|
289
|
+
- **Exit 1 (drift detected)**: structured diff lines printed to stdout, one per drift entry (≤150 bytes per the "Progressive disclosure + once-per-session budget for UserPromptSubmit governance prose" architecture rule progressive-disclosure budget). Capture stdout to a temp file and classify the drift via the **uncommitted-rename carve-out** (the "`/wr-itil:manage-problem` Step 0 reconcile halt-on-drift directive doesn't distinguish uncommitted-rename-rooted drift (same-session pending) from committed cross-session drift — should refresh inline rather than halt for the former case" problem) before halt-routing — see "Drift classification carve-out" immediately below.
|
|
290
|
+
- **Exit 2 (parse error)**: README missing or malformed. Halt with the parse-error message; this needs investigation, not mechanical reconciliation. AFK orchestrators halt-with-report per the "Structured User Interaction for Governance-Skill Decisions" architecture rule Rule 6.
|
|
291
291
|
|
|
292
|
-
#### Drift classification carve-out (
|
|
292
|
+
#### Drift classification carve-out (the "`/wr-itil:manage-problem` Step 0 reconcile halt-on-drift directive doesn't distinguish uncommitted-rename-rooted drift (same-session pending) from committed cross-session drift — should refresh inline rather than halt for the former case" problem)
|
|
293
293
|
|
|
294
|
-
The Exit 1 halt-and-route path is correct for **committed cross-session drift** — a past session committed a ticket transition without staging the README refresh, and proceeding now would re-encode the drift into the post-operation refresh and propagate the lie. It is **wrong for uncommitted-rename-rooted drift** — when the current working tree carries a staged ticket rename (a same-session `git mv` that the in-flow
|
|
294
|
+
The Exit 1 halt-and-route path is correct for **committed cross-session drift** — a past session committed a ticket transition without staging the README refresh, and proceeding now would re-encode the drift into the post-operation refresh and propagate the lie. It is **wrong for uncommitted-rename-rooted drift** — when the current working tree carries a staged ticket rename (a same-session `git mv` that the in-flow the "Problem 094: `/wr-itil:manage-problem` does not refresh `docs/problems/README.md` on ticket creation" problem / the "Problem 062: `manage-problem` does not refresh `docs/problems/README.md` on single-ticket transitions; fast-path cache goes stale silently" problem refresh at Step 5 / Step 7 will reconcile in the upcoming commit per the "Governance Skills Commit Their Own Completed Work" architecture rule's single-commit grain). Halting in the latter case forces a separate `/wr-itil:reconcile-readme` commit, splitting one logical change across two commits and violating the "Governance Skills Commit Their Own Completed Work" architecture rule grain.
|
|
295
295
|
|
|
296
296
|
Run the classifier on Exit 1 to distinguish the two cases:
|
|
297
297
|
|
|
@@ -305,21 +305,21 @@ if [ "$reconcile_exit" -eq 1 ]; then
|
|
|
305
305
|
fi
|
|
306
306
|
```
|
|
307
307
|
|
|
308
|
-
The `wr-itil-classify-readme-drift` command is a `$PATH`-resolved shim (
|
|
308
|
+
The `wr-itil-classify-readme-drift` command is a `$PATH`-resolved shim (the "Plugin-bundled scripts invoked from SKILL.md resolve via `bin/` on `$PATH`" architecture rule naming grammar) dispatching `packages/itil/scripts/classify-readme-drift.sh`. It cross-references the drifting IDs from the script's stdout against `git status --porcelain docs/problems/` filtered for staged rename (`R`) entries — the destination path's ticket ID is the post-rename status the in-flow refresh will reconcile.
|
|
309
309
|
|
|
310
310
|
Classifier exit-code routing:
|
|
311
311
|
|
|
312
|
-
- **`classify_exit == 0` (INLINE_REFRESH)**: every drifting ID is the destination of a staged rename in the working tree. Log a one-line note ("Step 0 reconcile drift covered by N staged rename(s); deferring README refresh to in-flow Step 5 / Step 7 per
|
|
313
|
-
- **`classify_exit == 1` (HALT_ROUTE_RECONCILE)**: at least one drifting ID is NOT covered by a staged rename — committed cross-session drift OR mixed (some IDs in working tree, some committed-only). **Halt this invocation** with a directive to invoke `/wr-itil:reconcile-readme` (interactive mode) or auto-route through the same skill in non-interactive mode (per
|
|
312
|
+
- **`classify_exit == 0` (INLINE_REFRESH)**: every drifting ID is the destination of a staged rename in the working tree. Log a one-line note ("Step 0 reconcile drift covered by N staged rename(s); deferring README refresh to in-flow Step 5 / Step 7 per the "Problem 094: `/wr-itil:manage-problem` does not refresh `docs/problems/README.md` on ticket creation" problem / the "Problem 062: `manage-problem` does not refresh `docs/problems/README.md` on single-ticket transitions; fast-path cache goes stale silently" problem + the "Governance Skills Commit Their Own Completed Work" architecture rule single-commit grain") and continue to Step 1. Do NOT invoke `/wr-itil:reconcile-readme` — the in-flow refresh will land the README correction in the same commit as the ticket work.
|
|
313
|
+
- **`classify_exit == 1` (HALT_ROUTE_RECONCILE)**: at least one drifting ID is NOT covered by a staged rename — committed cross-session drift OR mixed (some IDs in working tree, some committed-only). **Halt this invocation** with a directive to invoke `/wr-itil:reconcile-readme` (interactive mode) or auto-route through the same skill in non-interactive mode (per the "Structured User Interaction for Governance-Skill Decisions" architecture rule Rule 6, AFK orchestrator). The reconciliation must complete and commit before this manage-problem invocation proceeds. Mixed routes to halt because `/wr-itil:reconcile-readme` resolves both classes safely; the in-flow refresh only handles the rename'd subset.
|
|
314
314
|
- **`classify_exit == 2` (parse error)**: classifier received empty / missing drift input — contract violation upstream. Fall back to the conservative halt-and-route path.
|
|
315
315
|
|
|
316
|
-
This is a **preflight CHECK only** — manage-problem does NOT itself apply edits. The edit application lives in `/wr-itil:reconcile-readme`'s Step 4 with narrative preservation. Per architect verdict on
|
|
316
|
+
This is a **preflight CHECK only** — manage-problem does NOT itself apply edits. The edit application lives in `/wr-itil:reconcile-readme`'s Step 4 with narrative preservation. Per architect verdict on the "`docs/problems/README.md` drifts from filesystem truth across sessions despite (refresh-on-create) and (refresh-on-transition) both Closed" problem (Q3): manage-problem and work-problems Step 0 invoke the script (cheap mechanical check); transition-problem does NOT (the "Problem 062: `manage-problem` does not refresh `docs/problems/README.md` on single-ticket transitions; fast-path cache goes stale silently" problem already covers transition-time refresh inside the same commit, redundant preflight there would pay the cost on every transition).
|
|
317
317
|
|
|
318
|
-
This step is a robustness layer ON TOP of
|
|
318
|
+
This step is a robustness layer ON TOP of the "Problem 094: `/wr-itil:manage-problem` does not refresh `docs/problems/README.md` on ticket creation" problem + the "Problem 062: `manage-problem` does not refresh `docs/problems/README.md` on single-ticket transitions; fast-path cache goes stale silently" problem, not a supersession of either — both per-operation contracts remain in force at Step 5 (creation refresh) and Step 7 (transition refresh).
|
|
319
319
|
|
|
320
|
-
### 0.5. Deferred-placeholder + README-cadence advisory (per
|
|
320
|
+
### 0.5. Deferred-placeholder + README-cadence advisory (per the "`/wr-itil:review-problems` not auto-fired when needed — user has to remember to run it" problem)
|
|
321
321
|
|
|
322
|
-
After Step 0's README reconciliation preflight and before Step 1's request parsing, check whether the deferred-placeholder backlog has accumulated past threshold AND the `docs/problems/README.md` "Last reviewed" cadence has slipped. This is the **interactive** sibling of `/wr-itil:work-problems` Step 0c. At an interactive `manage-problem` surface the right shape per
|
|
322
|
+
After Step 0's README reconciliation preflight and before Step 1's request parsing, check whether the deferred-placeholder backlog has accumulated past threshold AND the `docs/problems/README.md` "Last reviewed" cadence has slipped. This is the **interactive** sibling of `/wr-itil:work-problems` Step 0c. At an interactive `manage-problem` surface the right shape per the "Structured User Interaction for Governance-Skill Decisions" architecture rule Rule 1 is **advisory not auto-dispatch** — the user is at the keyboard; the advisory is the surface; the user invokes `/wr-itil:review-problems` directly if they want the heavyweight re-rate pass. Auto-dispatching a heavyweight skill mid-interactive-session would break the ": Enforce Governance Without Slowing Down" user outcome's "Reviews complete in under 60 seconds so they don't break flow" outcome.
|
|
323
323
|
|
|
324
324
|
**Mechanism:**
|
|
325
325
|
|
|
@@ -335,20 +335,20 @@ Routing on the helper's five-outcome enum:
|
|
|
335
335
|
|----------------------------------------------------------|--------------------------------------------------------------------------------------------------------|
|
|
336
336
|
| `no-deferred-placeholders` | Silent-pass. Proceed to Step 1. |
|
|
337
337
|
| `below-threshold count=<N> threshold=3` | Silent-pass. Proceed to Step 1. |
|
|
338
|
-
| `fresh-readme count=<N> age=<X>s threshold=<Y>s` | Silent-pass per
|
|
338
|
+
| `fresh-readme count=<N> age=<X>s threshold=<Y>s` | Silent-pass per the "Structured User Interaction for Governance-Skill Decisions" architecture rule Rule 5 — the cadence is in spec. |
|
|
339
339
|
| `no-readme count=<N>` | Emit an **advisory note** to stdout (visible to the interactive maintainer) naming the placeholder count + a directive: *"`<N>` deferred-placeholder ticket(s) accumulated AND `docs/problems/README.md` is missing/malformed; run `/wr-itil:review-problems` to re-rate and rebuild the README."* Then proceed to Step 1. |
|
|
340
340
|
| `stale-readme count=<N> age=<X>s threshold=<Y>s` | Emit an **advisory note** naming the placeholder count + readable age: *"`<N>` deferred-placeholder ticket(s) accumulated AND the WSJF Rankings cadence is `<X>` days stale (> 7-day threshold); run `/wr-itil:review-problems` to re-rate and refresh."* Then proceed to Step 1. |
|
|
341
341
|
|
|
342
|
-
**Why advisory not auto-dispatch at this surface** (
|
|
343
|
-
- The interactive user is at the keyboard. The advisory IS the surface; auto-dispatching a heavyweight skill mid-interactive-session would force a flow break that
|
|
342
|
+
**Why advisory not auto-dispatch at this surface** (the "Structured User Interaction for Governance-Skill Decisions" architecture rule Rule 1 + the ": Enforce Governance Without Slowing Down" user outcome):
|
|
343
|
+
- The interactive user is at the keyboard. The advisory IS the surface; auto-dispatching a heavyweight skill mid-interactive-session would force a flow break that the ": Enforce Governance Without Slowing Down" user outcome explicitly proscribes ("Reviews complete in under 60 seconds so they don't break flow").
|
|
344
344
|
- The advisory preserves the user's authority to pick when to absorb the re-rate cost — at the next natural break, after a release, before the next session, etc.
|
|
345
|
-
- `AskUserQuestion` would also be valid here (
|
|
345
|
+
- `AskUserQuestion` would also be valid here (the "Structured User Interaction for Governance-Skill Decisions" architecture rule Rule 1 interactive surface), but for a single optional pre-flight directive the advisory shape carries less round-trip friction than a structured question. The advisory is a **directive**, not a decision — the user already knows to run review-problems if they want to.
|
|
346
346
|
|
|
347
|
-
**ADR-
|
|
347
|
+
**the "Evidence-based relevance-close pass for the problem backlog (Phase 1: file-no-longer-exists; Phase 2: ADR-shipped-confirmed + named-skill-exists + self-marker-in-body + driver-child-closed + Phase 1 false-positive fixes)" architecture rule composition note**: when the user follows the advisory and invokes `/wr-itil:review-problems`, that skill includes Step 4.6 relevance-close per the "Evidence-based relevance-close pass for the problem backlog (Phase 1: file-no-longer-exists; Phase 2: ADR-shipped-confirmed + named-skill-exists + self-marker-in-body + driver-child-closed + Phase 1 false-positive fixes)" architecture rule — relevance-close fires as a side-effect of any review pass.
|
|
348
348
|
|
|
349
349
|
**Fail-soft**: any error in this step (helper missing, malformed output) MUST NOT block manage-problem — log an advisory note and proceed to Step 1.
|
|
350
350
|
|
|
351
|
-
<!-- @jtbd
|
|
351
|
+
<!-- @jtbd the ": Enforce Governance Without Slowing Down" user outcome (Enforce Governance Without Slowing Down — interactive advisory keeps the signal surfaced without forcing a flow break) -->
|
|
352
352
|
|
|
353
353
|
After Step 0.5 completes (whether silent-pass or advisory emitted), proceed to Step 1.
|
|
354
354
|
|
|
@@ -362,11 +362,11 @@ Determine the operation from `$ARGUMENTS`:
|
|
|
362
362
|
- If arguments contain "review", **delegate to `/wr-itil:review-problems`** via the Skill tool. See "Deprecated-argument forwarders" below.
|
|
363
363
|
- Otherwise, this is a new problem creation
|
|
364
364
|
|
|
365
|
-
#### Deprecated-argument forwarders (
|
|
365
|
+
#### Deprecated-argument forwarders (the "Rename `wr-problem` Plugin to `wr-itil`" architecture rule amended + the "Problem 071: Argument-based skill subcommands are not discoverable in Claude Code autocomplete" problem)
|
|
366
366
|
|
|
367
|
-
Per
|
|
367
|
+
Per the "Rename `wr-problem` Plugin to `wr-itil`" architecture rule'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.
|
|
368
368
|
|
|
369
|
-
**Forwarder for `list`** (
|
|
369
|
+
**Forwarder for `list`** (the "Problem 071: Argument-based skill subcommands are not discoverable in Claude Code autocomplete" problem split slice 1 — new skill `/wr-itil:list-problems`):
|
|
370
370
|
|
|
371
371
|
When `$ARGUMENTS` contains the word `list` as a top-level argument (not inside a ticket body edit), delegate to `/wr-itil:list-problems` via the Skill tool and emit this systemMessage verbatim:
|
|
372
372
|
|
|
@@ -374,7 +374,7 @@ When `$ARGUMENTS` contains the word `list` as a top-level argument (not inside a
|
|
|
374
374
|
|
|
375
375
|
The forwarder does NOT re-implement the list logic locally — it invokes the Skill tool with `wr-itil:list-problems` and returns the new skill's output verbatim. Duplicating the logic would harden the deprecation window into a permanent fork.
|
|
376
376
|
|
|
377
|
-
**Forwarder for `review`** (
|
|
377
|
+
**Forwarder for `review`** (the "Problem 071: Argument-based skill subcommands are not discoverable in Claude Code autocomplete" problem split slice 2 — new skill `/wr-itil:review-problems`):
|
|
378
378
|
|
|
379
379
|
When `$ARGUMENTS` contains the word `review` as a top-level argument (not inside a ticket body edit), delegate to `/wr-itil:review-problems` via the Skill tool and emit this systemMessage verbatim:
|
|
380
380
|
|
|
@@ -382,15 +382,15 @@ When `$ARGUMENTS` contains the word `review` as a top-level argument (not inside
|
|
|
382
382
|
|
|
383
383
|
The forwarder does NOT re-implement the review logic locally — it invokes the Skill tool with `wr-itil:review-problems` and returns the new skill's output verbatim. Duplicating the Step 9 re-scoring / auto-transition / verification-prompt / README-refresh stack would harden the deprecation window into a permanent fork.
|
|
384
384
|
|
|
385
|
-
**Forwarder for `work`** (
|
|
385
|
+
**Forwarder for `work`** (the "Problem 071: Argument-based skill subcommands are not discoverable in Claude Code autocomplete" problem split slice 3 — new skill `/wr-itil:work-problem`, singular):
|
|
386
386
|
|
|
387
387
|
When `$ARGUMENTS` contains the word `work` as a top-level argument (not inside a ticket body edit), delegate to `/wr-itil:work-problem` via the Skill tool and emit this systemMessage verbatim:
|
|
388
388
|
|
|
389
389
|
> `/wr-itil:manage-problem work is deprecated; use /wr-itil:work-problem directly. This forwarder will be removed in @windyroad/itil's next major version.`
|
|
390
390
|
|
|
391
|
-
The forwarder does NOT re-implement the selection logic locally — it invokes the Skill tool with `wr-itil:work-problem` and returns the new skill's output verbatim. Duplicating the freshness-check / AskUserQuestion selection / delegate-to-`manage-problem <NNN>` stack would harden the deprecation window into a permanent fork. Note the singular/plural distinction: the forwarder targets `/wr-itil:work-problem` (singular, one ticket per invocation), NOT `/wr-itil:work-problems` (plural AFK orchestrator). The two names coexist intentionally per
|
|
391
|
+
The forwarder does NOT re-implement the selection logic locally — it invokes the Skill tool with `wr-itil:work-problem` and returns the new skill's output verbatim. Duplicating the freshness-check / AskUserQuestion selection / delegate-to-`manage-problem <NNN>` stack would harden the deprecation window into a permanent fork. Note the singular/plural distinction: the forwarder targets `/wr-itil:work-problem` (singular, one ticket per invocation), NOT `/wr-itil:work-problems` (plural AFK orchestrator). The two names coexist intentionally per the "Problem 071: Argument-based skill subcommands are not discoverable in Claude Code autocomplete" problem.
|
|
392
392
|
|
|
393
|
-
**Forwarder for `<NNN> <status>` transitions** (
|
|
393
|
+
**Forwarder for `<NNN> <status>` transitions** (the "Problem 071: Argument-based skill subcommands are not discoverable in Claude Code autocomplete" problem split slice 4 — new skill `/wr-itil:transition-problem`):
|
|
394
394
|
|
|
395
395
|
When `$ARGUMENTS` starts with a three-digit ticket ID followed by a status word (`known-error`, `verifying`, or `close`), delegate to `/wr-itil:transition-problem` via the Skill tool and emit the canonical deprecation notice verbatim, naming the specific argument form the user supplied:
|
|
396
396
|
|
|
@@ -398,7 +398,7 @@ When `$ARGUMENTS` starts with a three-digit ticket ID followed by a status word
|
|
|
398
398
|
|
|
399
399
|
The parser must distinguish a **bare `<NNN>`** (update flow — handled inline by Step 6) from a **`<NNN> <status>` pair** (transition — delegated). The status-word tokens that trigger the transition forwarder are fixed: `known-error`, `verifying`, `close`. Any other suffix after `<NNN>` routes to the inline update flow per Step 6. This preserves the two legitimate shapes the original subcommand carried while splitting the transition intent out cleanly.
|
|
400
400
|
|
|
401
|
-
The forwarder does NOT re-implement the Step 7 transition logic locally — it invokes the Skill tool with `wr-itil:transition-problem` and returns the new skill's output verbatim. Duplicating the pre-flight-checks /
|
|
401
|
+
The forwarder does NOT re-implement the Step 7 transition logic locally — it invokes the Skill tool with `wr-itil:transition-problem` and returns the new skill's output verbatim. Duplicating the pre-flight-checks / the "Problem 063: manage-problem does not trigger /wr-itil:report-upstream when root cause is external" problem-external-root-cause-detection / the "Problem 057: `git mv` + Edit + `git add` staging-ordering trap drops content edits from the commit" problem-staging-trap / the "Problem 062: `manage-problem` does not refresh `docs/problems/README.md` on single-ticket transitions; fast-path cache goes stale silently" problem-README-refresh stack would harden the deprecation window into a permanent fork. Per the "Rename `wr-problem` Plugin to `wr-itil`" architecture rule amended "Split-skill execution ownership" (the "Problem 093: `/wr-itil:transition-problem` ↔ `/wr-itil:manage-problem` circular delegation for `<NNN> <status>` args" problem), the forwarder is **one-way** — `/wr-itil:transition-problem` hosts its own inline Step 7 block and does NOT re-invoke `/wr-itil:manage-problem`. The in-skill Step 7 block below stays in place for in-skill callers (Step 9b auto-transition, the Parked path, Step 9d closure inside review); the split skill carries a scoped inline copy for the user-initiated transition path only ("copy, not move"). Lifecycle completeness (known-error + verifying + close) is covered per the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule's three-status mandate.
|
|
402
402
|
|
|
403
403
|
### 2. For new problems: Check for duplicates FIRST
|
|
404
404
|
|
|
@@ -408,59 +408,59 @@ Before creating, search existing problems for similar issues. The user may not k
|
|
|
408
408
|
2. Search all files in `docs/problems/` for those keywords using Grep
|
|
409
409
|
3. Read the title and status of each match
|
|
410
410
|
4. If matches are found, present them to the user via `AskUserQuestion`:
|
|
411
|
-
- "I found existing problems that may be related:
|
|
411
|
+
- "I found existing problems that may be related: the "Problem 011: Grep-based BATS tests produce false positives on legitimate refactors" problem (stuck saving, CLOSED), the "Problem 023: Governance skills should commit completed work, not defer to user" problem (foul drawn garbled, OPEN). Would you like to: (a) Update an existing problem, (b) Create a new problem anyway, (c) Cancel?"
|
|
412
412
|
5. If the user chooses to update, switch to the update flow for that problem ID
|
|
413
413
|
6. If no matches found, proceed to create
|
|
414
|
-
7. **After the grep completes** (whether duplicates were found or not), write the per-session create-gate marker so the `PreToolUse:Write` hook (`packages/itil/hooks/manage-problem-enforce-create.sh`,
|
|
414
|
+
7. **After the grep completes** (whether duplicates were found or not), write the per-session create-gate marker so the `PreToolUse:Write` hook (`packages/itil/hooks/manage-problem-enforce-create.sh`, the "Agent bypasses `/wr-itil:manage-problem` Step 2 duplicate-check by writing tickets directly to `docs/problems/`" problem) allows the subsequent Write of the new `.open.md` file. The marker is `/tmp/manage-problem-grep-${SESSION_ID}`. Per **the "create-gate marker race between concurrent Claude sessions via shared runtime-sid file" problem / the "Capture the runtime stdin session_id via a PreToolUse hook so the create-gate marker binds to the same SID the runtime hook will see" architecture rule Option C**, the agent writes it under EVERY recent candidate session SID — not just one — by sourcing the discovery helpers (the "`/wr-itil:manage-problem` Step 2 substep 7 session-id discovery is brittle — agent has no env var, must scrape marker filenames" problem) and piping the candidate set into `mark_step2_complete_candidates`:
|
|
415
415
|
|
|
416
416
|
```bash
|
|
417
417
|
wr-itil-mark-create-gate
|
|
418
418
|
```
|
|
419
419
|
|
|
420
|
-
`wr-itil-mark-create-gate` is the
|
|
420
|
+
`wr-itil-mark-create-gate` is the "Plugin-bundled scripts invoked from SKILL.md resolve via `bin/` on `$PATH`" architecture rule `$PATH` shim (adopter-safe — resolves its `hooks/lib` siblings relative to the script, NOT cwd; the "capture-problem / capture-rfc / manage-problem Step 2 create-gate marker step sources repo-relative `packages/itil/hooks/lib/*.sh` — fails in adopter installs (recurring published-path class: //)" problem/the ": Adopter-safe path resolution in shipped SKILLs ( — 24 repo-relative references)" release design) that internalises the former inline `source packages/itil/hooks/lib/{session-id,create-gate}.sh` + `get_candidate_session_ids | mark_step2_complete_candidates`. NEVER `source packages/...` repo-relative from a SKILL — those paths only resolve in the source monorepo, not adopter installs.
|
|
421
421
|
|
|
422
|
-
**Why every candidate, not one (
|
|
422
|
+
**Why every candidate, not one (the "create-gate marker race between concurrent Claude sessions via shared runtime-sid file" problem / the "Capture the runtime stdin session_id via a PreToolUse hook so the create-gate marker binds to the same SID the runtime hook will see" architecture rule Option C)**: under `/wr-itil:work-problems` the orchestrator main turn fires PreToolUse hooks concurrently with its backgrounded iter subprocess (Step 5). Both sessions write the same per-machine runtime-sid marker (last-writer-wins), so the single-SID `get_current_session_id` can return the subprocess SID while the orchestrator's Write carries the orchestrator SID on its stdin — marker mismatch, create-gate deny. No agent-side algorithm can predict the right single SID from filesystem state alone (the "Capture the runtime stdin session_id via a PreToolUse hook so the create-gate marker binds to the same SID the runtime hook will see" architecture rule §Context). The command instead enumerates EVERY candidate SID the hook might read — the `get_current_session_id` pick (env-var > runtime-sid > announce-marker priority, the "`/wr-itil:manage-problem` Step 2 substep 7 session-id discovery is brittle — agent has no env var, must scrape marker filenames" problem) PLUS every recent `/tmp/<system>-announced-<UUID>` UUID within a 24h mtime window (the "Progressive disclosure + once-per-session budget for UserPromptSubmit governance prose" architecture rule announce markers, set on prompt 1 of every session by architect / jtbd / tdd / style-guide / voice-tone / itil-assistant-gate / itil-correction-detect hooks) — and writes the marker under each. Whichever SID the hook reads from the Write's stdin, a matching marker provably exists. The candidate set is **bounded** to recent same-machine announce markers + the runtime-sid value — NOT a global fail-open: the "Agent bypasses `/wr-itil:manage-problem` Step 2 duplicate-check by writing tickets directly to `docs/problems/`" problem audit invariant holds (every marker still records that THIS session ran the duplicate-check grep). The marker is per-session, so a single write covers all new tickets for the rest of this session, enabling Step 4b multi-concern splits and same-session unrelated-ticket creation without re-running the grep.
|
|
423
423
|
|
|
424
|
-
**Why helpers instead of inline `${CLAUDE_SESSION_ID:-default}`**: the agent's process does NOT export `CLAUDE_SESSION_ID` today; the hook side reads `session_id` from its stdin JSON payload (per the Claude Code PreToolUse contract). The prior fallback wrote the marker under `default` while the hook checked the real UUID — mismatch caused the Write deny on every first ticket of a session until the agent ad-hoc scraped a UUID-bearing marker. The helpers canonicalise that scrape so every agent context discovers candidate SIDs the same way.
|
|
424
|
+
**Why helpers instead of inline `${CLAUDE_SESSION_ID:-default}`**: the agent's process does NOT export `CLAUDE_SESSION_ID` today; the hook side reads `session_id` from its stdin JSON payload (per the Claude Code PreToolUse contract). The prior fallback wrote the marker under `default` while the hook checked the real UUID — mismatch caused the Write deny on every first ticket of a session until the agent ad-hoc scraped a UUID-bearing marker. The helpers canonicalise that scrape so every agent context discovers candidate SIDs the same way. the "`/wr-itil:manage-problem` Step 2 substep 7 session-id discovery is brittle — agent has no env var, must scrape marker filenames" problem.
|
|
425
425
|
|
|
426
|
-
**Phase 4 (
|
|
426
|
+
**Phase 4 (the "Phase 4 — `get_current_session_id` helper system-priority bug; subprocess SIDs win mtime selection over orchestrator SID" problem / the "Capture the runtime stdin session_id via a PreToolUse hook so the create-gate marker binds to the same SID the runtime hook will see" architecture rule)** — the helper reads the runtime stdin `session_id` from a per-machine marker written by the `itil-runtime-sid-marker.sh` PreToolUse hook on every tool call. Because every Bash call that sources the helper is itself a PreToolUse:Bash event, the marker the helper reads was written moments earlier with the same `session_id` the runtime Write hook will see — so SID-mismatch denial is structurally impossible **in non-concurrent flow**. The Phase 3 announce-marker priority logic is preserved as cold-path fallback (first tool call of a session, before any PreToolUse fires).
|
|
427
427
|
|
|
428
|
-
**Phase 5 (
|
|
428
|
+
**Phase 5 (the "create-gate marker race between concurrent Claude sessions via shared runtime-sid file" problem / the "Capture the runtime stdin session_id via a PreToolUse hook so the create-gate marker binds to the same SID the runtime hook will see" architecture rule Option C)** — the "structurally impossible" guarantee above holds ONLY when no second session writes the runtime-sid marker concurrently. Under `/wr-itil:work-problems`, the orchestrator main turn and its backgrounded subprocess write the per-machine runtime-sid marker concurrently (last-writer-wins), re-introducing the mismatch (this was the "create-gate marker race between concurrent Claude sessions via shared runtime-sid file" problem, surfaced by the 2026-05-18 the "report-upstream skill has automation blocks that clamp the agent feedback signal — external-comms risk assessment is the actual protection layer" problem/the "Rule 6 AFK fail-safe clamps intake-scaffold auto-execution — sibling-class to at the intake-scaffold surface; external-comms risk assessment is the actual protection layer" problem foreground captures). The candidate-set marker-write above is the mitigation: it does not depend on the runtime marker carrying the right SID at Write-time, because it marks under every recent candidate SID.
|
|
429
429
|
|
|
430
430
|
**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.
|
|
431
431
|
|
|
432
|
-
#### Sub-step 2.8 — Hang-off-check via fresh-context subagent (
|
|
432
|
+
#### Sub-step 2.8 — Hang-off-check via fresh-context subagent (the "`/wr-itil:review-problems` has no path to close tickets that are no longer relevant (evidence-based, NOT age-based) — structural outflow gap drives monotonic backlog growth" problem Phase 3 amendment, 2026-05-31; the "Governance skill invocation patterns — foreground + background with deferred-question resumption" architecture rule 5th invocation pattern)
|
|
433
433
|
|
|
434
|
-
The wide-net grep + AskUserQuestion at sub-steps 1-6 above handles the title/keyword-overlap class. Sub-step 2.8 closes a wider gap: parent tickets where the new problem's scope belongs absorbed as an Investigation Tasks expansion / Phase N section rather than as a sibling. The wrongly-captured
|
|
434
|
+
The wide-net grep + AskUserQuestion at sub-steps 1-6 above handles the title/keyword-overlap class. Sub-step 2.8 closes a wider gap: parent tickets where the new problem's scope belongs absorbed as an Investigation Tasks expansion / Phase N section rather than as a sibling. The wrongly-captured the "Phase 2 — extend `evaluate-relevance.sh` with 4 more evidence shapes + fix Phase 1 file-no-longer-exists false-positive class" problem sibling of the "`/wr-itil:review-problems` has no path to close tickets that are no longer relevant (evidence-based, NOT age-based) — structural outflow gap drives monotonic backlog growth" problem on 2026-05-31 (now closed as duplicate-of-the "`/wr-itil:review-problems` has no path to close tickets that are no longer relevant (evidence-based, NOT age-based) — structural outflow gap drives monotonic backlog growth" problem) is the canonical regression — the main agent mid-iter pattern-matched the existing capture flow under session-context bias.
|
|
435
435
|
|
|
436
436
|
Sub-step 2.8 adds a **mechanical pre-filter + fresh-context subagent dispatch** that closes this gap without re-introducing the main agent's bias. Mirrors the `/wr-itil:capture-problem` Step 2 sub-step 2b dispatch verbatim.
|
|
437
437
|
|
|
438
438
|
**Mechanical pre-filter** — grep `docs/problems/open/*.md` + `docs/problems/verifying/*.md` BODIES for tokens shared with the new problem's description: any `ADR-NNN` / `RFC-NNN` / `JTBD-NNN` reference, SKILL path (`/wr-<plugin>:<skill>` or `packages/<plugin>/skills/<skill>/`), or file path (`packages/...`, `docs/...`, `.github/...`, `bin/...`, `scripts/...`). Collect candidates that share ≥1 signal; cap at 5; empty or >5 → skip dispatch.
|
|
439
439
|
|
|
440
|
-
**
|
|
440
|
+
**the "Report a Problem Without Pre-Classifying It" user outcome firewall** — sub-step 2.8 fires on **maintainer-internal new-problem** captures ONLY. The dispatch MUST be skipped when manage-problem is ingesting a plugin-user-reported issue from `.github/ISSUE_TEMPLATE/problem-report.yml` (plugin-user descriptions do not carry the same authorial intent as maintainer-internal captures; a plugin-user describing their friction in maintainer vocabulary could plausibly trigger a wrong-parent HANG_OFF). When ingesting plugin-user reports, triage stays user-judgement per the "Report a Problem Without Pre-Classifying It" user outcome. Mirrors the existing Step 1.5 / Step 4 firewall patterns in `/wr-itil:capture-problem` (see line 116 of `packages/itil/skills/capture-problem/SKILL.md`).
|
|
441
441
|
|
|
442
|
-
**AFK safe-default**: when `--no-prompt` is propagated, the dispatch still fires (the subagent verdict is non-interactive by construction — no `AskUserQuestion`), and ambiguous-multi-parent cases collapse to `PROCEED_NEW` per the subagent's Rule 6 contract. This satisfies
|
|
442
|
+
**AFK safe-default**: when `--no-prompt` is propagated, the dispatch still fires (the subagent verdict is non-interactive by construction — no `AskUserQuestion`), and ambiguous-multi-parent cases collapse to `PROCEED_NEW` per the subagent's Rule 6 contract. This satisfies the ": Progress the Backlog While I'm Away" user outcome's safe-default contract.
|
|
443
443
|
|
|
444
444
|
**Dispatch** — delegate to `wr-itil:hang-off-check` via the Agent tool with the same structured payload shape capture-problem uses (`SURFACE: manage-problem-step-2.8`; `<new-capture>` payload; `<candidates>` payload with `P<NNN> | <title> | <path> | shared-signals: ...` per row). The subagent reads candidate bodies in full and emits:
|
|
445
445
|
|
|
446
|
-
- `HANG_OFF: P<NNN>` with **Rationale**, **Signals matched**, **Where to absorb** → halt manage-problem's new-problem creation; route to the parent-ticket update flow (Step 6 ticket-body edit on the named parent). Record the hang-off decision + rationale in the parent ticket's Investigation Tasks bullet or `### Phase N — <name>` section per the subagent's `Where to absorb` directive. Single-commit grain preserved (the parent-ticket amendment commit IS this manage-problem invocation's commit per
|
|
446
|
+
- `HANG_OFF: P<NNN>` with **Rationale**, **Signals matched**, **Where to absorb** → halt manage-problem's new-problem creation; route to the parent-ticket update flow (Step 6 ticket-body edit on the named parent). Record the hang-off decision + rationale in the parent ticket's Investigation Tasks bullet or `### Phase N — <name>` section per the subagent's `Where to absorb` directive. Single-commit grain preserved (the parent-ticket amendment commit IS this manage-problem invocation's commit per the "Governance Skills Commit Their Own Completed Work" architecture rule).
|
|
447
447
|
|
|
448
|
-
- `PROCEED_NEW` with **Rationale** + **Per-candidate explanation** → continue to Step 3 (ID assignment). Append the subagent's rationale + per-candidate explanation to the new ticket's `## Related` section as the audit trail per
|
|
448
|
+
- `PROCEED_NEW` with **Rationale** + **Per-candidate explanation** → continue to Step 3 (ID assignment). Append the subagent's rationale + per-candidate explanation to the new ticket's `## Related` section as the audit trail per the "Agent output grounding — no fabricated quantitative estimates, cite + persist + uncertainty" architecture rule grounding + the "Restore Service Fast with an Audit Trail" user outcome.
|
|
449
449
|
|
|
450
|
-
**Why a subagent (not in-SKILL checks)**: the main agent is biased by session context — mid-iter, mid-work, pattern-matching existing flows ("I captured X then dispatched iter; do the same shape for Y"). A fresh subagent invocation starts clean, reads only the structured inputs, and reasons about candidate absorption without the bias. Same architectural pattern as `wr-architect:agent` / `wr-jtbd:agent` / `tdd:review-test` / `wr-risk-scorer:pipeline` — codified as
|
|
450
|
+
**Why a subagent (not in-SKILL checks)**: the main agent is biased by session context — mid-iter, mid-work, pattern-matching existing flows ("I captured X then dispatched iter; do the same shape for Y"). A fresh subagent invocation starts clean, reads only the structured inputs, and reasons about candidate absorption without the bias. Same architectural pattern as `wr-architect:agent` / `wr-jtbd:agent` / `tdd:review-test` / `wr-risk-scorer:pipeline` — codified as the "Governance skill invocation patterns — foreground + background with deferred-question resumption" architecture rule's 5th invocation pattern under the "`/wr-itil:review-problems` has no path to close tickets that are no longer relevant (evidence-based, NOT age-based) — structural outflow gap drives monotonic backlog growth" problem amendment 2026-05-31.
|
|
451
451
|
|
|
452
|
-
**Cross-references**: `packages/itil/agents/hang-off-check.md` (the subagent); `packages/itil/agents/test/fixtures/regression-p347-vs-p346.md` (canonical behavioural fixture); `docs/decisions/032-governance-skill-invocation-patterns.proposed.md` § Foreground fresh-context-subagent-as-decision-arbiter variant; `docs/rfcs/
|
|
452
|
+
**Cross-references**: `packages/itil/agents/hang-off-check.md` (the subagent); `packages/itil/agents/test/fixtures/regression-p347-vs-p346.md` (canonical behavioural fixture); `docs/decisions/032-governance-skill-invocation-patterns.proposed.md` § Foreground fresh-context-subagent-as-decision-arbiter variant; `docs/rfcs/the ": backlog flow control multi-phase" release design-p346-backlog-flow-control-multi-phase.proposed.md` (multi-phase trace per the "Every fix goes through an RFC" architecture rule); `docs/problems/.../346-...md` (driver master ticket).
|
|
453
453
|
|
|
454
|
-
**Hook contract (
|
|
454
|
+
**Hook contract (the "Agent bypasses `/wr-itil:manage-problem` Step 2 duplicate-check by writing tickets directly to `docs/problems/`" problem)**: writing a `.open.md` (or any `.<status>.md`) file under `docs/problems/` without first running this Step 2 grep + marker-touch is blocked by the `manage-problem-enforce-create.sh` PreToolUse hook with a `permissionDecision: deny` directing the agent back to this skill. Agents that try to bypass the skill (e.g. mid-retrospective inline capture, post-mortem wrap-up, or any "I'll just write it directly" shortcut) will hit the deny and be redirected here. Do not work around the deny by setting the marker manually — the marker exists to record that this Step 2 ran, and a marker without a grep is the audit-trail gap the "Agent bypasses `/wr-itil:manage-problem` Step 2 duplicate-check by writing tickets directly to `docs/problems/`" problem closes.
|
|
455
455
|
|
|
456
456
|
### 3. For new problems: Assign the next ID
|
|
457
457
|
|
|
458
|
-
Compute the next ID as the **max of the local and origin highest IDs**, plus one, zero-padded to 3 digits. Comparing against `origin/<base>` is required by
|
|
458
|
+
Compute the next ID as the **max of the local and origin highest IDs**, plus one, zero-padded to 3 digits. Comparing against `origin/<base>` is required by the "AFK orchestrator preflight: get the repo into a clean state before starting" architecture rule (confirmation criterion 2): without it, parallel sessions can mint the same ID for different problems and force a destructive surgical rebase on push (the "Problem 040: work-problems does not fetch origin before starting" problem incident).
|
|
459
459
|
|
|
460
460
|
```bash
|
|
461
461
|
# Local-max ID — dual-tolerant enumeration covers BOTH the flat
|
|
462
462
|
# `docs/problems/<NNN>-<title>.<state>.md` layout AND the per-state
|
|
463
|
-
# subdir `docs/problems/<state>/<NNN>-<title>.md` layout per
|
|
463
|
+
# subdir `docs/problems/<state>/<NNN>-<title>.md` layout per the ": docs/problems/ flat layout migration — per-state subdirs + adopter auto-migration" release design
|
|
464
464
|
# migration window. Both halves contribute to next-ID compute so a
|
|
465
465
|
# pre-migration ticket at flat-104 and a post-migration ticket at
|
|
466
466
|
# per-state-204 BOTH appear in `local_max` — never re-allocates an
|
|
@@ -473,11 +473,11 @@ local_max=$(ls docs/problems/*.md docs/problems/*/*.md 2>/dev/null | sed 's|.*/|
|
|
|
473
473
|
# where the fetch happens). Default base is `main`; if the user is on
|
|
474
474
|
# another branch, swap accordingly.
|
|
475
475
|
#
|
|
476
|
-
# `--name-only` is required (
|
|
476
|
+
# `--name-only` is required (the "Problem 056: Ticket-creator next-ID lookup greps blob SHAs, producing wrong `origin_max` values" problem): without it, each ls-tree line is
|
|
477
477
|
# `<mode> <type> <sha>\t<path>` and the 40-char blob SHA can contain
|
|
478
478
|
# three-digit runs that `grep -oE '[0-9]{3}'` false-matches (observed
|
|
479
|
-
# `origin_max=997` on 2026-04-20 opening
|
|
480
|
-
# the per-state subdirs introduced by
|
|
479
|
+
# `origin_max=997` on 2026-04-20 opening the "Problem 055: No standard problem-reporting channel for plugin users, and no reusable pattern for downstream projects to report upstream" problem). `-r` recurses into
|
|
480
|
+
# the per-state subdirs introduced by the ": docs/problems/ flat layout migration — per-state subdirs + adopter auto-migration" release design. `sed 's|.*/||'` strips
|
|
481
481
|
# all leading path components so the anchored `grep -oE '^[0-9]+'`
|
|
482
482
|
# picks up filename IDs in both layouts.
|
|
483
483
|
origin_max=$(git ls-tree --name-only -r origin/main docs/problems/ 2>/dev/null | sed 's|.*/||' | grep -oE '^[0-9]+' | sort -n | tail -1)
|
|
@@ -488,21 +488,21 @@ next=$(printf '%03d' $(( 10#$(echo -e "${local_max:-0}\n${origin_max:-0}" | sort
|
|
|
488
488
|
|
|
489
489
|
If the local choice would have collided with an origin ticket created since the last fetch, the `git ls-tree origin/<base>` lookup catches it here and the renumber is automatic. Log the renumber decision in the operation report (e.g. "Bumped next ID from 042 → 043 to avoid collision with origin").
|
|
490
490
|
|
|
491
|
-
### 4. For new problems: Gather information (
|
|
491
|
+
### 4. For new problems: Gather information (the "Agents over-ask in interactive sessions — conflating mechanical-stages with user-interactive-stages of multi-stage skill contracts (inverse-)" problem derive-first; the "— Decision-Delegation Contract: when agents act on the framework vs ask the user" architecture rule category-4 silent-framework on derivable fields; category-1 direction-setting fallback only on Description)
|
|
492
492
|
|
|
493
|
-
**Shared dispatch helper**: this surface invokes `packages/itil/lib/derive-first-dispatch.sh` for the canonical slug derivation (Title), RISK-POLICY matrix lookup (Priority), and I2-isomorphic stderr advisory format. The helper is sourced by `/wr-itil:capture-problem`, `/wr-itil:manage-incident`, and `/wr-itil:manage-problem`; drift in the advisory shape re-opens
|
|
493
|
+
**Shared dispatch helper**: this surface invokes `packages/itil/lib/derive-first-dispatch.sh` for the canonical slug derivation (Title), RISK-POLICY matrix lookup (Priority), and I2-isomorphic stderr advisory format. The helper is sourced by `/wr-itil:capture-problem`, `/wr-itil:manage-incident`, and `/wr-itil:manage-problem`; drift in the advisory shape re-opens the "Agents over-ask in interactive sessions — conflating mechanical-stages with user-interactive-stages of multi-stage skill contracts (inverse-)" problem. Surface-specific signal definitions (priority impact / likelihood regex lists) stay inline below — the helper owns the mechanism, not the per-surface signals (architect verdict 2026-05-15 the "Agents over-ask in interactive sessions — conflating mechanical-stages with user-interactive-stages of multi-stage skill contracts (inverse-)" problem Phase 2a-iii-A: "Helper must preserve per-surface signal definitions; only the dispatch mechanism is shared").
|
|
494
494
|
|
|
495
495
|
**Derive-first dispatch.** Problem-declaration inputs carry observable evidence in the user's prose, the working tree, `RISK-POLICY.md`, and the wall-clock — the framework can resolve most fields without firing `AskUserQuestion`. Only **Description** is genuinely user-knowledge (without prose there is literally nothing to capture); only **Description** retains the AskUserQuestion gate.
|
|
496
496
|
|
|
497
|
-
The
|
|
497
|
+
The "Agents over-ask in interactive sessions — conflating mechanical-stages with user-interactive-stages of multi-stage skill contracts (inverse-)" problem inverse-the "Problem 078: Assistant does not offer to capture a problem ticket when the user delivers strong-signal correction" problem trap (`docs/problems/known-error/132-...md`) is the load-bearing motivation. The 2026-05-06 I001 declaration regression cited in the "Agents over-ask in interactive sessions — conflating mechanical-stages with user-interactive-stages of multi-stage skill contracts (inverse-)" problem fired a 4-question AskUserQuestion with 3 of 4 sub-questions being lazy classifications (Title kebab-derivable, Severity matrix-derivable, Start time git-log-derivable). manage-problem Step 4 is the second declaration-skill surface under Phase 2a (after manage-incident Step 4 in commit b7cc645) to ship the derive-first dispatch. The pattern is isomorphic across `/wr-itil:capture-problem` Step 1.5 (the "`/wr-itil:capture-problem` asks a classification question (technical vs user-business) that it can answer itself from the description's observable evidence" problem worked example), `/wr-itil:manage-incident` Step 4, and this skill.
|
|
498
498
|
|
|
499
499
|
Resolve each field via the following dispatch. **The order is load-bearing** — every field except Description resolves silently with a stderr advisory citing the source; Description alone fires `AskUserQuestion` as the genuine category-1 surface.
|
|
500
500
|
|
|
501
|
-
| Field | Dispatch |
|
|
501
|
+
| Field | Dispatch | the "— Decision-Delegation Contract: when agents act on the framework vs ask the user" architecture rule category |
|
|
502
502
|
|-------|----------|------------------|
|
|
503
503
|
| **Title** | Derive silently. Kebab-case the first 8-10 non-stopword tokens of the user's prose description (same slug derivation as `/wr-itil:capture-problem` Step 1.4 and `/wr-itil:manage-incident` Step 4). Emit stderr advisory: `manage-problem: derived title='<slug>' from description; re-invoke with the desired title or rename the file if the slug is wrong`. Do NOT fire AskUserQuestion. | category-4 silent-framework |
|
|
504
504
|
| **Description** | Pull verbatim from `$ARGUMENTS` prose into Step 5's `## Description` section. **Fallback**: when `$ARGUMENTS` carries NO prose at all (only flags / status / no body), fire AskUserQuestion as the genuine category-1 direction-setting surface — *"only the user knows the goals that haven't been written down yet."* Question text: *"What is happening? What should happen instead?"* This is the ONLY user-knowledge field at Step 4. | category-1 direction-setting (fallback only; category-4 silent-framework on the typical path where prose is present) |
|
|
505
|
-
| **Priority** (Impact × Likelihood) | Derive silently when description signals map to a clear `RISK-POLICY.md` Impact × Likelihood cell. Cross-reference signals: (a) **impact** — service-disruption keywords (`down` / `degraded` / `unavailable` / `data loss` → high; latency / throughput / slow → moderate; cosmetic / typo / minor friction → low); (b) **likelihood** — reproducibility keywords (`every invocation` / `reproducible` / `100%` → high; `intermittent` / `flaky` / `sometimes` → medium; `one-off` / `single observation` → low); (c) **named anchors** — explicit `Impact: <label>` / `Likelihood: <label>` or `Priority: <score>` mentions in prose take precedence. When the cross-reference produces a single clear cell, set it silently and emit stderr advisory: `manage-problem: priority derived as <score> (<label>) from RISK-POLICY matrix + evidence: <evidence list>; re-invoke or update if mis-rated`. **Ambiguous-evidence fallback** (no mappable signal, or signals point to conflicting cells): fire AskUserQuestion with the Impact (1-5) × Likelihood (1-5) options as the genuine
|
|
505
|
+
| **Priority** (Impact × Likelihood) | Derive silently when description signals map to a clear `RISK-POLICY.md` Impact × Likelihood cell. Cross-reference signals: (a) **impact** — service-disruption keywords (`down` / `degraded` / `unavailable` / `data loss` → high; latency / throughput / slow → moderate; cosmetic / typo / minor friction → low); (b) **likelihood** — reproducibility keywords (`every invocation` / `reproducible` / `100%` → high; `intermittent` / `flaky` / `sometimes` → medium; `one-off` / `single observation` → low); (c) **named anchors** — explicit `Impact: <label>` / `Likelihood: <label>` or `Priority: <score>` mentions in prose take precedence. When the cross-reference produces a single clear cell, set it silently and emit stderr advisory: `manage-problem: priority derived as <score> (<label>) from RISK-POLICY matrix + evidence: <evidence list>; re-invoke or update if mis-rated`. **Ambiguous-evidence fallback** (no mappable signal, or signals point to conflicting cells): fire AskUserQuestion with the Impact (1-5) × Likelihood (1-5) options as the genuine the "— Decision-Delegation Contract: when agents act on the framework vs ask the user" architecture rule **category-5 (taste)** fallback surface. The fallback is genuine ambiguity, NOT defaults. | category-4 silent-framework (derivable); category-5 fallback (ambiguous) |
|
|
506
506
|
|
|
507
507
|
**Inferred fields (no ask, no advisory needed)**:
|
|
508
508
|
|
|
@@ -513,15 +513,15 @@ Resolve each field via the following dispatch. **The order is load-bearing** —
|
|
|
513
513
|
|
|
514
514
|
**Stderr advisory contract**: each derived field emits a SINGLE line to stderr (NOT stdout, NOT in the ticket body) per the capture-problem Step 1.5 + manage-incident Step 4 pattern. The advisory text shape is I2-isomorphic — identical sentence structure across the three declaration-skill surfaces (`<skill>: derived <field>=<value> from <source>; <reversibility-clause>`) beyond substituted values + source names. Embedding the advisory in stdout would risk machine-readers parsing it as a ticket-body line; embedding it in the ticket body would violate the required-section schema. Stderr is the correct channel — visible to interactive maintainers in the terminal; invisible to ticket consumers; loggable by orchestrators that capture subprocess stderr.
|
|
515
515
|
|
|
516
|
-
**
|
|
516
|
+
**the "Agent output grounding — no fabricated quantitative estimates, cite + persist + uncertainty" architecture rule cost-source grounding**: each derived field cites its source in the advisory (description token sequence for Title; RISK-POLICY matrix cell + named evidence for Priority). The `re-invoke or update if mis-rated` clause carries the reversibility marker the "Agent output grounding — no fabricated quantitative estimates, cite + persist + uncertainty" architecture rule mandates for ungrounded outputs.
|
|
517
517
|
|
|
518
|
-
**AFK fail-safe (
|
|
518
|
+
**AFK fail-safe (the "Structured User Interaction for Governance-Skill Decisions" architecture rule Rule 6)**: under AFK orchestration, all derivable fields resolve without interactive input; only Description-when-absent can block. The orchestrator should halt-with-stderr citing the missing-prose case rather than guess (Description is genuinely user-judgment per the ": Progress the Backlog While I'm Away" user outcome's "Problems requiring my judgment ... are queued for my return, not guessed at"). The typical AFK manage-problem call carries prose in `$ARGUMENTS` (or the orchestrator's per-iter context supplies it), so the halt-on-Description path is the rare-corner-case behaviour, not the routine flow.
|
|
519
519
|
|
|
520
|
-
**Cross-skill consistency note**: this is the third declaration-skill surface to ship the derive-first dispatch (after `/wr-itil:capture-problem` Step 1.5 and `/wr-itil:manage-incident` Step 4 in commit b7cc645). The architect verdict 2026-05-15
|
|
520
|
+
**Cross-skill consistency note**: this is the third declaration-skill surface to ship the derive-first dispatch (after `/wr-itil:capture-problem` Step 1.5 and `/wr-itil:manage-incident` Step 4 in commit b7cc645). The architect verdict 2026-05-15 the "Agents over-ask in interactive sessions — conflating mechanical-stages with user-interactive-stages of multi-stage skill contracts (inverse-)" problem Phase 2a-ii flagged this triplet as the pattern-lock point — the I2-isomorphic stderr advisory format is now established across three skills before Phase 2a-iii (`/wr-architect:create-adr` argument-collection) extends the same pattern to a fourth.
|
|
521
521
|
|
|
522
522
|
### 4b. For new problems: Concern-boundary analysis (multi-concern check)
|
|
523
523
|
|
|
524
|
-
Before writing the problem file, perform a concern-boundary analysis on the gathered description to prevent conflated tickets that make WSJF scoring meaningless (
|
|
524
|
+
Before writing the problem file, perform a concern-boundary analysis on the gathered description to prevent conflated tickets that make WSJF scoring meaningless (the "Problem 016: `manage-problem` skill does not flag or split multi-concern tickets" problem).
|
|
525
525
|
|
|
526
526
|
**Self-check**: Read the description and root cause information gathered in step 4. Answer: "How many distinct root causes are present? If fixed independently, how many separate fix paths exist?"
|
|
527
527
|
|
|
@@ -537,9 +537,9 @@ Before writing the problem file, perform a concern-boundary analysis on the gath
|
|
|
537
537
|
|
|
538
538
|
**Non-interactive fallback**: When `AskUserQuestion` is unavailable (e.g., non-interactive/AFK mode), automatically split into separate problems and note the auto-split in output. Do not block creation.
|
|
539
539
|
|
|
540
|
-
**
|
|
540
|
+
**the "Structured User Interaction for Governance-Skill Decisions" architecture rule Rule 6 carve-out audit (the "AFK iter default when a skill needs to ask a question and AskUserQuestion is unavailable — should queue the question and move to the next iteration (not halt, not silently skip)" problem, 2026-06-06 amendment)**: the universal AFK default is **queue-and-continue**; this site is a documented **AUTO-DEFAULT** carve-out. Authorising principle: policy-authorised safe default per the "— Decision-Delegation Contract: when agents act on the framework vs ask the user" architecture rule category 4 (silent framework). Splitting is fully reversible (manual combine via Related cross-references + WSJF re-rank), the framework's lifecycle model rewards explicit per-concern WSJF ranking, and "split when in doubt" is the persona-correct safe heuristic for the ": Progress the Backlog While I'm Away" user outcome — the loop progresses, over-splits are cheap to combine, and halt would cost more loop throughput than the over-split risk. Symmetric with the parallel `/wr-architect:create-adr` Step 1 multi-decision auto-split (same authority, same rationale).
|
|
541
541
|
|
|
542
|
-
**Split implementation**: When splitting, assign consecutive IDs (e.g., if next ID is 035, create
|
|
542
|
+
**Split implementation**: When splitting, assign consecutive IDs (e.g., if next ID is 035, create the "Problem 035: manage-problem commit gate has no fallback when subagent delegation is unavailable" problem and the "Problem 036: work-problems orchestrator does not verify commit-landing between iterations" problem). Create each problem file independently. Cross-reference each ticket in the other's "Related" section.
|
|
543
543
|
|
|
544
544
|
**Scope**: This step applies only to **new problem creation** (steps 2–5). It does NOT apply to updates, status transitions, or reviews of existing tickets.
|
|
545
545
|
|
|
@@ -595,58 +595,58 @@ Before writing the problem file, perform a concern-boundary analysis on the gath
|
|
|
595
595
|
<links to related files, problems, ADRs>
|
|
596
596
|
```
|
|
597
597
|
|
|
598
|
-
**`**Origin**` field (
|
|
598
|
+
**`**Origin**` field (the "Inbound-reported problems rank ahead of internally-discovered problems via a sort tier" architecture rule)** records where the problem came from and is an authoritative input to the "Inbound-reported problems rank ahead of internally-discovered problems via a sort tier" architecture rule reported-first ranking tier. Two values:
|
|
599
599
|
|
|
600
600
|
- `internal` — internally discovered (the default for tickets created by hand or by an internal observation).
|
|
601
|
-
- `inbound-reported (#NN)` — reported to us by an external user via an upstream channel, where `#NN` is the upstream issue/discussion number. Written by
|
|
601
|
+
- `inbound-reported (#NN)` — reported to us by an external user via an upstream channel, where `#NN` is the upstream issue/discussion number. Written by the "Inbound upstream-report discovery + assessment pipeline (peer of )" architecture rule'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 (the "Inbound-reported problems rank ahead of internally-discovered problems via a sort tier" architecture rule). When backfilling existing tickets during a review, stamp reported ones with `inbound-reported (#NN)`; leave the rest `internal`.
|
|
602
602
|
|
|
603
|
-
The `## Dependencies` section uses **bare ticket IDs** (`
|
|
603
|
+
The `## Dependencies` section uses **bare ticket IDs** (`the "Problem 038: No voice-and-tone gate on external communications" problem`, not `[the "Problem 038: No voice-and-tone gate on external communications" problem](./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.
|
|
604
604
|
|
|
605
|
-
**Concrete example** (for
|
|
605
|
+
**Concrete example** (for the "Problem 073: No voice-and-tone check or risk assessment on changeset bodies (which populate CHANGELOG.md, Release PRs, GitHub Releases, and npm release notes)" problem referencing two upstreams):
|
|
606
606
|
|
|
607
607
|
```markdown
|
|
608
608
|
## Dependencies
|
|
609
609
|
|
|
610
610
|
- **Blocks**: (none)
|
|
611
|
-
- **Blocked by**:
|
|
611
|
+
- **Blocked by**: the "Problem 038: No voice-and-tone gate on external communications" problem, the "Problem 064: No risk-scoring gate on external communications" problem
|
|
612
612
|
- **Composes with**: (none)
|
|
613
613
|
```
|
|
614
614
|
|
|
615
|
-
#### README.md refresh on new ticket (
|
|
615
|
+
#### README.md refresh on new ticket (the "Problem 094: `/wr-itil:manage-problem` does not refresh `docs/problems/README.md` on ticket creation" problem)
|
|
616
616
|
|
|
617
617
|
After writing the new `.open.md` file, regenerate `docs/problems/README.md` to insert the new ticket's row into the WSJF Rankings, and stage the refreshed README in the same commit as the new ticket. Without this refresh, new tickets are absent from the ranked table until the next `/wr-itil:review-problems` invocation or the next Step 7 transition — staleness accumulates silently on every creation-only session.
|
|
618
618
|
|
|
619
|
-
**Mechanism**: use the same rendering rules as Step 7's
|
|
619
|
+
**Mechanism**: use the same rendering rules as Step 7's the "Problem 062: `manage-problem` does not refresh `docs/problems/README.md` on single-ticket transitions; fast-path cache goes stale silently" problem 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 the "Problem 062: `manage-problem` does not refresh `docs/problems/README.md` on single-ticket transitions; fast-path cache goes stale silently" problem's established discipline. Only the new ticket's own WSJF is consumed from its freshly-written file.
|
|
620
620
|
|
|
621
|
-
**WSJF Rankings tier + tie-break sort (
|
|
621
|
+
**WSJF Rankings tier + tie-break sort (the "`docs/problems/README.md` WSJF Rankings table row order doesn't match `/wr-itil:work-problems`'s tie-break selection — users assume the orchestrator is broken" problem + the "Inbound-reported problems rank ahead of internally-discovered problems via a sort tier" architecture rule)**: 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 "Inbound-reported problems rank ahead of internally-discovered problems via a sort tier" architecture rule 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 (the "Inbound-reported problems rank ahead of internally-discovered problems via a sort tier" architecture rule) --> <!-- 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 the "Problem 062: `manage-problem` does not refresh `docs/problems/README.md` on single-ticket transitions; fast-path cache goes stale silently" problem block, the Step 9e template, AND `/wr-itil:review-problems` SKILL.md Step 3 / Step 5 — drift here re-opens the "`docs/problems/README.md` WSJF Rankings table row order doesn't match `/wr-itil:work-problems`'s tie-break selection — users assume the orchestrator is broken" problem / the "Inbound-reported problems rank ahead of internally-discovered problems via a sort tier" architecture rule.
|
|
622
622
|
|
|
623
|
-
**Verification Queue sort direction (
|
|
623
|
+
**Verification Queue sort direction (the "docs/problems/README.md Verification Queue rendered newest-first contradicts section header "Ranked by release age, oldest first"" problem)**: rows in the Verification Queue table are sorted by `Released date ASC` (oldest at row 1; same-day releases tiebreak by ID ASC) per the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule + the "Problem 048: manage-problem does not surface Fix Released problems as verification candidates when the fix path has been exercised" problem 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 the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule --> Any future change to the VQ sort direction MUST update this render block, the Step 7 the "Problem 062: `manage-problem` does not refresh `docs/problems/README.md` on single-ticket transitions; fast-path cache goes stale silently" problem 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 the "docs/problems/README.md Verification Queue rendered newest-first contradicts section header "Ranked by release age, oldest first"" problem.
|
|
624
624
|
|
|
625
|
-
**Likely-verified cell shape (
|
|
625
|
+
**Likely-verified cell shape (the "VQ `Likely verified?` column uses age-based heuristic (≥14 days = yes) instead of session-observed evidence — sibling proxy-for-evidence anti-pattern to" problem)**: the `Likely verified?` column carries an **evidence-first** cell — `yes — observed: <evidence>` / `no — not observed` / `no — observed regression`. The 14-day age-based heuristic (originally introduced by the "Problem 048: manage-problem does not surface Fix Released problems as verification candidates when the fix path has been exercised" problem Candidate 4) is superseded — age is preserved separately via the `Released` column; the `Likely verified?` column is reserved for session-observed evidence (Step 4 user confirmation, in-session test invocation outcome per the "Agent output grounding — no fabricated quantitative estimates, cite + persist + uncertainty" architecture rule grounding, or `run-retro` Step 4a close-on-evidence citation). <!-- LIKELY-VERIFIED-CELL-SHAPE: evidence-based per the "VQ `Likely verified?` column uses age-based heuristic (≥14 days = yes) instead of session-observed evidence — sibling proxy-for-evidence anti-pattern to" problem --> Any future change to the cell shape MUST update this render block, the Step 7 the "Problem 062: `manage-problem` does not refresh `docs/problems/README.md` on single-ticket transitions; fast-path cache goes stale silently" problem 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 the "VQ `Likely verified?` column uses age-based heuristic (≥14 days = yes) instead of session-observed evidence — sibling proxy-for-evidence anti-pattern to" problem.
|
|
626
626
|
|
|
627
627
|
1. After `Write`-ing the new `.open.md` file (and, for multi-concern splits per step 4b, after all split files are written), regenerate `docs/problems/README.md` in-place reflecting the new filename set.
|
|
628
|
-
2. Update the "Last reviewed" line per the **inline
|
|
628
|
+
2. Update the "Last reviewed" line per the **inline the "`docs/problems/README.md` line 3 narrative-blob accumulator bloat — sibling to (briefing tier 3) on a different surface" problem rotation mechanism** below. The mechanism is inlined here at the execution site (not deferred via cross-reference to the § Last-reviewed line discipline subsection further down this SKILL) so a single-pass agent reading this Step 5 does not silently skip the archive step. **Skipping the BEFORE-rewrite archive step destroys the displaced fragment and re-opens the "transition-problem SKILL Step 7 Last-reviewed rotation silently skipped across iters" problem** (iter-7 + iter-8 of 2026-05-30's AFK work-problems session silently skipped the rotation in 2 of 9 transition-bearing iters under exactly that failure mode). The mechanism MUST execute IN ORDER:
|
|
629
629
|
|
|
630
630
|
1. **Read** line 3 of `docs/problems/README.md`: `awk 'NR==3' docs/problems/README.md` (`head -3 | tail -1` or `sed -n '3p'` are acceptable equivalents).
|
|
631
631
|
2. **Append-if-non-empty (BEFORE step 3, not after)** — if line 3 is non-empty AND not a same-session same-verb near-duplicate of the new fragment, append the existing line 3 verbatim to `docs/problems/README-history.md` under a `## YYYY-MM-DD` heading (creating the heading on first append for that date; subsequent same-day appends nest under the existing heading). Run this BEFORE the Edit-tool rewrite in step 3 — Edit's replace pattern destroys the displaced content otherwise.
|
|
632
|
-
3. **Rewrite** line 3 of `docs/problems/README.md` with the new fragment of form `> Last reviewed: YYYY-MM-DD **<event>** — <one-line summary>` (e.g. `P<NNN> opened — <one-line title>`). Soft cap ≤ 1024 bytes per fragment; hard ceiling 5120 bytes per
|
|
633
|
-
4. **Stage both** — `git add docs/problems/README.md docs/problems/README-history.md` so the same single commit per
|
|
632
|
+
3. **Rewrite** line 3 of `docs/problems/README.md` with the new fragment of form `> Last reviewed: YYYY-MM-DD **<event>** — <one-line summary>` (e.g. `P<NNN> opened — <one-line title>`). Soft cap ≤ 1024 bytes per fragment; hard ceiling 5120 bytes per the "Session-start briefing surface — SessionStart hook over tiered directory + indexed README" architecture rule Tier 3 envelope.
|
|
633
|
+
4. **Stage both** — `git add docs/problems/README.md docs/problems/README-history.md` so the same single commit per the "Governance Skills Commit Their Own Completed Work" architecture rule captures both files.
|
|
634
634
|
|
|
635
|
-
Canonical rationale anchor: § Last-reviewed line discipline (
|
|
635
|
+
Canonical rationale anchor: § Last-reviewed line discipline (the "`docs/problems/README.md` line 3 narrative-blob accumulator bloat — sibling to (briefing tier 3) on a different surface" problem) subsection below. The cross-reference is preserved for the "why"; the "what" is inlined above for execution-time legibility per the "transition-problem SKILL Step 7 Last-reviewed rotation silently skipped across iters" problem.
|
|
636
636
|
3. `git add docs/problems/README.md` — the stage list at Step 11 must include it alongside the new `.open.md` file (Step 11's `git add -u` catch-all handles tracked-file modifications; the new README render lands via this path when README.md already exists in git, and via an explicit `git add docs/problems/README.md` when it is newly created). When line-3 truncation displaces prior content, also `git add docs/problems/README-history.md`.
|
|
637
637
|
|
|
638
638
|
For the multi-concern split path (step 4b), the refresh fires **once** after all split tickets are written, not per-split — a single render captures the full new set in one pass.
|
|
639
639
|
|
|
640
|
-
#### Last-reviewed line discipline (
|
|
640
|
+
#### Last-reviewed line discipline (the "`docs/problems/README.md` line 3 narrative-blob accumulator bloat — sibling to (briefing tier 3) on a different surface" problem)
|
|
641
641
|
|
|
642
|
-
The "Last reviewed" line (line 3 of `docs/problems/README.md`) was designed as a short audit marker — one ticket name + one transition reason — but historically accumulated multi-paragraph session-summary fragments unbounded ("Prior:" stacking on every refresh). At ~62 KB / 76 KB it crossed the Read-tool 25K-token whole-file limit and could no longer be window-read at any offset/limit.
|
|
642
|
+
The "Last reviewed" line (line 3 of `docs/problems/README.md`) was designed as a short audit marker — one ticket name + one transition reason — but historically accumulated multi-paragraph session-summary fragments unbounded ("Prior:" stacking on every refresh). At ~62 KB / 76 KB it crossed the Read-tool 25K-token whole-file limit and could no longer be window-read at any offset/limit. the "`docs/problems/README.md` line 3 narrative-blob accumulator bloat — sibling to (briefing tier 3) on a different surface" problem closes the accumulator on this surface; sibling to the "Problem 099: `docs/BRIEFING.md` grows unbounded via run-retro appends — violates progressive disclosure" problem on `docs/briefing/<topic>.md`.
|
|
643
643
|
|
|
644
|
-
**Contract** — applies to every refresh that touches line 3 (Step 5
|
|
644
|
+
**Contract** — applies to every refresh that touches line 3 (Step 5 the "Problem 094: `/wr-itil:manage-problem` does not refresh `docs/problems/README.md` on ticket creation" problem creation, Step 6 the "Problem 094: `/wr-itil:manage-problem` does not refresh `docs/problems/README.md` on ticket creation" problem conditional update, Step 7 the "Problem 062: `manage-problem` does not refresh `docs/problems/README.md` on single-ticket transitions; fast-path cache goes stale silently" problem transition; mirrored in `transition-problem`, `transition-problems`, `review-problems`, `reconcile-readme`):
|
|
645
645
|
|
|
646
646
|
1. **Single most-recent fragment only on line 3.** The "Last reviewed" parenthetical names ONE event — the operation this refresh covers. Do NOT prepend a `Prior:` segment, do NOT stack multi-paragraph rationale, do NOT carry history forward inline.
|
|
647
647
|
2. **Soft cap: ≤ 1024 bytes per fragment.** Authoring guidance — keep the fragment dense and audit-meaningful (ticket ID + verb + one-line summary + ADR/JTBD anchors when load-bearing). Multi-paragraph rationale belongs in retros, ticket bodies, and ADR amendments — never on line 3.
|
|
648
648
|
3. **Archive sibling: `docs/problems/README-history.md`.** When this refresh would displace prior line-3 content, append the displaced content to `README-history.md` BEFORE writing the new line 3. Forward-chronology — newest fragment goes at the bottom under a date heading (`## YYYY-MM-DD`). The archive is a log; it's grep-and-tail territory, not display-tier (which is why its chronology diverges from the README's reverse-chrono surface convention).
|
|
649
|
-
4. **Hard ceiling: 5120 bytes on line 3.** Matches
|
|
649
|
+
4. **Hard ceiling: 5120 bytes on line 3.** Matches the "Session-start briefing surface — SessionStart hook over tiered directory + indexed README" architecture rule Tier 3 envelope. Surfaced advisory-only by `wr-itil-check-problems-readme-budget` (`$PATH`-resolved shim per the "Plugin-bundled scripts invoked from SKILL.md resolve via `bin/` on `$PATH`" architecture rule; canonical body at `packages/itil/scripts/check-problems-readme-budget.sh`) — the script emits `OVER docs/problems/README.md line=3 bytes=<N> threshold=<N>` when the ceiling is breached. Always exits 0 (advisory; overflow is signal, not failure).
|
|
650
650
|
|
|
651
651
|
**Mechanism** (when authoring a refresh):
|
|
652
652
|
|
|
@@ -654,15 +654,15 @@ The "Last reviewed" line (line 3 of `docs/problems/README.md`) was designed as a
|
|
|
654
654
|
2. If the current line 3 is non-empty AND the new fragment is not a near-duplicate (same ticket + same verb in the same session): append the current line 3 verbatim to `docs/problems/README-history.md` under a `## YYYY-MM-DD` heading (creating the heading on first append for that date; subsequent same-day appends nest under the existing heading).
|
|
655
655
|
3. Compose the new line 3 as a single paragraph naming the operation only. Keep ≤ 1024 bytes.
|
|
656
656
|
4. Replace line 3 of README.md with the new paragraph.
|
|
657
|
-
5. Stage both files in the same commit as the ticket change per
|
|
657
|
+
5. Stage both files in the same commit as the ticket change per the "Governance Skills Commit Their Own Completed Work" architecture rule: `git add docs/problems/README.md docs/problems/README-history.md`.
|
|
658
658
|
|
|
659
659
|
**Fast-path interaction**: the Step 9 freshness check uses git-mtime on `docs/problems/README.md`, NOT the prose contents of line 3. Truncating line 3 does NOT degrade the fast-path contract.
|
|
660
660
|
|
|
661
|
-
**Cross-references**:
|
|
661
|
+
**Cross-references**: the "Session-start briefing surface — SessionStart hook over tiered directory + indexed README" architecture rule line 92 (reusable accumulator-doc pattern — explicitly names "problems index"), the "Progressive disclosure + once-per-session budget for UserPromptSubmit governance prose" architecture rule (progressive disclosure), the "Governance Skills Commit Their Own Completed Work" architecture rule (single-commit governance), the "Plugin-bundled scripts invoked from SKILL.md resolve via `bin/` on `$PATH`" architecture rule (plugin-bundled scripts via `bin/` on `$PATH`), `wr-itil-check-problems-readme-budget` shim (canonical body at `packages/itil/scripts/check-problems-readme-budget.sh`), `packages/itil/scripts/test/check-problems-readme-budget.bats`.
|
|
662
662
|
|
|
663
663
|
### 6. For updates: Edit the existing file
|
|
664
664
|
|
|
665
|
-
Find the file matching the problem ID. Dual-tolerant lookup spans the flat layout AND the per-state subdir layout per
|
|
665
|
+
Find the file matching the problem ID. Dual-tolerant lookup spans the flat layout AND the per-state subdir layout per the ": docs/problems/ flat layout migration — per-state subdirs + adopter auto-migration" release design migration window:
|
|
666
666
|
```bash
|
|
667
667
|
ls docs/problems/<NNN>-*.md docs/problems/*/<NNN>-*.md 2>/dev/null
|
|
668
668
|
```
|
|
@@ -674,7 +674,7 @@ Apply the update — this could be:
|
|
|
674
674
|
- Adding "Related" links
|
|
675
675
|
- Updating priority based on new information
|
|
676
676
|
|
|
677
|
-
#### README.md refresh on conditional update (
|
|
677
|
+
#### README.md refresh on conditional update (the "Problem 094: `/wr-itil:manage-problem` does not refresh `docs/problems/README.md` on ticket creation" problem)
|
|
678
678
|
|
|
679
679
|
If the update changed the ticket's **Priority**, **Effort**, or **WSJF** line, regenerate `docs/problems/README.md` to reflect the new ranking and stage it in the same commit as the update. If the update was to other sections (Root Cause Analysis, Symptoms, Related, Dependencies, etc.) and did NOT change the ranking-bearing fields, skip the refresh — the rendered table would be identical and the cost is not load-bearing.
|
|
680
680
|
|
|
@@ -688,36 +688,36 @@ If the edit touched only `## Root Cause Analysis`, `## Symptoms`, `## Workaround
|
|
|
688
688
|
|
|
689
689
|
**Mechanism** (when the trigger fires):
|
|
690
690
|
|
|
691
|
-
1. Regenerate `docs/problems/README.md` using the same render rules as Step 7's
|
|
692
|
-
2. Update the "Last reviewed" line per the **inline
|
|
691
|
+
1. Regenerate `docs/problems/README.md` using the same render rules as Step 7's the "Problem 062: `manage-problem` does not refresh `docs/problems/README.md` on single-ticket transitions; fast-path cache goes stale silently" problem block — render, not re-rank. Trust every other ticket's stored WSJF; consume only this ticket's updated WSJF from the post-edit file.
|
|
692
|
+
2. Update the "Last reviewed" line per the **inline the "`docs/problems/README.md` line 3 narrative-blob accumulator bloat — sibling to (briefing tier 3) on a different surface" problem rotation mechanism** below. The mechanism is inlined here at the execution site (not deferred via cross-reference to the § Last-reviewed line discipline subsection further up this SKILL) so a single-pass agent reading this Step 6 does not silently skip the archive step. **Skipping the BEFORE-rewrite archive step destroys the displaced fragment and re-opens the "transition-problem SKILL Step 7 Last-reviewed rotation silently skipped across iters" problem**. The mechanism MUST execute IN ORDER:
|
|
693
693
|
|
|
694
694
|
1. **Read** line 3 of `docs/problems/README.md`: `awk 'NR==3' docs/problems/README.md`.
|
|
695
695
|
2. **Append-if-non-empty (BEFORE step 3, not after)** — if line 3 is non-empty AND not a same-session same-verb near-duplicate of the new fragment, append the existing line 3 verbatim to `docs/problems/README-history.md` under a `## YYYY-MM-DD` heading (creating the heading on first append for that date). Run this BEFORE the Edit-tool rewrite in step 3 — Edit's replace pattern destroys the displaced content otherwise.
|
|
696
|
-
3. **Rewrite** line 3 of `docs/problems/README.md` with the new fragment of form `> Last reviewed: YYYY-MM-DD **<event>** — <one-line summary>` (e.g. `P<NNN> re-rated — <old-WSJF> → <new-WSJF>`). Soft cap ≤ 1024 bytes; hard ceiling 5120 bytes per
|
|
697
|
-
4. **Stage both** — `git add docs/problems/README.md docs/problems/README-history.md` so the same single commit per
|
|
696
|
+
3. **Rewrite** line 3 of `docs/problems/README.md` with the new fragment of form `> Last reviewed: YYYY-MM-DD **<event>** — <one-line summary>` (e.g. `P<NNN> re-rated — <old-WSJF> → <new-WSJF>`). Soft cap ≤ 1024 bytes; hard ceiling 5120 bytes per the "Session-start briefing surface — SessionStart hook over tiered directory + indexed README" architecture rule Tier 3 envelope.
|
|
697
|
+
4. **Stage both** — `git add docs/problems/README.md docs/problems/README-history.md` so the same single commit per the "Governance Skills Commit Their Own Completed Work" architecture rule captures both files.
|
|
698
698
|
|
|
699
|
-
Canonical rationale anchor: § Last-reviewed line discipline (
|
|
700
|
-
3. `git add docs/problems/README.md` so the refresh rides the same commit as the ticket update per
|
|
699
|
+
Canonical rationale anchor: § Last-reviewed line discipline (the "`docs/problems/README.md` line 3 narrative-blob accumulator bloat — sibling to (briefing tier 3) on a different surface" problem) subsection in Step 5 above. The cross-reference is preserved for the "why"; the "what" is inlined above for execution-time legibility per the "transition-problem SKILL Step 7 Last-reviewed rotation silently skipped across iters" problem.
|
|
700
|
+
3. `git add docs/problems/README.md` so the refresh rides the same commit as the ticket update per the "Governance Skills Commit Their Own Completed Work" architecture rule. When line-3 truncation displaces prior content, also `git add docs/problems/README-history.md`.
|
|
701
701
|
|
|
702
|
-
**Dependency ripple**: if this update changed the ticket's Effort, and the ticket is an upstream of other tickets (any ticket's `## Dependencies` → `**Blocked by**` list references this ID), the transitive-effort rule (
|
|
702
|
+
**Dependency ripple**: if this update changed the ticket's Effort, and the ticket is an upstream of other tickets (any ticket's `## Dependencies` → `**Blocked by**` list references this ID), the transitive-effort rule (the "Problem 076: WSJF scoring in manage-problem does not model transitive dependencies" problem) says dependents may need to re-rate too. The surgical render in this step does NOT re-walk the graph — that is Step 9b.1's job. If the dependency graph is known to be non-trivial, prefer `/wr-itil:review-problems` instead of a bare update; the review path handles the re-walk deterministically. The conditional refresh here is sufficient for the common case of a self-only re-rate.
|
|
703
703
|
|
|
704
704
|
### 7. For status transitions
|
|
705
705
|
|
|
706
706
|
**Open → Known Error** (rename file, update content):
|
|
707
707
|
|
|
708
|
-
Known Error means "root cause identified AND workaround documented; fix not yet proposed" (per
|
|
708
|
+
Known Error means "root cause identified AND workaround documented; fix not yet proposed" (per the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule corrected semantics, 2026-06-08 amendment). The fix is proposed AFTER Known Error, by drawing a release row on a story map. Releasing the fix is a separate Known Error → Verification Pending transition — do NOT stay on `.known-error.md` after the fix ships.
|
|
709
709
|
|
|
710
710
|
Pre-flight checks before allowing transition:
|
|
711
711
|
- [ ] Root cause is documented (not just "Preliminary Hypothesis")
|
|
712
712
|
- [ ] At least one investigation task is checked off
|
|
713
713
|
- [ ] A reproduction test exists or is referenced
|
|
714
714
|
- [ ] A workaround is documented (even if "feature disabled")
|
|
715
|
-
- [ ] Effort bucket re-rated against the now-documented fix strategy; if the bucket changed since creation, update the Effort / WSJF lines and note the reason (
|
|
716
|
-
- [ ] Status multiplier re-rated from Open 1.0 to Known Error 2.0; recompute WSJF with the post-transition status and current Effort (
|
|
715
|
+
- [ ] Effort bucket re-rated against the now-documented fix strategy; if the bucket changed since creation, update the Effort / WSJF lines and note the reason (the "Problem 047: WSJF effort buckets are coarse and not re-rated at lifecycle transitions" problem — creation-time estimates drift as scope clarifies)
|
|
716
|
+
- [ ] Status multiplier re-rated from Open 1.0 to Known Error 2.0; recompute WSJF with the post-transition status and current Effort (the "WSJF uses the pre-transition status multiplier" problem)
|
|
717
717
|
|
|
718
718
|
If any check fails, report which checks failed and ask the user to address them before transitioning.
|
|
719
719
|
|
|
720
|
-
#### External-root-cause detection (
|
|
720
|
+
#### External-root-cause detection (the "Problem 063: manage-problem does not trigger /wr-itil:report-upstream when root cause is external" problem)
|
|
721
721
|
|
|
722
722
|
Before renaming the file, scan the ticket's Root Cause Analysis section for external-root-cause markers. The same detection fires when parking a ticket with the `upstream-blocked` reason (see the Parked lifecycle entry at the top of this skill — it routes back to this block).
|
|
723
723
|
|
|
@@ -734,25 +734,25 @@ if grep -iE '\b(upstream|third-party|external|vendor)\b|@[[:alnum:]_-]+/[[:alnum
|
|
|
734
734
|
fi
|
|
735
735
|
```
|
|
736
736
|
|
|
737
|
-
Detection is intentionally **strict** (explicit label or scoped-npm package only) to avoid prompt fatigue (
|
|
737
|
+
Detection is intentionally **strict** (explicit label or scoped-npm package only) to avoid prompt fatigue (the "Problem 063: manage-problem does not trigger /wr-itil:report-upstream when root cause is external" problem Direction decision). A passing reference to a bare package name (`gh`, `npm`) does NOT trigger the prompt.
|
|
738
738
|
|
|
739
|
-
**Already-noted check** — before firing the prompt, grep the ticket for the stable marker `- **Upstream report pending** --` (canonical ASCII form per
|
|
739
|
+
**Already-noted check** — before firing the prompt, grep the ticket for the stable marker `- **Upstream report pending** --` (canonical ASCII form per the "work-problems SKILL.md AFK-fallback marker wording uses em-dash, forces consumer-side whitespace surgery" problem) or the legacy em-dash variant `- **Upstream report pending** —` (written by option 2 / the AFK fallback below; the grep MUST match BOTH variants for backward compatibility) or `- **Reported Upstream:**` / a `## Reported Upstream` section (written by `/wr-itil:report-upstream` Step 7 back-write per the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule Confirmation criterion 3a). If any of those are already present, skip the prompt — the detection has already fired on a prior run.
|
|
740
740
|
|
|
741
741
|
**If the detection fires and nothing has been noted yet**, use `AskUserQuestion`:
|
|
742
742
|
|
|
743
743
|
- `header: "External root cause detected"`
|
|
744
744
|
- `multiSelect: false`
|
|
745
745
|
- Options:
|
|
746
|
-
1. `Invoke /wr-itil:report-upstream now` — halt the transition; the skill runs (it writes the `## Reported Upstream` appendage per
|
|
747
|
-
2. `Defer and note in ticket` — append a pending-upstream-report line to the ticket's `## Related` section using the stable marker `- **Upstream report pending** -- external dependency identified; invoke /wr-itil:report-upstream when ready`. The marker wording is fixed (ASCII `--` per
|
|
746
|
+
1. `Invoke /wr-itil:report-upstream now` — halt the transition; the skill runs (it writes the `## Reported Upstream` appendage per the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule Confirmation criterion 3a); the transition resumes afterwards.
|
|
747
|
+
2. `Defer and note in ticket` — append a pending-upstream-report line to the ticket's `## Related` section using the stable marker `- **Upstream report pending** -- external dependency identified; invoke /wr-itil:report-upstream when ready`. The marker wording is fixed (ASCII `--` per the "work-problems SKILL.md AFK-fallback marker wording uses em-dash, forces consumer-side whitespace surgery" problem — ASCII-only in machine-parseable identifiers; em-dash permitted in pure narrative prose) so subsequent runs (and the work-problems `upstream-blocked` skip path) can detect "already noted" without re-firing.
|
|
748
748
|
3. `Not actually upstream` — proceed without invocation; append the same marker with text `- **Upstream report pending** -- false positive; detection misfire` so the prompt does not re-fire on later reviews.
|
|
749
749
|
|
|
750
|
-
**Non-interactive (AFK) branch** (per
|
|
750
|
+
**Non-interactive (AFK) branch** (per the "Structured User Interaction for Governance-Skill Decisions" architecture rule Rule 6 + the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule 2026-06-04 (the "Agent waits for human to initiate upstream report instead of filing on detect — feedback delay class" problem) amendment): when `AskUserQuestion` is unavailable, **auto-invoke `/wr-itil:report-upstream`** instead of deferring with the marker. The skill composes the report draft via its own Steps 1–5/4b/5c/6 then scores the drafted prose via the `wr-risk-scorer:external-comms` agent (the "External-comms gate — voice-tone + risk/leak evaluators on shared PreToolUse surface" architecture rule) per the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule 2026-06-04 amendment's orchestrator-side pre-fire gate. Branches:
|
|
751
751
|
|
|
752
752
|
- **Below external-comms appetite** → the skill proceeds (public-issue path Step 5, comment path Step 5c, or security path Step 6 per the existing classification routing); commits the `## Reported Upstream` back-write per Step 7 / Step 8.
|
|
753
|
-
- **Above appetite** → the skill takes risk-reducing measures (per
|
|
753
|
+
- **Above appetite** → the skill takes risk-reducing measures (per the "Auto-apply scorer remediations to reach within appetite — open action-class vocabulary" architecture rule within-axis precedent generalised to the external-comms risk class — the measures vocabulary is **open-ended LLM judgement** per the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule 2026-06-04 second-amendment ratification leaf (a): the `wr-risk-scorer:external-comms` agent's own scoring picks the remedy case-by-case, matching the "Auto-apply scorer remediations to reach within appetite — open action-class vocabulary" architecture rule's open-vocabulary precedent — NOT a bounded enumeration); re-scores; if within appetite → sends; else → **queues** an `outstanding_questions` entry naming the local ticket ID + queued report path + risk-reduce attempts + residual band + remedy ("review the queued report at `/wr-itil:report-upstream <NNN> <upstream-repo-url>` on return"). The orchestrator continues (the "AFK iter default when a skill needs to ask a question and AskUserQuestion is unavailable — should queue the question and move to the next iteration (not halt, not silently skip)" problem queue-and-continue). The `## Queued Upstream Report` section (renamed from `## Drafted Upstream Report` per the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule 2026-06-04 second-amendment leaf (c) — same shape; new name reflects the queue-for-review-on-return semantics) carries the report content for the queued question's reference. Security-path routing follows leaf (b) ratification: upstream-with-`SECURITY.md` + below-appetite → file via the declared channel; upstream-without-`SECURITY.md` but with another disclosure channel → external-comms-gated assessment considering impact to (i) our repository, (ii) our reputation, (iii) the party we are reporting to.
|
|
754
754
|
|
|
755
|
-
The legacy `- **Upstream report pending** --` marker append (canonical ASCII per
|
|
755
|
+
The legacy `- **Upstream report pending** --` marker append (canonical ASCII per the "work-problems SKILL.md AFK-fallback marker wording uses em-dash, forces consumer-side whitespace surgery" problem; em-dash variant is the pre-the "work-problems SKILL.md AFK-fallback marker wording uses em-dash, forces consumer-side whitespace surgery" problem form, still matched for backward compatibility) — the pre-2026-06-04 AFK default — is **superseded** by this auto-invoke branch for all classifications including security. Tickets that already carry the marker from prior sessions (either form) are still handled correctly by the work-problems Step 4 classifier — the new path's "already-noted check" matches both variants and routes to the report-upstream invocation. The marker shape is retained for backward compatibility on the parking + interactive fallback paths (interactive option 2 still appends it; see options 1/2/3 above).
|
|
756
756
|
|
|
757
757
|
**Scope**: this detection block fires at two points —
|
|
758
758
|
|
|
@@ -761,7 +761,7 @@ The legacy `- **Upstream report pending** --` marker append (canonical ASCII per
|
|
|
761
761
|
|
|
762
762
|
The work-problems orchestrator's `upstream-blocked` skip path (see `packages/itil/skills/work-problems/SKILL.md` classifier table) runs the AFK fallback before skipping, so ticket bodies accumulate the marker even when the orchestrator never invokes `manage-problem` on them.
|
|
763
763
|
|
|
764
|
-
> **Staging trap (
|
|
764
|
+
> **Staging trap (the "Problem 057: `git mv` + Edit + `git add` staging-ordering trap drops content edits from the commit" problem).** `git mv` stages only the rename — it does NOT pick up subsequent `Edit`-tool content changes. After the `Edit` tool modifies the renamed file (Status field, `## Fix Released` section, etc.), re-stage it explicitly: `git add <new>`. Without the explicit re-stage, the transition commit captures the rename-only change and the content edit leaks into the next commit, corrupting the audit trail. This rule applies to every `git mv` block below (Open → Known Error, Known Error → Verification Pending, Verification Pending → Closed) and to the supersession rename in `create-adr` Step 6.
|
|
765
765
|
|
|
766
766
|
```bash
|
|
767
767
|
git mv docs/problems/open/<NNN>-<title>.md docs/problems/known-error/<NNN>-<title>.md
|
|
@@ -771,13 +771,13 @@ git add docs/problems/known-error/<NNN>-<title>.md
|
|
|
771
771
|
|
|
772
772
|
Update the "Status" field in the file to "Known Error".
|
|
773
773
|
|
|
774
|
-
**Known Error → Verification Pending** (fix released, per
|
|
774
|
+
**Known Error → Verification Pending** (fix released, per the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule):
|
|
775
775
|
|
|
776
776
|
When the fix for a Known Error ships, transition the ticket in a single commit.
|
|
777
777
|
|
|
778
|
-
#### Conditional-deferral check BEFORE the rename (
|
|
778
|
+
#### Conditional-deferral check BEFORE the rename (the "Agent treats conditionally-deferred work (deferred-pending-X-graduation) as permanently out of scope — prematurely transitions parent ticket when X graduates" problem)
|
|
779
779
|
|
|
780
|
-
BEFORE the `git mv` to `.verifying.md`, scan the `.known-error.md` ticket body for **phase-tracking sections with unticked checkboxes whose deferral conditions have now lifted**. Conditional-deferral language ("Phase N SHIP deferred to post-Phase-M-graduation" / "deferred-pending-X-graduation" / "Phase N deferred until Y") names a CONDITION — it is NOT terminal. When the gating condition fires (Phase M graduates, dependency Y ships), the conditionally-deferred work is back IN SCOPE; transitioning K→V while it remains unticked silently loses the work.
|
|
780
|
+
BEFORE the `git mv` to `.verifying.md`, scan the `.known-error.md` ticket body for **phase-tracking sections with unticked checkboxes whose deferral conditions have now lifted**. Conditional-deferral language ("Phase N SHIP deferred to post-Phase-M-graduation" / "deferred-pending-X-graduation" / "Phase N deferred until Y") names a CONDITION — it is NOT terminal. When the gating condition fires (Phase M graduates, dependency Y ships), the conditionally-deferred work is back IN SCOPE; transitioning K→V while it remains unticked silently loses the work. the "Agent treats conditionally-deferred work (deferred-pending-X-graduation) as permanently out of scope — prematurely transitions parent ticket when X graduates" problem's driver case (the "Problem tickets strain as fixes decompose into multiple coordinated changes — need an RFC framework that ties all changes back to problems (and unifies technical with user/business problems)" problem Phase 2 SHIP deferred to post-Phase-1-graduation) is the canonical regression — the agent's NLP parsed "deferred" as terminal without checking the conditional clause, transitioned the parent ticket, and would have lost the Phase 2 work if the user hadn't asked an orthogonal question that surfaced the misreading.
|
|
781
781
|
|
|
782
782
|
**Detection** (run in order):
|
|
783
783
|
|
|
@@ -787,7 +787,7 @@ BEFORE the `git mv` to `.verifying.md`, scan the `.known-error.md` ticket body f
|
|
|
787
787
|
- `deferred (?:to|pending|until) (?:post-)?[A-Za-z0-9-]+(?:-graduation)?`
|
|
788
788
|
- `Phase [0-9]+ (?:SHIP )?deferred`
|
|
789
789
|
- `deferred-pending-[a-z-]+`
|
|
790
|
-
4. For each conditional-deferral marker, resolve whether the **gating condition** has fired. The gating condition typically names another phase, ticket, or RFC — check whether that artefact has reached `.closed.md` / `.verifying.md` (for tickets), or `closed` lifecycle (for RFCs / stories per
|
|
790
|
+
4. For each conditional-deferral marker, resolve whether the **gating condition** has fired. The gating condition typically names another phase, ticket, or RFC — check whether that artefact has reached `.closed.md` / `.verifying.md` (for tickets), or `closed` lifecycle (for RFCs / stories per the "Problem-RFC-Story framework with mandatory problem-trace and unified problem ontology" architecture rule).
|
|
791
791
|
|
|
792
792
|
**Halt-and-route** (when ANY conditional deferral has lifted with unticked work remaining):
|
|
793
793
|
|
|
@@ -795,23 +795,23 @@ Emit a structured report naming each deferred section + the lifted condition + t
|
|
|
795
795
|
|
|
796
796
|
- **Interactive**: fire `AskUserQuestion` with `header: "Conditional deferral lifted"` + options:
|
|
797
797
|
1. `Re-open Phase N — work the deferred tasks now (Recommended)` — halt the K→V transition; route to working the deferred Phase N tasks; revert to Known Error.
|
|
798
|
-
2. `Confirm Phase N permanently out of scope — proceed with K→V` — user explicit acknowledgement that the deferral was misclassified as conditional and is in fact terminal; proceed with the K→V transition; append `<!--
|
|
798
|
+
2. `Confirm Phase N permanently out of scope — proceed with K→V` — user explicit acknowledgement that the deferral was misclassified as conditional and is in fact terminal; proceed with the K→V transition; append `<!-- the "Agent treats conditionally-deferred work (deferred-pending-X-graduation) as permanently out of scope — prematurely transitions parent ticket when X graduates" problem: user-confirmed Phase N permanently OOS -->` marker to the deferred section so re-detection skips it.
|
|
799
799
|
3. `Split Phase N into a new ticket — proceed with K→V on this one` — halt the K→V transition; route to `/wr-itil:capture-problem` for a new ticket carrying the Phase N scope; once captured, resume the K→V transition on the original ticket.
|
|
800
|
-
- **AFK** (per
|
|
800
|
+
- **AFK** (per the "Structured User Interaction for Governance-Skill Decisions" architecture rule Rule 6 + the "AFK iter default when a skill needs to ask a question and AskUserQuestion is unavailable — should queue the question and move to the next iteration (not halt, not silently skip)" problem queue-and-continue universal default): queue an `outstanding_questions` entry naming the local ticket ID + the lifted-condition citation + the unticked task count + the three options above. **Do NOT auto-transition.** The orchestrator main turn surfaces the queued question at loop end via the existing batched-`AskUserQuestion` end-of-loop gate. Brief the substance BEFORE referencing IDs per `feedback_brief_before_id.md` — the user reads the prompt without project filesystem access.
|
|
801
801
|
|
|
802
802
|
**Proceed silently** (no halt) when:
|
|
803
803
|
- No phase-tracking sections exist in the ticket body (the common case).
|
|
804
804
|
- Phase-tracking sections exist but every task is ticked.
|
|
805
805
|
- Phase-tracking sections exist with unticked tasks BUT the deferral marker explicitly states "permanently out of scope" / "won't fix" / "rejected" without a conditional clause.
|
|
806
|
-
- The conditional-deferral marker carries the `<!--
|
|
806
|
+
- The conditional-deferral marker carries the `<!-- the "Agent treats conditionally-deferred work (deferred-pending-X-graduation) as permanently out of scope — prematurely transitions parent ticket when X graduates" problem: user-confirmed Phase N permanently OOS -->` marker from a prior surfacing.
|
|
807
807
|
|
|
808
|
-
**Why halt-and-route not silent-default-with-marker**:
|
|
808
|
+
**Why halt-and-route not silent-default-with-marker**: the "Agent treats conditionally-deferred work (deferred-pending-X-graduation) as permanently out of scope — prematurely transitions parent ticket when X graduates" problem's failure mode is "work silently lost if user doesn't notice"; the "Problem 063: manage-problem does not trigger /wr-itil:report-upstream when root cause is external" problem silent-default-with-marker shape leaves the lost-work-detection burden on the user reading the marker in the Verification Queue. The halt-and-route shape catches the failure at the transition surface where the loss occurs. Authority: the "— Decision-Delegation Contract: when agents act on the framework vs ask the user" architecture rule category 2 (deviation-approval) — the agent surfaces a deviation candidate with citations + evidence + a proposed shape; user picks. Driver: user direction in the "Agent treats conditionally-deferred work (deferred-pending-X-graduation) as permanently out of scope — prematurely transitions parent ticket when X graduates" problem Workaround line 37 — *"explicitly ask the user 'is Phase N still deferred or is it now in-scope?' before transitioning when the ticket body shows phase-tracking sections."*
|
|
809
809
|
|
|
810
|
-
This check fires BEFORE the
|
|
810
|
+
This check fires BEFORE the "derive-release-vehicle helper requires pre-edit of ticket changeset reference — three-touch when one-touch would suffice" problem Release-vehicle seed below — halt-on-conditional-deferral is the outer gate, seed-and-rename is the inner mechanic.
|
|
811
811
|
|
|
812
|
-
**Seed `Release vehicle` reference BEFORE the rename (
|
|
812
|
+
**Seed `Release vehicle` reference BEFORE the rename (the "derive-release-vehicle helper requires pre-edit of ticket changeset reference — three-touch when one-touch would suffice" problem).** BEFORE the `git mv` to `.verifying.md`, edit the `.known-error.md` ticket body to append a `**Release vehicle**: .changeset/<name>.md` paragraph at the END of the `## Fix Strategy` section (create the section if absent). The `<name>.md` is the kebab-case slug of the changeset file the fix commit authored under `.changeset/` (e.g. `wr-itil-p330-option-b.md`). The seed eliminates the `wr-itil-derive-release-vehicle <NNN>` helper's exit-2 routing on standalone K→V iters — the helper greps the ticket body for `.changeset/<name>.md` and exits 2 when absent; seeding the reference at fix-ship time (when the changeset name is fresh in scope, since the fix commit just created it) makes the helper exit 0 deterministically on first call. The exit-2 recovery routing documented in `/wr-itil:transition-problem` Step 6 remains as the legacy-ticket fallback. Matches the user's documented workaround pattern across 3 of 4 standalone K→V dogfoods in the 2026-05-30 session (the "Rejected-pending-supersede ADRs re-surface in every review-decisions drain — no "rejected" state to suppress them" problem / the "capture-problem skill template references pre- flat-path shape" problem / the "ADR-confirmation summaries should lead with the Decision Outcome, not the meta-framing (caused 2 user re-asks this session)" problem — see the "derive-release-vehicle helper requires pre-edit of ticket changeset reference — three-touch when one-touch would suffice" problem § Symptoms).
|
|
813
813
|
|
|
814
|
-
> **Two
|
|
814
|
+
> **Two the "Problem 057: `git mv` + Edit + `git add` staging-ordering trap drops content edits from the commit" problem staging-trap windows on K→V (seed + rename).** The seed Edit on `.known-error.md` is the FIRST the "Problem 057: `git mv` + Edit + `git add` staging-ordering trap drops content edits from the commit" problem window; the Edit that updates Status / writes `## Fix Released` AFTER the `git mv` is the SECOND. Consolidate staging into a SINGLE `git add docs/problems/verifying/<NNN>-<title>.md` AFTER both Edits + the `git mv`. `git mv` operates on the index entry — the body content the index references at rename time is the post-seed content, so the seed Edit's content is carried across the rename automatically; the single final `git add` re-stages the post-rename file with the post-`Edit` Status + `## Fix Released` content. The seed step does NOT introduce a separate `git add` of the `known-error/` path — staging discipline stays single-call by riding the rename's index entry.
|
|
815
815
|
|
|
816
816
|
```bash
|
|
817
817
|
# Step 1 — seed `**Release vehicle**: .changeset/<name>.md` in the Fix Strategy section
|
|
@@ -831,9 +831,9 @@ Then edit the file:
|
|
|
831
831
|
- Update the "Status" field to "Verification Pending"
|
|
832
832
|
- Add a `## Fix Released` section with: release marker (version, commit SHA, or date), one-sentence fix summary, "Awaiting user verification" line, and any exercise evidence from the releasing session.
|
|
833
833
|
|
|
834
|
-
Re-stage the `.verifying.md` file explicitly after the `Edit` tool runs (
|
|
834
|
+
Re-stage the `.verifying.md` file explicitly after the `Edit` tool runs (the "Problem 057: `git mv` + Edit + `git add` staging-ordering trap drops content edits from the commit" problem). The trailing `git add` above is NOT redundant — `git mv` alone stages only the rename, not the subsequent content edit; the same `git add` also re-stages the seed Edit content carried across the rename (single staging call, two Edit windows; the "derive-release-vehicle helper requires pre-edit of ticket changeset reference — three-touch when one-touch would suffice" problem + the "Problem 057: `git mv` + Edit + `git add` staging-ordering trap drops content edits from the commit" problem).
|
|
835
835
|
|
|
836
|
-
Both the `git mv` and the file edits belong in the same commit as the fix implementation per
|
|
836
|
+
Both the `git mv` and the file edits belong in the same commit as the fix implementation per the "Governance Skills Commit Their Own Completed Work" architecture rule (governance skills commit their own work). The `.verifying.md` suffix signals to every downstream consumer (work-problems classifier, review step 9d, README rendering) that the remaining work is user-side verification — no file-body scan needed.
|
|
837
837
|
|
|
838
838
|
**Verification Pending → Closed** (user confirms):
|
|
839
839
|
|
|
@@ -845,32 +845,32 @@ git mv docs/problems/verifying/<NNN>-<title>.md docs/problems/closed/<NNN>-<titl
|
|
|
845
845
|
git add docs/problems/closed/<NNN>-<title>.md
|
|
846
846
|
```
|
|
847
847
|
|
|
848
|
-
Update the "Status" field to "Closed". Reference the problem ID in the closure commit message (e.g., "Closes
|
|
848
|
+
Update the "Status" field to "Closed". Reference the problem ID in the closure commit message (e.g., "Closes the "Problem 008: AskUserQuestion Unavailable When --channels Is Active" problem"). Step 9d's verification prompt is the structured path that fires this transition during `manage-problem review`. Re-stage the `.closed.md` file explicitly after the Edit (the "Problem 057: `git mv` + Edit + `git add` staging-ordering trap drops content edits from the commit" problem staging trap).
|
|
849
849
|
|
|
850
|
-
#### README.md refresh on every transition (
|
|
850
|
+
#### README.md refresh on every transition (the "Problem 062: `manage-problem` does not refresh `docs/problems/README.md` on single-ticket transitions; fast-path cache goes stale silently" problem)
|
|
851
851
|
|
|
852
852
|
Every Step 7 status transition (Open → Known Error, Known Error → Verification Pending, Verification Pending → Closed, Parked — regardless of source or destination suffix) regenerates `docs/problems/README.md` and stages it in the same commit so the dev-work table, Verification Queue, Parked section, and "Last reviewed" line never lag the on-disk ticket inventory. Without this step, README.md accumulates staleness between `review` invocations; the next `work` fast-path check correctly detects the lag and forces a full rescan (self-healing but wasteful), and any human browsing the file between transitions sees outdated rankings.
|
|
853
853
|
|
|
854
|
-
The refresh uses the same rendering rules as Step 9e (dual-tolerant glob per
|
|
854
|
+
The refresh uses the same rendering rules as Step 9e (dual-tolerant glob per the ": docs/problems/ flat layout migration — per-state subdirs + adopter auto-migration" release design 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.
|
|
855
855
|
|
|
856
|
-
**WSJF Rankings tier + tie-break sort (
|
|
856
|
+
**WSJF Rankings tier + tie-break sort (the "`docs/problems/README.md` WSJF Rankings table row order doesn't match `/wr-itil:work-problems`'s tie-break selection — users assume the orchestrator is broken" problem + the "Inbound-reported problems rank ahead of internally-discovered problems via a sort tier" architecture rule)**: 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 (the "Inbound-reported problems rank ahead of internally-discovered problems via a sort tier" architecture rule) --> <!-- 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 the "Problem 094: `/wr-itil:manage-problem` does not refresh `docs/problems/README.md` on ticket creation" problem block, the Step 9e template, AND `/wr-itil:review-problems` SKILL.md Step 3 / Step 5 — drift here re-opens the "`docs/problems/README.md` WSJF Rankings table row order doesn't match `/wr-itil:work-problems`'s tie-break selection — users assume the orchestrator is broken" problem / the "Inbound-reported problems rank ahead of internally-discovered problems via a sort tier" architecture rule.
|
|
857
857
|
|
|
858
|
-
**Verification Queue sort direction (
|
|
858
|
+
**Verification Queue sort direction (the "docs/problems/README.md Verification Queue rendered newest-first contradicts section header "Ranked by release age, oldest first"" problem)**: rows in the Verification Queue table are sorted by `Released date ASC` (oldest at row 1; same-day releases tiebreak by ID ASC) per the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule + the "Problem 048: manage-problem does not surface Fix Released problems as verification candidates when the fix path has been exercised" problem 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 the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule --> Any future change to the VQ sort direction MUST update this render block, the Step 5 the "Problem 094: `/wr-itil:manage-problem` does not refresh `docs/problems/README.md` on ticket creation" problem 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 the "docs/problems/README.md Verification Queue rendered newest-first contradicts section header "Ranked by release age, oldest first"" problem.
|
|
859
859
|
|
|
860
|
-
**Likely-verified cell shape (
|
|
860
|
+
**Likely-verified cell shape (the "VQ `Likely verified?` column uses age-based heuristic (≥14 days = yes) instead of session-observed evidence — sibling proxy-for-evidence anti-pattern to" problem)**: the `Likely verified?` column carries an **evidence-first** cell — `yes — observed: <evidence>` / `no — not observed` / `no — observed regression`. Age is preserved separately via the `Released` column; session-observed evidence drives the cell. On a Known Error → Verification Pending transition the refresh writes `no — not observed` as the default (no observed evidence yet at the moment of release). <!-- LIKELY-VERIFIED-CELL-SHAPE: evidence-based per the "VQ `Likely verified?` column uses age-based heuristic (≥14 days = yes) instead of session-observed evidence — sibling proxy-for-evidence anti-pattern to" problem --> Any future change to the cell shape MUST update this render block, the Step 5 the "Problem 094: `/wr-itil:manage-problem` does not refresh `docs/problems/README.md` on ticket creation" problem 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 the "VQ `Likely verified?` column uses age-based heuristic (≥14 days = yes) instead of session-observed evidence — sibling proxy-for-evidence anti-pattern to" problem.
|
|
861
861
|
|
|
862
862
|
**Mechanism:**
|
|
863
863
|
|
|
864
864
|
1. After renaming + Editing + `git add`-ing the transitioned ticket file (per the staging-trap rule above), regenerate `docs/problems/README.md` in-place reflecting the new filename set and the transitioned ticket's new Status.
|
|
865
865
|
2. `git add docs/problems/README.md` — stage the refreshed README with the same commit as the transition.
|
|
866
|
-
3. Update the "Last reviewed" line per the **inline
|
|
866
|
+
3. Update the "Last reviewed" line per the **inline the "`docs/problems/README.md` line 3 narrative-blob accumulator bloat — sibling to (briefing tier 3) on a different surface" problem rotation mechanism** below. The mechanism is inlined here at the execution site (not deferred via cross-reference to the § Last-reviewed line discipline subsection in Step 5 above) so a single-pass agent reading this Step 7 does not silently skip the archive step. **Skipping the BEFORE-rewrite archive step destroys the displaced fragment and re-opens the "transition-problem SKILL Step 7 Last-reviewed rotation silently skipped across iters" problem** (iter-7 + iter-8 of 2026-05-30's AFK work-problems session silently skipped the rotation in 2 of 9 transition-bearing iters under exactly that failure mode). The mechanism MUST execute IN ORDER:
|
|
867
867
|
|
|
868
868
|
1. **Read** line 3 of `docs/problems/README.md`: `awk 'NR==3' docs/problems/README.md` (`head -3 | tail -1` or `sed -n '3p'` are acceptable equivalents).
|
|
869
869
|
2. **Append-if-non-empty (BEFORE step 3, not after)** — if line 3 is non-empty AND not a same-session same-verb near-duplicate of the new fragment, append the existing line 3 verbatim to `docs/problems/README-history.md` under a `## YYYY-MM-DD` heading (creating the heading on first append for that date; subsequent same-day appends nest under the existing heading). Run this BEFORE the Edit-tool rewrite in step 3 — Edit's replace pattern destroys the displaced content otherwise.
|
|
870
|
-
3. **Rewrite** line 3 of `docs/problems/README.md` with the new fragment of form `> Last reviewed: YYYY-MM-DD **<event>** — <one-line summary>` (e.g. `P<NNN> <status> — <one-line fix summary>`). Soft cap ≤ 1024 bytes per fragment; hard ceiling 5120 bytes per
|
|
871
|
-
4. **Stage both** — `git add docs/problems/README.md docs/problems/README-history.md` so the same single commit per
|
|
870
|
+
3. **Rewrite** line 3 of `docs/problems/README.md` with the new fragment of form `> Last reviewed: YYYY-MM-DD **<event>** — <one-line summary>` (e.g. `P<NNN> <status> — <one-line fix summary>`). Soft cap ≤ 1024 bytes per fragment; hard ceiling 5120 bytes per the "Session-start briefing surface — SessionStart hook over tiered directory + indexed README" architecture rule Tier 3 envelope.
|
|
871
|
+
4. **Stage both** — `git add docs/problems/README.md docs/problems/README-history.md` so the same single commit per the "Governance Skills Commit Their Own Completed Work" architecture rule single-commit grain captures both files.
|
|
872
872
|
|
|
873
|
-
Canonical rationale anchor: § Last-reviewed line discipline (
|
|
873
|
+
Canonical rationale anchor: § Last-reviewed line discipline (the "`docs/problems/README.md` line 3 narrative-blob accumulator bloat — sibling to (briefing tier 3) on a different surface" problem) subsection in Step 5 above. The cross-reference is preserved for the "why"; the "what" is inlined above for execution-time legibility per the "transition-problem SKILL Step 7 Last-reviewed rotation silently skipped across iters" problem.
|
|
874
874
|
|
|
875
875
|
**Scope**: fires for every Step 7 rename. Applies equally to:
|
|
876
876
|
- Standalone transition commits (e.g. `docs(problems): P<NNN> known error — <summary>`).
|
|
@@ -878,13 +878,13 @@ The refresh uses the same rendering rules as Step 9e (dual-tolerant glob per RFC
|
|
|
878
878
|
|
|
879
879
|
**Fast-path interaction**: the Step 9 fast-path freshness check (`git log -1 --format=%H -- docs/problems/README.md` followed by `git log --oneline "${readme_commit}..HEAD" -- 'docs/problems/*.md'`) remains the authoritative staleness test. When this refresh fires on every transition, that check should return empty on any subsequent invocation — the cache stays fresh by construction. If the check still reports "stale", something skipped the refresh (bug) and the slow-path is the correct recovery.
|
|
880
880
|
|
|
881
|
-
#### Bidirectional upstream lifecycle update (
|
|
881
|
+
#### Bidirectional upstream lifecycle update (the "Problem 080: No bidirectional update of upstream-reported problems — local lifecycle transitions never propagate back to the reporter" problem — advisory, copy-not-move from transition-problem Step 7b)
|
|
882
882
|
|
|
883
|
-
After the rename + README refresh land but BEFORE the Step 11 commit, fire the bidirectional lifecycle-update sibling skill so the upstream issue (if any) receives the lifecycle update comment in the SAME commit as the transition per
|
|
883
|
+
After the rename + README refresh land but BEFORE the Step 11 commit, fire the bidirectional lifecycle-update sibling skill so the upstream issue (if any) receives the lifecycle update comment in the SAME commit as the transition per the "Governance Skills Commit Their Own Completed Work" architecture rule single-commit grain. This is the **outbound-lifecycle-update leg** of the reporter loop (the inbound-discovery leg is owned by the "Inbound upstream-report discovery + assessment pipeline (peer of )" architecture rule's assessment pipeline; together they close the reporter relationship per the "Report a Problem Without Pre-Classifying It" user outcome + the "Restore Service Fast with an Audit Trail" user outcome).
|
|
884
884
|
|
|
885
|
-
This subsection is the **copy-not-move sibling** of `transition-problem` SKILL.md Step 7b per [
|
|
885
|
+
This subsection is the **copy-not-move sibling** of `transition-problem` SKILL.md Step 7b per [the "Rename `wr-problem` Plugin to `wr-itil`" architecture rule](../../../docs/decisions/010-rename-wr-problem-to-wr-itil.proposed.md) amended "Split-skill execution ownership" rule (the "Problem 093: `/wr-itil:transition-problem` ↔ `/wr-itil:manage-problem` circular delegation for `<NNN> <status>` args" problem). The user-initiated transition path lives in `/wr-itil:transition-problem`; the in-skill callers (Step 9b auto-transition, Step 9d closure inside review, the Parked path) need the same lifecycle-update trigger and carry their own scoped copy. Drift between the two copies re-opens the "Problem 080: No bidirectional update of upstream-reported problems — local lifecycle transitions never propagate back to the reporter" problem's bidirectional gap on the in-skill paths.
|
|
886
886
|
|
|
887
|
-
The trigger fires **whenever the ticket carries a `## Reported Upstream` section (outbound) OR an `**Origin**: inbound-reported (#NN)` field (inbound,
|
|
887
|
+
The trigger fires **whenever the ticket carries a `## Reported Upstream` section (outbound) OR an `**Origin**: inbound-reported (#NN)` field (inbound, the "Inbound-reported tickets never receive fix-released verdict on originating issue" problem)** — gate the Skill-tool dispatch behind a one-line mechanical pre-check rather than dispatching on every transition. Dispatching unconditionally pays the full `/wr-itil:update-upstream` SKILL.md context load (~14 KB into the calling agent's context) just to hit the sibling skill's no-op exit; the common case is a ticket with neither surface, so the load is wasted (the "Unconditional update-upstream Skill dispatch pays full SKILL.md context load for the common no-op case" problem). The grep IS the trigger: it preserves the fire-whenever-a-surface-exists semantics — an upstream/inbound comment posts iff one of the two surfaces is present — while eliminating the context load for the common no-op case. Authority: [the "SKILL.md runtime budget policy" architecture rule](../../../docs/decisions/054-skill-md-runtime-budget-policy.proposed.md) (SKILL.md runtime-budget policy; [the "Progressive disclosure + once-per-session budget for UserPromptSubmit governance prose" architecture rule](../../../docs/decisions/038-progressive-disclosure-for-governance-tooling-context.proposed.md) progressive-disclosure as the ancestor principle); [the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule](../../../docs/decisions/024-cross-project-problem-reporting-contract.proposed.md) amendment (the "Inbound-reported tickets never receive fix-released verdict on originating issue" problem) for the inbound-origin alternation.
|
|
888
888
|
|
|
889
889
|
**Pre-check first** (mechanical — no user decision): run `grep -qE '^## Reported Upstream|^\*\*Origin\*\*: inbound-reported \(#' <ticket-file>`. If it does NOT match (NEITHER the outbound `## Reported Upstream` section NOR the inbound `**Origin**: inbound-reported (#NN)` field is present), skip the Skill dispatch entirely, log one line (`no ## Reported Upstream section and no inbound Origin; skipping upstream lifecycle update`), and proceed to Step 11. Only when it matches, invoke the sibling skill via the Skill tool:
|
|
890
890
|
|
|
@@ -895,19 +895,19 @@ The trigger fires **whenever the ticket carries a `## Reported Upstream` section
|
|
|
895
895
|
Behaviour matrix:
|
|
896
896
|
|
|
897
897
|
- **Neither `## Reported Upstream` section nor inbound `**Origin**` field on the local ticket** → the grep pre-check skips the Skill dispatch (no context load); log `no ## Reported Upstream section and no inbound Origin; skipping upstream lifecycle update` and proceed to Step 11. (The sibling skill retains its own Step 1 no-op exit as defence-in-depth for any path that reaches it directly.)
|
|
898
|
-
- **`**Origin**: inbound-reported (#NN)` present** → the sibling skill runs its inbound-origin verdict dispatch leg (
|
|
898
|
+
- **`**Origin**: inbound-reported (#NN)` present** → the sibling skill runs its inbound-origin verdict dispatch leg (the "Inbound-reported tickets never receive fix-released verdict on originating issue" problem): posts the reporter-facing fix-released / closed verdict on the originating own-repo issue through the same external-comms + voice-tone gates, idempotency-guarded, and back-writes a direction-tagged `## Upstream Lifecycle Updates` entry. If BOTH surfaces are present, the outbound and inbound legs fire independently.
|
|
899
899
|
- **`## Reported Upstream` present AND both gates within appetite** → the sibling skill posts via `gh issue comment` (and on Verifying → Closed, also `gh issue close`), back-writes to `## Upstream Lifecycle Updates`, and stages the back-write into the index. The Step 11 commit captures the back-write alongside the transition.
|
|
900
|
-
- **`## Reported Upstream` present AND above-appetite (after silent risk-reduce + re-score)** → the sibling skill saves the drafted comment to `## Queued Upstream Update` and queues an `outstanding_questions` entry. The Step 11 commit captures the `## Queued Upstream Update` appendage alongside the transition. **The orchestrator continues per
|
|
900
|
+
- **`## Reported Upstream` present AND above-appetite (after silent risk-reduce + re-score)** → the sibling skill saves the drafted comment to `## Queued Upstream Update` and queues an `outstanding_questions` entry. The Step 11 commit captures the `## Queued Upstream Update` appendage alongside the transition. **The orchestrator continues per the "AFK iter default when a skill needs to ask a question and AskUserQuestion is unavailable — should queue the question and move to the next iteration (not halt, not silently skip)" problem queue-and-continue** — do NOT halt the transition on an above-appetite upstream update.
|
|
901
901
|
|
|
902
|
-
If `/wr-itil:update-upstream` is not installed (the `@windyroad/itil` package version pre-dates
|
|
902
|
+
If `/wr-itil:update-upstream` is not installed (the `@windyroad/itil` package version pre-dates the "Problem 080: No bidirectional update of upstream-reported problems — local lifecycle transitions never propagate back to the reporter" problem shipping), the Skill tool returns a not-found error. Log a one-line warning (`update-upstream skill not available; skipping upstream lifecycle update`) and proceed to Step 11 — do NOT halt the transition.
|
|
903
903
|
|
|
904
|
-
Per [
|
|
904
|
+
Per [the "Structured User Interaction for Governance-Skill Decisions" architecture rule Rule 6](../../../docs/decisions/013-structured-user-interaction-for-governance-decisions.proposed.md) (AFK fail-safe), AFK orchestrators MUST NOT halt this transition path on a queued upstream-update — the queued entry surfaces at the existing batched-`AskUserQuestion` end-of-loop gate.
|
|
905
905
|
|
|
906
|
-
Authority: [
|
|
906
|
+
Authority: [the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule](../../../docs/decisions/024-cross-project-problem-reporting-contract.proposed.md) amendment (the "Problem 080: No bidirectional update of upstream-reported problems — local lifecycle transitions never propagate back to the reporter" problem) — bidirectional lifecycle-update sibling skill. The advisory ALSO lives in `/wr-itil:transition-problem` Step 7b per the "Rename `wr-problem` Plugin to `wr-itil`" architecture rule amended "copy, not move" (the "Problem 093: `/wr-itil:transition-problem` ↔ `/wr-itil:manage-problem` circular delegation for `<NNN> <status>` args" problem) — both copies must move in lockstep.
|
|
907
907
|
|
|
908
908
|
### 8. For list: Show summary
|
|
909
909
|
|
|
910
|
-
Read all open + known-error tickets via the dual-tolerant glob `ls docs/problems/*.open.md docs/problems/*.known-error.md docs/problems/open/*.md docs/problems/known-error/*.md 2>/dev/null` (
|
|
910
|
+
Read all open + known-error tickets via the dual-tolerant glob `ls docs/problems/*.open.md docs/problems/*.known-error.md docs/problems/open/*.md docs/problems/known-error/*.md 2>/dev/null` (the ": docs/problems/ flat layout migration — per-state subdirs + adopter auto-migration" release design migration window). Extract ID, title, priority, and status. Sort by priority (highest first). Display as a markdown table.
|
|
911
911
|
|
|
912
912
|
### 9. For review: Re-assess all open problems
|
|
913
913
|
|
|
@@ -915,13 +915,13 @@ This is a batch operation that reviews every open/known-error problem and update
|
|
|
915
915
|
|
|
916
916
|
**Fast-path for `work` (skip full re-scan when cache is fresh):**
|
|
917
917
|
|
|
918
|
-
Before running the full review, check whether `docs/problems/README.md` exists and is up to date using **git history** (not filesystem mtime, which is unreliable in worktrees and fresh checkouts — see
|
|
918
|
+
Before running the full review, check whether `docs/problems/README.md` exists and is up to date using **git history** (not filesystem mtime, which is unreliable in worktrees and fresh checkouts — see the "Problem 031: `manage-problem work` incorrectly determines cache is fresh" problem):
|
|
919
919
|
|
|
920
920
|
```bash
|
|
921
921
|
readme_commit=$(git log -1 --format=%H -- docs/problems/README.md 2>/dev/null)
|
|
922
922
|
# Cache is stale if: no README commit, OR problem files committed since README, OR uncommitted problem file changes.
|
|
923
923
|
# Pathspec pair `'docs/problems/*.md' 'docs/problems/*/*.md'` is the
|
|
924
|
-
#
|
|
924
|
+
# the ": docs/problems/ flat layout migration — per-state subdirs + adopter auto-migration" release design dual-tolerant transitional shape — covers BOTH the flat
|
|
925
925
|
# layout AND the per-state subdir layout. T6 drops the flat half post-T5.
|
|
926
926
|
if [ -z "$readme_commit" ] || \
|
|
927
927
|
git log --oneline "${readme_commit}..HEAD" -- 'docs/problems/*.md' 'docs/problems/*/*.md' ':!docs/problems/README.md' 2>/dev/null | grep -q .; then
|
|
@@ -933,7 +933,7 @@ If the command produces **no output** (no problem files have been committed or m
|
|
|
933
933
|
- Read `docs/problems/README.md` only — it contains the ranked table from the last review
|
|
934
934
|
- Skip steps 9a–9b entirely
|
|
935
935
|
- Proceed to step 9c (work selection) using the cached table
|
|
936
|
-
- **Step 9d always fires even on the fast-path cache hit** (
|
|
936
|
+
- **Step 9d always fires even on the fast-path cache hit** (the "Problem 048: manage-problem does not surface Fix Released problems as verification candidates when the fix path has been exercised" problem Candidate 1): the verification prompt surface must not depend on whether the cache is fresh — pending verifications accumulate across sessions and the user expects the prompts to appear on every `review`. Skipping 9d alongside 9a–9b would suppress verification prompts whenever the cache is fresh, which is exactly when the user is most likely to verify.
|
|
937
937
|
- Note in the output: "Using cached ranking from [timestamp in README.md]"
|
|
938
938
|
|
|
939
939
|
If the command prints "stale", or `README.md` does not exist in git, run the full review (steps 9a–9e) and refresh the cache.
|
|
@@ -944,7 +944,7 @@ Read `RISK-POLICY.md` to get the current impact levels (1-5), likelihood levels
|
|
|
944
944
|
|
|
945
945
|
**Step 9b: For each open/known-error problem (skip parked / verifying tickets entirely):**
|
|
946
946
|
|
|
947
|
-
Enumerate via dual-tolerant glob `docs/problems/*.open.md docs/problems/*.known-error.md docs/problems/open/*.md docs/problems/known-error/*.md` per
|
|
947
|
+
Enumerate via dual-tolerant glob `docs/problems/*.open.md docs/problems/*.known-error.md docs/problems/open/*.md docs/problems/known-error/*.md` per the ": docs/problems/ flat layout migration — per-state subdirs + adopter auto-migration" release design migration window. Parked problems and Verification Pending problems are excluded from WSJF ranking — do not read, score, or update them in this step. Parked tickets are shown in a dedicated Parked section in step 9c; Verification Pending tickets are shown in a dedicated Verification Queue section in step 9c (ranked by release age, not WSJF — per the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule).
|
|
948
948
|
|
|
949
949
|
1. Read the problem file
|
|
950
950
|
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
|
|
@@ -952,15 +952,15 @@ Enumerate via dual-tolerant glob `docs/problems/*.open.md docs/problems/*.known-
|
|
|
952
952
|
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?"
|
|
953
953
|
5. **Calculate Severity** = Impact × Likelihood
|
|
954
954
|
6. **Look up Label** from the risk matrix label bands
|
|
955
|
-
7. **Re-estimate Effort** (S / M / L / XL) by reading the root cause analysis and fix strategy. 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 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").
|
|
955
|
+
7. **Re-estimate Effort** (S / M / L / XL) by reading the root cause analysis and fix strategy. 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 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"). the "Problem 047: WSJF effort buckets are coarse and not re-rated at lifecycle transitions" problem.
|
|
956
956
|
8. **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:
|
|
957
957
|
- `git mv docs/problems/open/<NNN>-<title>.md docs/problems/known-error/<NNN>-<title>.md`
|
|
958
958
|
- Update the Status field to "Known Error"
|
|
959
959
|
- This happens automatically — do not ask the user
|
|
960
|
-
9. **Calculate WSJF** = (Severity × Status Multiplier) / Effort Divisor, using the ticket's status after step 8 (Open 1.0; Known Error 2.0).
|
|
960
|
+
9. **Calculate WSJF** = (Severity × Status Multiplier) / Effort Divisor, using the ticket's status after step 8 (Open 1.0; Known Error 2.0). the "WSJF uses the pre-transition status multiplier" problem.
|
|
961
961
|
10. **Update the Priority and WSJF lines** in the problem file if the scores changed
|
|
962
962
|
|
|
963
|
-
**Step 9b.1: Dependency-graph traversal — propagate transitive effort (
|
|
963
|
+
**Step 9b.1: Dependency-graph traversal — propagate transitive effort (the "Problem 076: WSJF scoring in manage-problem does not model transitive dependencies" problem)**
|
|
964
964
|
|
|
965
965
|
After every `.open.md` / `.known-error.md` ticket has a marginal effort, run a **second pass** that walks the dependency graph and propagates effort up per the transitive-dependency rule (see the WSJF Prioritisation section's "Transitive dependencies" subsection). This is a deterministic re-rate — no `AskUserQuestion` required.
|
|
966
966
|
|
|
@@ -975,26 +975,26 @@ After every `.open.md` / `.known-error.md` ticket has a marginal effort, run a *
|
|
|
975
975
|
P<NNN>: Effort <OLD> → <NEW> (transitive via <UPSTREAM>)
|
|
976
976
|
```
|
|
977
977
|
|
|
978
|
-
Example: `
|
|
978
|
+
Example: `the "Problem 073: No voice-and-tone check or risk assessment on changeset bodies (which populate CHANGELOG.md, Release PRs, GitHub Releases, and npm release notes)" problem: Effort S → XL (transitive via the "Problem 038: No voice-and-tone gate on external communications" problem)`. The shape is fixed so downstream audit tools can grep it deterministically.
|
|
979
979
|
|
|
980
|
-
7. **Cycle-bundle output**: for cycle bundles, surface a shared WSJF line covering all members, e.g. `Bundle [
|
|
980
|
+
7. **Cycle-bundle output**: for cycle bundles, surface a shared WSJF line covering all members, e.g. `Bundle [the "Problem 038: No voice-and-tone gate on external communications" problem, the "Problem 064: No risk-scoring gate on external communications" problem]: effort XL (cycle), WSJF 3.0 (shared)`. The shared WSJF is a computed artefact of the review rendering — do NOT write a shared-bundle field into the individual ticket files.
|
|
981
981
|
|
|
982
982
|
The re-rate pass is part of Step 9b's output — a re-rate row appears in the step 9c ranked table with the transitive effort (not the marginal). Hide the marginal from the main table but preserve it in the ticket's HTML-comment audit trail so a future review knows where the propagation came from.
|
|
983
983
|
|
|
984
984
|
**Step 9c: Present summary and select problem to work**
|
|
985
985
|
|
|
986
|
-
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 (
|
|
986
|
+
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 (the "`docs/problems/README.md` WSJF Rankings table row order doesn't match `/wr-itil:work-problems`'s tie-break selection — users assume the orchestrator is broken" problem + the "Inbound-reported problems rank ahead of internally-discovered problems via a sort tier" architecture rule): <!-- REPORTED-FIRST-TIER-SOURCE: /wr-itil:work-problems SKILL.md Step 3 (the "Inbound-reported problems rank ahead of internally-discovered problems via a sort tier" architecture rule) -->
|
|
987
987
|
|
|
988
988
|
| WSJF | ID | Title | Severity | Status | Effort | Reported | Origin | Notes |
|
|
989
989
|
|------|-----|-------|----------|--------|--------|----------|--------|-------|
|
|
990
990
|
|
|
991
|
-
Then present a separate **Verification Queue** section for `.verifying.md` files (per
|
|
991
|
+
Then present a separate **Verification Queue** section for `.verifying.md` files (per the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule — 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 the "docs/problems/README.md Verification Queue rendered newest-first contradicts section header "Ranked by release age, oldest first"" problem. <!-- VQ-SORT-DIRECTION: oldest-first per the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule --> The final `Likely verified?` column carries an **evidence-first** cell (per the "VQ `Likely verified?` column uses age-based heuristic (≥14 days = yes) instead of session-observed evidence — sibling proxy-for-evidence anti-pattern to" problem — supersedes the original the "Problem 048: manage-problem does not surface Fix Released problems as verification candidates when the fix path has been exercised" problem Candidate 4 14-day heuristic). <!-- LIKELY-VERIFIED-CELL-SHAPE: evidence-based per the "VQ `Likely verified?` column uses age-based heuristic (≥14 days = yes) instead of session-observed evidence — sibling proxy-for-evidence anti-pattern to" problem --> Three canonical values:
|
|
992
992
|
|
|
993
993
|
| ID | Title | Released | Fix summary | Likely verified? |
|
|
994
994
|
|----|-------|----------|-------------|------------------|
|
|
995
995
|
|
|
996
|
-
The `Likely verified?` column takes values (per
|
|
997
|
-
- `yes — observed: <evidence>` — session-observed evidence the fix works. Cite the evidence inline (≤ 120 chars): a Step 9d user confirmation phrase quoted, an in-session test invocation + observable outcome per
|
|
996
|
+
The `Likely verified?` column takes values (per the "VQ `Likely verified?` column uses age-based heuristic (≥14 days = yes) instead of session-observed evidence — sibling proxy-for-evidence anti-pattern to" problem):
|
|
997
|
+
- `yes — observed: <evidence>` — session-observed evidence the fix works. Cite the evidence inline (≤ 120 chars): a Step 9d user confirmation phrase quoted, an in-session test invocation + observable outcome per the "Agent output grounding — no fabricated quantitative estimates, cite + persist + uncertainty" architecture rule grounding, or a `run-retro` Step 4a close-on-evidence citation. Surface these FIRST in step 9d's verification prompt so the user can batch-close them.
|
|
998
998
|
- `no — not observed` — fix released but no session-observable evidence yet. Default for newly-released tickets. Fire step 9d for these too, without batch-close highlight. Aging surfaces via the `Released` column — NOT in this cell.
|
|
999
999
|
- `no — observed regression` — fix released and the bug recurred this session. Cite the recurrence inline (≤ 120 chars). Do NOT batch-close — these may warrant `.verifying.md` → `.known-error.md` flip-back via `/wr-itil:transition-problem`.
|
|
1000
1000
|
|
|
@@ -1008,7 +1008,7 @@ Highlight:
|
|
|
1008
1008
|
- Problems that were auto-transitioned to known-error
|
|
1009
1009
|
- Problems that may be stale (reported > 2 weeks ago with no investigation progress)
|
|
1010
1010
|
- Problems that have been fixed but not closed (check git history for fix commits)
|
|
1011
|
-
- Verification Pending tickets whose fix has been exercised repeatedly without regression (
|
|
1011
|
+
- Verification Pending tickets whose fix has been exercised repeatedly without regression (the "Problem 048: manage-problem does not surface Fix Released problems as verification candidates when the fix path has been exercised" problem detection layer — candidate for closure verification)
|
|
1012
1012
|
|
|
1013
1013
|
**When the operation is `work` (not just `review`), select the problem to work using `AskUserQuestion`:**
|
|
1014
1014
|
|
|
@@ -1024,15 +1024,15 @@ Highlight:
|
|
|
1024
1024
|
|
|
1025
1025
|
**Step 9d: Check for pending verifications**
|
|
1026
1026
|
|
|
1027
|
-
Target `docs/problems/*.verifying.md` via glob — do NOT scan `.known-error.md` bodies for a `## Fix Released` section (per
|
|
1027
|
+
Target `docs/problems/*.verifying.md` via glob — do NOT scan `.known-error.md` bodies for a `## Fix Released` section (per the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule, Verification Pending is a first-class status, not a substring marker). For each `.verifying.md` file, the agent collects in-session evidence per Step 4a's "Exercised successfully in-session" pattern (test invocation + observable outcome per the "Agent output grounding — no fabricated quantitative estimates, cite + persist + uncertainty" architecture rule grounding). When evidence-citation is concrete and unambiguous, the agent **closes the ticket on evidence** by delegating to `/wr-itil:transition-problem <NNN> close` (per the "Governance Skills Commit Their Own Completed Work" architecture rule commit grain) WITHOUT firing `AskUserQuestion` — per the "— Decision-Delegation Contract: when agents act on the framework vs ask the user" architecture rule framework-resolution boundary, evidence-grounded close is a framework-mediated decision (the agent applies the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule's evidence semantics; per-candidate ask is sub-contracting that resolution back to the user as lazy deferral per Step 2d Ask Hygiene Pass classification).
|
|
1028
1028
|
|
|
1029
|
-
When evidence is **ambiguous, contested, or absent** (no specific in-session citation), leave the ticket as Verification Pending — same exclusion path as Step 4a. The user surfaces concerns via the
|
|
1029
|
+
When evidence is **ambiguous, contested, or absent** (no specific in-session citation), leave the ticket as Verification Pending — same exclusion path as Step 4a. The user surfaces concerns via the "Problem 078: Assistant does not offer to capture a problem ticket when the user delivers strong-signal correction" problem capture-on-correction surface (authentic-correction per the "— Decision-Delegation Contract: when agents act on the framework vs ask the user" architecture rule category 6) if a close-on-evidence action was wrong; closes are reversible via `/wr-itil:transition-problem <NNN> known-error` (the verifying-flip-back path used in the 2026-04-27 the "`/wr-itil:manage-problem` Step 2 substep 7 session-id discovery is brittle — agent has no env var, must scrape marker filenames" problem regression flip-back). The Step 9d output table records each close action with its triggering citation + the documented recovery path.
|
|
1030
1030
|
|
|
1031
1031
|
**Step 9e: Update files and refresh README.md cache**
|
|
1032
1032
|
|
|
1033
1033
|
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.
|
|
1034
1034
|
|
|
1035
|
-
**WSJF Rankings tier + tie-break sort (
|
|
1035
|
+
**WSJF Rankings tier + tie-break sort (the "`docs/problems/README.md` WSJF Rankings table row order doesn't match `/wr-itil:work-problems`'s tie-break selection — users assume the orchestrator is broken" problem + the "Inbound-reported problems rank ahead of internally-discovered problems via a sort tier" architecture rule)**: 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 (the "Inbound-reported problems rank ahead of internally-discovered problems via a sort tier" architecture rule) --> <!-- 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 the "Problem 094: `/wr-itil:manage-problem` does not refresh `docs/problems/README.md` on ticket creation" problem block, the Step 7 the "Problem 062: `manage-problem` does not refresh `docs/problems/README.md` on single-ticket transitions; fast-path cache goes stale silently" problem block, AND `/wr-itil:review-problems` SKILL.md Step 3 / Step 5 — drift here re-opens the "`docs/problems/README.md` WSJF Rankings table row order doesn't match `/wr-itil:work-problems`'s tie-break selection — users assume the orchestrator is broken" problem / the "Inbound-reported problems rank ahead of internally-discovered problems via a sort tier" architecture rule.
|
|
1036
1036
|
|
|
1037
1037
|
```markdown
|
|
1038
1038
|
# Problem Backlog
|
|
@@ -1049,7 +1049,7 @@ Edit each problem file where the priority changed. Then write/overwrite `docs/pr
|
|
|
1049
1049
|
|
|
1050
1050
|
## Verification Queue
|
|
1051
1051
|
|
|
1052
|
-
Fix released, awaiting user verification (driven off `docs/problems/*.verifying.md` via glob — per
|
|
1052
|
+
Fix released, awaiting user verification (driven off `docs/problems/*.verifying.md` via glob — per the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule). Sorted by `Released date ASC` (oldest at row 1; same-day releases tiebreak by ID ASC). <!-- VQ-SORT-DIRECTION: oldest-first per the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule --> Drift here re-opens the "docs/problems/README.md Verification Queue rendered newest-first contradicts section header "Ranked by release age, oldest first"" problem — any change to VQ sort direction MUST update the Step 5 the "Problem 094: `/wr-itil:manage-problem` does not refresh `docs/problems/README.md` on ticket creation" problem block, the Step 7 the "Problem 062: `manage-problem` does not refresh `docs/problems/README.md` on single-ticket transitions; fast-path cache goes stale silently" problem block, the Step 9c presentation block, this template, AND `/wr-itil:review-problems` + `/wr-itil:transition-problem` + `/wr-itil:transition-problems` + `/wr-itil:reconcile-readme` + `/wr-itil:list-problems`. The `Likely verified?` column carries an **evidence-first** cell per the "VQ `Likely verified?` column uses age-based heuristic (≥14 days = yes) instead of session-observed evidence — sibling proxy-for-evidence anti-pattern to" problem — three canonical values: `yes — observed: <evidence>`, `no — not observed` (default for newly-released tickets), `no — observed regression`. <!-- LIKELY-VERIFIED-CELL-SHAPE: evidence-based per the "VQ `Likely verified?` column uses age-based heuristic (≥14 days = yes) instead of session-observed evidence — sibling proxy-for-evidence anti-pattern to" problem --> Age is preserved separately via the `Released` column — drift on the cell shape re-opens the "VQ `Likely verified?` column uses age-based heuristic (≥14 days = yes) instead of session-observed evidence — sibling proxy-for-evidence anti-pattern to" problem.
|
|
1053
1053
|
|
|
1054
1054
|
| ID | Title | Released | Fix summary | Likely verified? |
|
|
1055
1055
|
|----|-------|----------|-------------|------------------|
|
|
@@ -1064,14 +1064,14 @@ Fix released, awaiting user verification (driven off `docs/problems/*.verifying.
|
|
|
1064
1064
|
...
|
|
1065
1065
|
```
|
|
1066
1066
|
|
|
1067
|
-
Then commit all changed files per
|
|
1067
|
+
Then commit all changed files per the "Governance Skills Commit Their Own Completed Work" architecture rule:
|
|
1068
1068
|
1. `git add` the changed problem files and `docs/problems/README.md`
|
|
1069
1069
|
2. Satisfy the commit gate — two paths are valid (either produces a bypass marker):
|
|
1070
1070
|
- **Primary**: delegate to the `wr-risk-scorer:pipeline` subagent-type via the Agent tool
|
|
1071
|
-
- **Fallback**: if the `wr-risk-scorer:pipeline` subagent-type is not available in the current tool set (e.g., this skill is itself running inside a spawned subagent), invoke the `/wr-risk-scorer:assess-release` skill via the Skill tool. Per
|
|
1071
|
+
- **Fallback**: if the `wr-risk-scorer:pipeline` subagent-type is not available in the current tool set (e.g., this skill is itself running inside a spawned subagent), invoke the `/wr-risk-scorer:assess-release` skill via the Skill tool. Per the "On-Demand Assessment Skills for Governance Plugins" architecture rule it wraps the same pipeline subagent and produces an equivalent bypass marker via the `PostToolUse:Agent` hook. Do not silently skip the gate because the primary path is unavailable — the fallback exists specifically to close this gap (see the "Problem 035: manage-problem commit gate has no fallback when subagent delegation is unavailable" problem).
|
|
1072
1072
|
3. `git commit -m "docs(problems): review — re-rank priorities"`
|
|
1073
1073
|
|
|
1074
|
-
If `AskUserQuestion` is unavailable and risk is above appetite, skip the commit and report the uncommitted state (
|
|
1074
|
+
If `AskUserQuestion` is unavailable and risk is above appetite, skip the commit and report the uncommitted state (the "Structured User Interaction for Governance-Skill Decisions" architecture rule Rule 6 fail-safe). This applies only to the risk-above-appetite branch, not to the delegation-unavailable case above.
|
|
1075
1075
|
|
|
1076
1076
|
### 10. Quality checks
|
|
1077
1077
|
|
|
@@ -1094,34 +1094,34 @@ After any operation, report:
|
|
|
1094
1094
|
- The current status
|
|
1095
1095
|
- Any quality check warnings
|
|
1096
1096
|
|
|
1097
|
-
Commit the completed work per
|
|
1098
|
-
1. `git add` all created/modified files for this operation — **including any file renamed via `git mv` that was then modified by the `Edit` tool** (
|
|
1097
|
+
Commit the completed work per the "Governance Skills Commit Their Own Completed Work" architecture rule (governance skills commit their own work):
|
|
1098
|
+
1. `git add` all created/modified files for this operation — **including any file renamed via `git mv` that was then modified by the `Edit` tool** (the "Problem 057: `git mv` + Edit + `git add` staging-ordering trap drops content edits from the commit" problem staging trap — `git mv` alone stages only the rename, not the subsequent content edit). `git add -u` is a safe catch-all for tracked modifications. **For any Step 7 status transition** (Open → Known Error, Known Error → Verification Pending, Verification Pending → Closed, or Parked) — including folded-fix commits where the `.verifying.md` transition rides with a `fix(<scope>): ...` commit — the stage list MUST include `docs/problems/README.md` refreshed per Step 7's "README.md refresh on every transition" block (the "Problem 062: `manage-problem` does not refresh `docs/problems/README.md` on single-ticket transitions; fast-path cache goes stale silently" problem). Skipping the refresh leaks staleness to the next session's fast-path. **For any Step 5 new-ticket creation** (single or multi-concern split) and for any Step 6 update that changed Priority / Effort / WSJF, the stage list MUST include `docs/problems/README.md` refreshed per the "Problem 094: `/wr-itil:manage-problem` does not refresh `docs/problems/README.md` on ticket creation" problem blocks in those steps. Creation-path and ranking-change-update-path refreshes are treated identically to Step 7 transitions — single-commit transaction, README alongside the ticket.
|
|
1099
1099
|
2. Satisfy the commit gate — two paths are valid (either produces a bypass marker):
|
|
1100
1100
|
- **Primary**: delegate to the `wr-risk-scorer:pipeline` subagent-type via the Agent tool (subagent_type: `wr-risk-scorer:pipeline`)
|
|
1101
|
-
- **Fallback**: if the `wr-risk-scorer:pipeline` subagent-type is not available in the current tool set (e.g., this skill is itself running inside a spawned subagent), invoke the `/wr-risk-scorer:assess-release` skill via the Skill tool. Per
|
|
1102
|
-
3. Land the commit via the **`wr-risk-scorer-restage-commit`** helper — atomic re-stage + commit in a single bash call (
|
|
1101
|
+
- **Fallback**: if the `wr-risk-scorer:pipeline` subagent-type is not available in the current tool set (e.g., this skill is itself running inside a spawned subagent), invoke the `/wr-risk-scorer:assess-release` skill via the Skill tool. Per the "On-Demand Assessment Skills for Governance Plugins" architecture rule it wraps the same pipeline subagent and the `PostToolUse:Agent` hook writes an equivalent bypass marker. Do not silently skip the gate because the primary path is unavailable — the fallback exists specifically to close this gap (see the "Problem 035: manage-problem commit gate has no fallback when subagent delegation is unavailable" problem).
|
|
1102
|
+
3. Land the commit via the **`wr-risk-scorer-restage-commit`** helper — atomic re-stage + commit in a single bash call (the "Staged index is cleared after a `wr-risk-scorer:pipeline` Agent delegation — forces a re-`git add` before the commit lands" problem wrapper):
|
|
1103
1103
|
```bash
|
|
1104
1104
|
wr-risk-scorer-restage-commit -m "<message>" -- <path1> [<path2>...]
|
|
1105
1105
|
```
|
|
1106
|
-
The Agent-tool delegation in step 2 can silently clear the parent index — a subsequent bare `git commit` then fails with `Changes not staged for commit`. The helper re-adds the supplied paths, asserts the cached diff is non-empty, then runs `git commit "${msg_args[@]}"` — eliminating the silent re-add round-trip
|
|
1106
|
+
The Agent-tool delegation in step 2 can silently clear the parent index — a subsequent bare `git commit` then fails with `Changes not staged for commit`. The helper re-adds the supplied paths, asserts the cached diff is non-empty, then runs `git commit "${msg_args[@]}"` — eliminating the silent re-add round-trip the "Staged index is cleared after a `wr-risk-scorer:pipeline` Agent delegation — forces a re-`git add` before the commit lands" problem documents. Pass repeated `-m` flags for trailer paragraphs (e.g. `RISK_BYPASS:` allow-list tokens).
|
|
1107
1107
|
4. Message conventions per operation type:
|
|
1108
1108
|
- New problem: `docs(problems): open P<NNN> <title>`
|
|
1109
1109
|
- Known Error transition: `docs(problems): P<NNN> known error — <root cause summary>`
|
|
1110
1110
|
- Verification Pending transition: usually folded into the `fix(<scope>): ... (closes P<NNN>)` commit that ships the fix — the `git mv` to `.verifying.md` and the `## Fix Released` section land together. If transitioning without a fix commit, use `docs(problems): P<NNN> verification pending — <release marker>`.
|
|
1111
1111
|
- Problem closed: `docs(problems): close P<NNN> <title>`
|
|
1112
1112
|
- Review/re-rank: `docs(problems): review — re-rank priorities`
|
|
1113
|
-
- Fix implemented: `fix(<scope>): <description> (closes P<NNN>)` — include problem file changes (rename to `.verifying.md` + `## Fix Released` section) in the same commit per
|
|
1114
|
-
5. If commit risk is above appetite: auto-apply scorer remediations per **
|
|
1113
|
+
- Fix implemented: `fix(<scope>): <description> (closes P<NNN>)` — include problem file changes (rename to `.verifying.md` + `## Fix Released` section) in the same commit per the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule
|
|
1114
|
+
5. If commit risk is above appetite: auto-apply scorer remediations per **the "Auto-apply scorer remediations to reach within appetite — open action-class vocabulary" architecture rule Rule 1** incrementally until residual commit risk is within appetite (≤ 4/25), OR halt per the "Auto-apply scorer remediations to reach within appetite — open action-class vocabulary" architecture rule Rule 5 if the scorer cannot converge. **The skill MUST NOT commit above appetite, and MUST NOT call `AskUserQuestion` to ask whether to commit anyway** (the "Skills, agents, and hooks override RISK-POLICY appetite instead of applying it" problem/the ": Apply RISK-POLICY appetite faithfully across all surfaces" release design amendment 2026-06-24 — above-appetite is framework-mediated, never a category-3 one-time-override; same invariant the push/release branch at Step 12 already enforces). The "Structured User Interaction for Governance-Skill Decisions" architecture rule Rule 6 fail-safe (no `AskUserQuestion` available / non-interactive → skip the commit and report the uncommitted state) remains the terminal fallback. This applies only to the risk-above-appetite branch, not to the delegation-unavailable case above.
|
|
1115
1115
|
|
|
1116
|
-
**Multi-commit slice changeset discipline (
|
|
1116
|
+
**Multi-commit slice changeset discipline (the "AFK iter `packages/<plugin>/` commits without changesets — orchestrator-main-turn back-fill is fragile recovery, hook-level enforcement preferable" problem Phase 2)**: when a single logical fix lands across multiple the "Governance Skills Commit Their Own Completed Work" architecture rule-grain commits targeting the same plugin (e.g. helper extraction in commit 1, callers wired in commit 2, SKILL note + transition in commit 3 — all `packages/<plugin>/`), author ONE changeset on the first commit in the slice. Subsequent same-plugin commits do NOT need their own changeset — the `itil-changeset-discipline.sh` hook's Check 2b recognises any `.changeset/*.md` already in the unpushed slice scope (`origin/<base>..HEAD` + untracked + modified-not-staged) that targets `"@windyroad/<plugin>": <any-bump>` and allows. This eliminates the per-commit changeset ceremony that previously produced N redundant `.changeset/*.md` files for one logical release entry (changesets-action collapses bump-class at version-package time, so per-commit changesets rendered N near-identical CHANGELOG bullets for one release). Once a changeset hits `origin/<base>` (drained at release time), it no longer counts — a fresh changeset is required for the next slice. Cross-plugin coverage is NOT permitted: an `@windyroad/itil` changeset does not satisfy a `packages/voice-tone/` commit.
|
|
1117
1117
|
|
|
1118
|
-
### 12. Auto-release when changesets are queued (
|
|
1118
|
+
### 12. Auto-release when changesets are queued (the "Governance skills auto-release when changesets are queued" architecture rule)
|
|
1119
1119
|
|
|
1120
|
-
**Skip this step if the skill is running inside an AFK orchestrator** (e.g. `/wr-itil:work-problems`). Orchestrators handle release cadence themselves per
|
|
1120
|
+
**Skip this step if the skill is running inside an AFK orchestrator** (e.g. `/wr-itil:work-problems`). Orchestrators handle release cadence themselves per the "Inter-iteration release cadence for AFK loops" architecture rule (Step 6.5). Detect via the presence of an orchestrator marker in the invoking prompt — look for phrases like "AFK", "work-problems", "batch-work", or the sentinel `ALL_DONE` convention. When in doubt, defer to the orchestrator by skipping this step.
|
|
1121
1121
|
|
|
1122
1122
|
Otherwise, after the commit in step 11 lands, drain the release queue so the fix actually lands on npm without requiring manual user action.
|
|
1123
1123
|
|
|
1124
|
-
**Mechanism — delegate, do not re-implement scoring (per
|
|
1124
|
+
**Mechanism — delegate, do not re-implement scoring (per the "On-Demand Assessment Skills for Governance Plugins" architecture rule):**
|
|
1125
1125
|
|
|
1126
1126
|
1. Invoke the release scorer. Two paths are valid:
|
|
1127
1127
|
- **Primary**: delegate to subagent type `wr-risk-scorer:pipeline` via the Agent tool.
|
|
@@ -1129,7 +1129,7 @@ Otherwise, after the commit in step 11 lands, drain the release queue so the fix
|
|
|
1129
1129
|
2. Read the returned `RISK_SCORES: commit=X push=Y release=Z` line.
|
|
1130
1130
|
3. **Drain condition**: if `push` and `release` are both within appetite (≤ 4/25, "Low" band per `RISK-POLICY.md`), AND `.changeset/` is non-empty, proceed to the drain action. Otherwise, skip the drain and report the unreleased state.
|
|
1131
1131
|
|
|
1132
|
-
**Drain action (non-interactive, policy-authorised per
|
|
1132
|
+
**Drain action (non-interactive, policy-authorised per the "Structured User Interaction for Governance-Skill Decisions" architecture rule Rule 6):**
|
|
1133
1133
|
|
|
1134
1134
|
1. Run `npm run push:watch` (push + wait for CI to pass).
|
|
1135
1135
|
2. If `.changeset/` remains non-empty after push (i.e. a release PR is pending), run `npm run release:watch` (merge the release PR + wait for npm publish).
|
|
@@ -1137,18 +1137,18 @@ Otherwise, after the commit in step 11 lands, drain the release queue so the fix
|
|
|
1137
1137
|
|
|
1138
1138
|
**Failure handling**: If `release:watch` fails (CI failure, publish failure), stop and report the failure clearly. Do not retry non-interactively — the user must intervene.
|
|
1139
1139
|
|
|
1140
|
-
**Above-appetite branch (per
|
|
1140
|
+
**Above-appetite branch (per the "Auto-apply scorer remediations to reach within appetite — open action-class vocabulary" architecture rule)**: If push or release risk is above appetite (≥ 5/25), the skill MUST auto-apply scorer remediations incrementally until residual risk converges within appetite, OR halt the skill per the "Auto-apply scorer remediations to reach within appetite — open action-class vocabulary" architecture rule Rule 5 if the scorer cannot produce a convergent plan. **The skill MUST NOT release above appetite under any circumstance.** The skill MUST NOT call `AskUserQuestion` as a shortcut out of the auto-apply loop.
|
|
1141
1141
|
|
|
1142
|
-
**Auto-apply mechanism (
|
|
1142
|
+
**Auto-apply mechanism (the "Auto-apply scorer remediations to reach within appetite — open action-class vocabulary" architecture rule Rule 2):**
|
|
1143
1143
|
|
|
1144
|
-
1. Parse the scorer's `RISK_REMEDIATIONS:` block. Expected shape per
|
|
1144
|
+
1. Parse the scorer's `RISK_REMEDIATIONS:` block. Expected shape per the "On-Demand Assessment Skills for Governance Plugins" architecture rule / the "Auto-apply scorer remediations to reach within appetite — open action-class vocabulary" architecture rule Rule 2a (5 columns):
|
|
1145
1145
|
```
|
|
1146
1146
|
RISK_REMEDIATIONS:
|
|
1147
1147
|
- R1 | <description> | <effort S/M/L> | <risk_delta -N> | <files affected>
|
|
1148
1148
|
- R2 | ...
|
|
1149
1149
|
```
|
|
1150
1150
|
2. Read the descriptions. Decide what to do. The agent MAY follow a scorer suggestion, adapt it, or do something else entirely. There is no requirement to rank all suggestions upfront or iterate through them in order.
|
|
1151
|
-
3. **Verification Pending carve-out (
|
|
1151
|
+
3. **Verification Pending carve-out (the "Auto-apply scorer remediations to reach within appetite — open action-class vocabulary" architecture rule Rule 2b)**: skip remediations that target a commit attached to a `.verifying.md` ticket. Do NOT auto-revert VP commits.
|
|
1152
1152
|
4. Apply the chosen action using standard primitives (git, Edit, Bash). Example actions:
|
|
1153
1153
|
- `revert-commit`: `git revert --no-edit <sha>`. The scorer SHOULD supply the target commit SHA in the `description` column. Before executing, verify the SHA is NOT attached to a `.verifying.md` ticket (Rule 2b carve-out). After revert, commit the revert as a standalone auto-apply commit (no amend folding in non-AFK mode). If `git revert` produces merge conflicts, route to Rule 5 halt with the conflict detail.
|
|
1154
1154
|
- `split-change`: split the work into independently releasable, within-appetite commits and re-score each slice.
|
|
@@ -1160,10 +1160,10 @@ Otherwise, after the commit in step 11 lands, drain the release queue so the fix
|
|
|
1160
1160
|
- The final `RISK_SCORES:` line
|
|
1161
1161
|
- An "Auto-apply trail" subsection listing each remediation attempted with outcome
|
|
1162
1162
|
- Any Verification Pending ticket IDs implicated per Rule 2b
|
|
1163
|
-
- A one-line scorer-gap note (e.g., "available remediations did not reduce residual risk below 5/25 — extend scorer vocabulary per
|
|
1163
|
+
- A one-line scorer-gap note (e.g., "available remediations did not reduce residual risk below 5/25 — extend scorer vocabulary per the "Scorer `RISK_REMEDIATIONS:` block is free-form prose — agent must parse descriptions to decide what to do" problem")
|
|
1164
1164
|
|
|
1165
1165
|
The user resolves interactively — typical resolutions include splitting the commit, feature-flagging the change, or opening a problem ticket documenting the scorer gap.
|
|
1166
1166
|
|
|
1167
|
-
`push:watch` and `release:watch` are policy-authorised actions when residual risk is within appetite per RISK-POLICY.md, so no `AskUserQuestion` is required for the drain itself (
|
|
1167
|
+
`push:watch` and `release:watch` are policy-authorised actions when residual risk is within appetite per RISK-POLICY.md, so no `AskUserQuestion` is required for the drain itself (the "Structured User Interaction for Governance-Skill Decisions" architecture rule Rule 5). Auto-apply actions under Rules 2–7 are also policy-authorised per the "Structured User Interaction for Governance-Skill Decisions" architecture rule Rule 5 — `RISK-POLICY.md` appetite + the "Auto-apply scorer remediations to reach within appetite — open action-class vocabulary" architecture rule eligibility constitute the policy.
|
|
1168
1168
|
|
|
1169
1169
|
$ARGUMENTS
|