@windyroad/itil 2.0.0 → 2.1.1-preview.1128
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/bin/wr-itil-is-close-blocked +51 -0
- package/lib/install-utils.mjs +138 -8
- package/package.json +1 -1
- package/scripts/is-close-blocked.sh +93 -0
- package/skills/manage-problem/SKILL.md +34 -11
- package/skills/review-problems/SKILL.md +2 -2
- package/skills/transition-problem/SKILL.md +41 -5
- package/skills/transition-problems/SKILL.md +17 -3
- package/skills/update-upstream/SKILL.md +81 -9
- package/skills/work-problems/SKILL.md +52 -10
- package/skills-codex/capture-problem/SKILL.md +1 -1
- package/skills-codex/capture-rfc/SKILL.md +1 -1
- package/skills-codex/capture-story/SKILL.md +1 -1
- package/skills-codex/capture-story-map/SKILL.md +1 -1
- package/skills-codex/check-upstream-responses/SKILL.md +1 -1
- package/skills-codex/close-incident/SKILL.md +1 -1
- package/skills-codex/link-incident/SKILL.md +1 -1
- package/skills-codex/list-incidents/SKILL.md +1 -1
- package/skills-codex/list-problems/SKILL.md +1 -1
- package/skills-codex/list-stories/SKILL.md +1 -1
- package/skills-codex/list-story-maps/SKILL.md +1 -1
- package/skills-codex/manage-incident/SKILL.md +1 -1
- package/skills-codex/manage-problem/SKILL.md +35 -12
- package/skills-codex/manage-rfc/SKILL.md +1 -1
- package/skills-codex/manage-story/SKILL.md +1 -1
- package/skills-codex/manage-story-map/SKILL.md +1 -1
- package/skills-codex/mitigate-incident/SKILL.md +1 -1
- package/skills-codex/reconcile-readme/SKILL.md +1 -1
- package/skills-codex/reconcile-stories/SKILL.md +1 -1
- package/skills-codex/reconcile-story-maps/SKILL.md +1 -1
- package/skills-codex/report-upstream/SKILL.md +1 -1
- package/skills-codex/restore-incident/SKILL.md +1 -1
- package/skills-codex/review-problems/SKILL.md +3 -3
- package/skills-codex/scaffold-intake/SKILL.md +1 -1
- package/skills-codex/transition-problem/SKILL.md +42 -6
- package/skills-codex/transition-problems/SKILL.md +18 -4
- package/skills-codex/update-upstream/SKILL.md +82 -10
- package/skills-codex/work-problem/SKILL.md +1 -1
- package/skills-codex/work-problems/SKILL.md +70 -17
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: manage-rfc
|
|
3
3
|
description: Heavyweight RFC intake + lifecycle management following the "Problem-RFC-Story framework with mandatory problem-trace and unified problem ontology" architecture rule Problem-RFC-Story framework. Creates new RFCs (delegates to /wr-itil:capture-rfc for the lightweight path), updates existing RFCs, transitions through proposed → accepted → in-progress → verifying → closed lifecycle, runs WSJF re-rank reviews, and refreshes docs/rfcs/README.md per the "Problem 062: `manage-problem` does not refresh `docs/problems/README.md` on single-ticket transitions; fast-path cache goes stale silently" problem / the "Problem 094: `/wr-itil:manage-problem` does not refresh `docs/problems/README.md` on ticket creation" problem contract pattern.
|
|
4
4
|
allowed-tools: Read, Write, Edit, Bash, Grep, Glob, Task
|
|
5
5
|
---
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: manage-story
|
|
3
3
|
description: Heavyweight story intake + lifecycle management following the "Problem-RFC-Story framework with mandatory problem-trace and unified problem ontology" architecture rule Phase 2. Creates and updates story tickets, transitions through draft → accepted → in-progress → done → archived lifecycle, enforces I7 + I8 trace-gate at the accepted transition, runs INVEST checks per I10 at acceptance, auto-detects accepted→in-progress on the first implementing commit and in-progress→done on all-criteria-ticked + linked RFC closes (per the "A story cannot be implemented while in draft — implementation requires accepted" architecture rule a draft story is NEVER implementable — draft→in-progress is removed; the itil-no-implement-draft-gate blocks implementing a draft story), and refreshes docs/stories/README.md per the "Problem 062: `manage-problem` does not refresh `docs/problems/README.md` on single-ticket transitions; fast-path cache goes stale silently" problem / the "Problem 094: `/wr-itil:manage-problem` does not refresh `docs/problems/README.md` on ticket creation" problem contract pattern. Companion to /wr-itil:capture-story (lightweight aside surface).
|
|
4
4
|
allowed-tools: Read, Write, Edit, Bash, Grep, Glob
|
|
5
5
|
---
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: manage-story-map
|
|
3
3
|
description: Heavyweight story-map intake + lifecycle management following the "Problem-RFC-Story framework with mandatory problem-trace and unified problem ontology" architecture rule Phase 2. Authors backbone × ribs × slices structure on draft maps, transitions through draft → accepted → in-progress → completed → archived, re-validates I3 + I4 invariants at every transition, and refreshes docs/story-maps/README.md per the "Problem 062: `manage-problem` does not refresh `docs/problems/README.md` on single-ticket transitions; fast-path cache goes stale silently" problem / the "Problem 094: `/wr-itil:manage-problem` does not refresh `docs/problems/README.md` on ticket creation" problem contract pattern. Companion to /wr-itil:capture-story-map (lightweight aside surface).
|
|
4
4
|
allowed-tools: Read, Write, Edit, Bash, Grep, Glob
|
|
5
5
|
---
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: mitigate-incident
|
|
3
3
|
description: Record a mitigation attempt against an incident — transitions an investigating incident to mitigating on the first attempt, appends subsequent attempts to the Mitigation attempts timeline. Evidence-first gate enforced per the "Add `manage-incident` Skill to `wr-itil` Plugin" architecture rule.
|
|
4
4
|
allowed-tools: Read, Write, Edit, Bash, Glob, Grep, request_user_input, Skill
|
|
5
5
|
---
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: reconcile-readme
|
|
3
3
|
description: Detect and correct drift between docs/problems/README.md and the on-disk ticket inventory. Wraps the diagnose-only `<itil-plugin-root>/scripts/reconcile-readme.sh` script with an agent-applied-edits pattern that preserves narrative content (the "Last reviewed" prose paragraph and Closed-section closure-via free text). Use when README WSJF Rankings, Verification Queue, or Closed sections drift from filesystem state — typically detected by manage-problem Step 0 preflight or work-problems Step 0 preflight.
|
|
4
4
|
allowed-tools: Read, Edit, Write, Bash, Grep, Glob
|
|
5
5
|
---
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: reconcile-stories
|
|
3
3
|
description: Detect and correct drift between docs/stories/README.md and the on-disk story inventory. Wraps the diagnose-only <itil-plugin-root>/scripts/reconcile-stories.sh script with an agent-applied-edits pattern that preserves narrative content (the "Last reviewed" prose paragraph). Use when docs/stories/README.md Story Rankings or Done sections drift from filesystem state — typically detected by manage-story Step 0 preflight or work-problems preflight on RFC iters with story-tier traces.
|
|
4
4
|
allowed-tools: Read, Write, Edit, Bash, Grep, Glob
|
|
5
5
|
---
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: reconcile-story-maps
|
|
3
3
|
description: Detect and correct drift between docs/story-maps/README.md and the on-disk story-map HTML inventory. Wraps the diagnose-only <itil-plugin-root>/scripts/reconcile-story-maps.sh script with an agent-applied-edits pattern preserving narrative content.
|
|
4
4
|
allowed-tools: Read, Write, Edit, Bash, Grep, Glob
|
|
5
5
|
---
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: report-upstream
|
|
3
3
|
description: Report a local problem ticket as a structured issue against an upstream repository, with bidirectional cross-references and SECURITY.md-aware routing for security-classified tickets. Implements the contract in the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule, with the "Report-upstream classifier is problem-first — supersedes Decision Outcome Steps 3 + 5" architecture rule governing problem-first classifier + default body shape.
|
|
4
4
|
allowed-tools: Read, Write, Edit, Bash, Glob, Grep, request_user_input, Skill, Agent
|
|
5
5
|
---
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: restore-incident
|
|
3
3
|
description: Mark an incident as service-restored — transitions a mitigating incident to restored, appends a Timeline entry, and hands off to /wr-itil:manage-problem for linked-problem creation or update per the "Add `manage-incident` Skill to `wr-itil` Plugin" architecture rule.
|
|
4
4
|
allowed-tools: Read, Write, Edit, Bash, Glob, Grep, request_user_input, Skill
|
|
5
5
|
---
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: review-problems
|
|
3
3
|
description: Re-assess every open and known-error problem ticket in docs/problems/ — re-read RISK-POLICY.md, re-rate Impact × Likelihood, re-estimate Effort, recalculate WSJF, surface pending verifications, auto-transition Open → Known Error where warranted, and rewrite docs/problems/README.md with the refreshed ranking. Writes to problem files and the README cache; commits the refresh per the "Governance Skills Commit Their Own Completed Work" architecture rule.
|
|
4
4
|
allowed-tools: Read, Write, Edit, Bash, Glob, Grep, request_user_input, Skill
|
|
5
5
|
---
|
|
@@ -32,7 +32,7 @@ When referencing problem IDs, ADR IDs, JTBD IDs, or RFC IDs in prose output (the
|
|
|
32
32
|
**In scope** (the ": docs/problems/ flat layout migration — per-state subdirs + adopter auto-migration" release design migration window — each glob is dual-tolerant, covering BOTH the flat `docs/problems/<NNN>-<title>.<state>.md` filename-suffix layout AND the per-state subdir `docs/problems/<state>/<NNN>-<title>.md` layout):
|
|
33
33
|
|
|
34
34
|
- `docs/problems/*.open.md` + `docs/problems/open/*.md` and `docs/problems/*.known-error.md` + `docs/problems/known-error/*.md` — re-scored (Impact × Likelihood × Effort → WSJF); Priority + Effort + WSJF lines updated when they change.
|
|
35
|
-
- `docs/problems/*.verifying.md` + `docs/problems/verifying/*.md` — surfaced in the Verification Queue and fed to Step 4's verification
|
|
35
|
+
- `docs/problems/*.verifying.md` + `docs/problems/verifying/*.md` — surfaced in the Verification Queue and fed to Step 4's verification routing (the Verification Pending → Closed path — Bucket 1 closes on evidence, Bucket 2 asks, Bucket 3 flips back).
|
|
36
36
|
- `docs/problems/*.parked.md` + `docs/problems/parked/*.md` — listed in the Parked section; NOT re-scored (WSJF multiplier is 0).
|
|
37
37
|
- `docs/problems/README.md` — rewritten with the refreshed WSJF Rankings + Verification Queue + Parked tables; staged and committed with the review.
|
|
38
38
|
|
|
@@ -124,7 +124,7 @@ Omit an empty section rather than rendering an empty header.
|
|
|
124
124
|
|
|
125
125
|
Target the dual-tolerant glob `docs/problems/*.verifying.md docs/problems/verifying/*.md` (the ": docs/problems/ flat layout migration — per-state subdirs + adopter auto-migration" release design migration window) — 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). Bucket each verifying ticket by its Step-3 `Likely verified?` cell (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 evidence-first cell shape: `yes — observed: <evidence>` / `no — not observed` / `no — observed regression`) and route each bucket differently. **Do NOT fire one `request_user_input` per ticket** — the evidence-backed subset closes on evidence; only the unobserved subset asks.
|
|
126
126
|
|
|
127
|
-
**Bucket 1 — `yes — observed: <evidence>` → close-on-evidence
|
|
127
|
+
**Bucket 1 — `yes — observed: <evidence>` → close-on-evidence.** Specific observed evidence authorizes a mechanical close without asking again. First run `<itil-plugin-root>/bin/wr-itil-is-close-blocked <NNN> docs/problems`: exit 0 keeps the ticket open and reports the matched marker; exit 2 is a pre-flight failure; exit 1 proceeds. Move the ticket to `.closed.md`, re-stage it, and persist the authority in `**Status**: Closed (closed-on-evidence <YYYY-MM-DD> — <citation>. Recovery: rerun /wr-itil:transition-problem <NNN> known-error to reopen)`. A provenance-proven GitHub issue on this project's tracker receives the gated comment and closes; unresolved or non-issue inbound provenance performs no issue mutation. A foreign issue receives the comment but stays open on local evidence alone, while that upstream party's confirmation may authorize closure. Pull requests remain comment-only. Update the review cell with the same evidence citation and report the reversible recovery path.
|
|
128
128
|
|
|
129
129
|
**Bucket 2 — `no — not observed` → ask (genuine user-authority).** No session-observable evidence yet, so the user may hold out-of-band production knowledge the agent cannot observe — this is the genuine user-input surface. Use `request_user_input` to ask whether the fix has been verified in production. The question MUST include a fix summary extracted from the `## Fix Released` section — inline the first sentence (or first bullet list) of that section in the question body or option description per the brief-before-ID discipline, so the user can answer without reading the full problem file. Do NOT ask with only the problem ID + title + version.
|
|
130
130
|
- If the user confirms: close the problem (`git mv` from `.verifying.md` to `.closed.md`, update Status to "Closed", re-stage per the "Problem 057: `git mv` + Edit + `git add` staging-ordering trap drops content edits from the commit" problem staging trap). Update the `Likely verified?` cell to `yes — observed: user confirmed <YYYY-MM-DD>`.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: scaffold-intake
|
|
3
3
|
description: Scaffold the four OSS intake surfaces (.github/ISSUE_TEMPLATE/, SECURITY.md, SUPPORT.md, CONTRIBUTING.md) for a downstream project that adopts @windyroad/itil. Idempotent, foreground-synchronous, and respects the "Gate Marker Lifecycle: TTL + Drift, Not Stop-Hook Reset" architecture rule marker semantics. Implements the contract in the "Scaffold downstream OSS intake — skill + layered triggers" architecture rule.
|
|
4
4
|
allowed-tools: Read, Write, Edit, Bash, Glob, Grep, request_user_input
|
|
5
5
|
---
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: transition-problem
|
|
3
3
|
description: Advance a problem ticket's lifecycle status — Open → Known Error, Known Error → Verification Pending (verifying), Verification Pending → Closed. Renames the ticket file, updates the Status field, and refreshes docs/problems/README.md in the same commit. Hosts the transition execution inline (pre-flight checks, the "Problem 057: `git mv` + Edit + `git add` staging-ordering trap drops content edits from the commit" problem staging-trap handling, the "Problem 063: manage-problem does not trigger /wr-itil:report-upstream when root cause is external" problem external-root-cause detection, 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, the "Governance Skills Commit Their Own Completed Work" architecture rule commit) per the "Rename `wr-problem` Plugin to `wr-itil`" architecture rule amended "Split-skill execution ownership". Use when the user asks to "transition", "close", "mark known-error", or "release" a specific ticket.
|
|
4
4
|
allowed-tools: Read, Write, Edit, Bash, Glob, Grep, request_user_input, Skill
|
|
5
5
|
---
|
|
@@ -29,7 +29,7 @@ The deprecated `/wr-itil:manage-problem <NNN> known-error` subcommand route rema
|
|
|
29
29
|
- `<status>` — the destination status. One of:
|
|
30
30
|
- `known-error` — Open → Known Error (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; the fix proposal draws a release row on a story map).
|
|
31
31
|
- `verifying` — Known Error → Verification Pending (fix released, awaiting user verification per the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule).
|
|
32
|
-
- `close` — Verification Pending → Closed (user has confirmed the fix works in production).
|
|
32
|
+
- `close` — Verification Pending → Closed (cited evidence meets the ticket's own close criterion, OR the user has confirmed the fix works in production — see Step 4).
|
|
33
33
|
|
|
34
34
|
The `<NNN>` and `<status>` tokens are **data parameters**, not word-subcommands. Per the "Problem 071: Argument-based skill subcommands are not discoverable in Codex autocomplete" problem split rule (the "Rename `wr-problem` Plugin to `wr-itil`" architecture rule amended), data parameters (IDs, paths, URLs, enum destinations) are permitted; word-subcommands that name distinct user intents are not. This skill's argument shape is `data + data`, which is the same shape as `/wr-itil:report-upstream <NNN>`.
|
|
35
35
|
|
|
@@ -79,8 +79,12 @@ Check the current filename suffix and verify the destination status is reachable
|
|
|
79
79
|
| `.open.md` | `known-error` | yes |
|
|
80
80
|
| `.known-error.md` | `verifying` | yes |
|
|
81
81
|
| `.verifying.md` | `close` | yes |
|
|
82
|
+
| `.verifying.md` | `known-error` | yes — **flip-back**: the fix recurred or proved incomplete. Required by `review-problems` Bucket 3, `manage-problem`, and `run-retro` Step 4a, all of which already instruct it. |
|
|
83
|
+
| `.closed.md` | `known-error` | yes — **reopen**: a close was wrong. This is the recovery path every evidence-authorised close reports (the "The Verification Pending → Closed transition is reserved for the maintainer, so evidence-based closure never fires and the verification queue grows without bound" problem), so it has to be reachable or the reversibility that justifies closing without a consent gate is fiction. |
|
|
82
84
|
| any other pairing | — | no — emit an error and stop |
|
|
83
85
|
|
|
86
|
+
The two backward pairings are what make an agent-authorised close safe to make. The argument for closing on evidence without asking is that the close is cheap and reversible; a reopen route the skill refuses would make that argument false. Both are ordinary renames — `git mv` back to `known-error/`, Status field back to `Known Error`, append the recurrence or mis-close citation to the ticket body, refresh the README, one commit per the "Governance Skills Commit Their Own Completed Work" architecture rule — and neither re-runs the Open → Known Error pre-flight, because root cause and workaround were established the first time round. (the "The transition lifecycle table rejects both the fix-on-capture fast path and its own documented recovery path" problem tracks the wider set of missing pairings, including the fix-on-capture fast path.)
|
|
87
|
+
|
|
84
88
|
If the pairing is invalid, emit a clear message naming the current status, the requested destination, and the valid next step. Do not silently skip or auto-correct — invalid transitions are almost always user typos and a clear error is the cheapest recovery.
|
|
85
89
|
|
|
86
90
|
### 4. Run pre-flight checks
|
|
@@ -128,9 +132,34 @@ Emit a structured report naming each deferred section + the lifted condition + t
|
|
|
128
132
|
|
|
129
133
|
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 step in Step 6 — halt-on-conditional-deferral is the outer gate, seed-and-rename is the inner mechanic.
|
|
130
134
|
|
|
131
|
-
**Verification Pending → Closed** (`<status>` = `close`) requires:
|
|
135
|
+
**Verification Pending → Closed** (`<status>` = `close`) requires **either** of:
|
|
136
|
+
|
|
137
|
+
- [ ] **Cited evidence** that meets the ticket's own stated close criterion — a test invocation and its outcome, a commit SHA whose diff covers the fix path, a skill or hook invocation that exercised the fix and behaved as the fix contracts, a post-release invocation of the shipped artefact that behaved as the fix contracts, or a `yes — observed: <citation>` cell already carried in the Verification Queue. The agent closes on its own authority and records the citation in the closure. **Mechanical stage — do NOT fire `request_user_input`** (the "Agents over-ask in interactive sessions — conflating mechanical-stages with user-interactive-stages of multi-stage skill contracts (inverse-)" problem / the "— Decision-Delegation Contract: when agents act on the framework vs ask the user" architecture rule category 4, mirroring the shipped `review-problems` Step 4 Bucket 1 and `run-retro` Step 4a sub-step 5). Surface the recovery path alongside the close: `Recovery: rerun /wr-itil:transition-problem <NNN> known-error to reopen`.
|
|
138
|
+
- [ ] **The user has explicitly confirmed** the fix works in production, or an orchestrator supplied the `close` argument under prior user authorisation.
|
|
139
|
+
|
|
140
|
+
**Never close on inference — absence of evidence is not evidence.** A ticket nobody exercised stays Verification Pending, however old it is and however plausible the fix looks. "The fix is on disk", "it has been months", "that area has been touched a lot" and "the ADR that prescribed it shipped" are inference, not observation — see the "Relevance-close evaluator over-fires — a bare ADR/skill citation is read as "fix shipped", so live tickets return CLOSE-CANDIDATE" problem for what happens when a bare citation is read as proof of shipping. Closing tickets nobody exercised is the opposite failure and is exactly as wrong as never closing any.
|
|
141
|
+
|
|
142
|
+
**Genuine ambiguity stays the user's surface** — contested evidence, a fix that covers only part of the ticket, or a recorded do-not-close marker. Run the mechanical check first; it is a field read, not a judgement:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
<itil-plugin-root>/bin/wr-itil-is-close-blocked <NNN> docs/problems && close_blocked=1
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Exit 0 means **BLOCKED**: the ticket carries a line-anchored `DO NOT CLOSE` marker (`docs/problems/verifying/151-*.md` § "Regression / incomplete observed … DO NOT CLOSE" is the canonical shape). Do NOT close it whatever the evidence says — route it to the `verifying → known-error` flip-back, or queue it for the user. Exit 1 means not blocked. Exit 2 means the ticket ref did not resolve — treat as a pre-flight failure, not as permission.
|
|
149
|
+
|
|
150
|
+
**Evidence-authorised tracker updates.** Write the basis into the ticket's `**Status**:` line alongside the citation (`**Status**: Closed (closed-on-evidence <YYYY-MM-DD> — <citation>. Recovery: rerun /wr-itil:transition-problem <NNN> known-error to reopen)`). A provenance-proven GitHub issue on this project's tracker receives the gated comment and closes; unresolved or non-issue inbound provenance performs no issue mutation. A foreign issue receives the comment but stays open on our evidence alone; that upstream party's confirmation may authorize closure. Pull requests remain comment-only.
|
|
132
151
|
|
|
133
|
-
-
|
|
152
|
+
Authority: the "— Decision-Delegation Contract: when agents act on the framework vs ask the user" architecture rule (framework-resolution boundary — evidence-backed close is category 4, silent framework action; contested or absent evidence is category 1, queued not guessed), the "Agent output grounding — no fabricated quantitative estimates, cite + persist + uncertainty" architecture rule (cite the evidence, persist it, state the uncertainty), the "Structured User Interaction for Governance-Skill Decisions" architecture rule Rule 5 (policy-authorised silent proceed), 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 (evidence-based closure precedent on the open/known-error side of the same lifecycle), the "The Verification Pending → Closed transition is reserved for the maintainer, so evidence-based closure never fires and the verification queue grows without bound" problem (this contract).
|
|
153
|
+
|
|
154
|
+
**Verification Pending → Known Error** (`<status>` = `known-error` — flip-back) requires:
|
|
155
|
+
|
|
156
|
+
- [ ] A recurrence or incompleteness citation: what was observed, and when. Append it to the ticket body; the `Likely verified?` cell becomes `no — observed regression — <one-line citation>`.
|
|
157
|
+
|
|
158
|
+
**Closed → Known Error** (`<status>` = `known-error` — reopen) requires:
|
|
159
|
+
|
|
160
|
+
- [ ] A stated reason the close was wrong. Nothing more — this is the recovery path for an evidence-authorised close and it must stay one command deep, or the reversibility that justifies closing without a consent gate is not real.
|
|
161
|
+
|
|
162
|
+
Neither backward pairing re-runs the Open → Known Error pre-flight above: root cause and workaround were established when the ticket first reached Known Error and are still on the ticket. Neither fires the "Problem 063: manage-problem does not trigger /wr-itil:report-upstream when root cause is external" problem external-root-cause detection (Step 5 is Open → Known Error only).
|
|
134
163
|
|
|
135
164
|
### 5. External-root-cause detection (the "Problem 063: manage-problem does not trigger /wr-itil:report-upstream when root cause is external" problem — Open → Known Error only)
|
|
136
165
|
|
|
@@ -206,7 +235,7 @@ git mv docs/problems/known-error/<NNN>-<title>.md docs/problems/verifying/<NNN>-
|
|
|
206
235
|
git add docs/problems/verifying/<NNN>-<title>.md
|
|
207
236
|
```
|
|
208
237
|
|
|
209
|
-
The `## Fix Released` section contains: release marker (version, commit SHA, or date), one-sentence fix summary, "Awaiting user verification" line, and any exercise evidence from the releasing session. The `.verifying.md` suffix signals to every downstream consumer (work-problems classifier, review step 9d, README rendering) that the remaining work is
|
|
238
|
+
The `## Fix Released` section contains: release marker (version, commit SHA, or date), one-sentence fix summary, "Awaiting user verification" line, and any exercise evidence from the releasing session. The `.verifying.md` suffix signals to every downstream consumer (work-problems classifier, review step 9d, README rendering) that the remaining work is verification — by evidence or by the user — no file-body scan needed.
|
|
210
239
|
|
|
211
240
|
When this transition is folded into a `fix(<scope>): ... (closes P<NNN>)` commit (the common case), the `git mv` + `Edit` + re-stage + README refresh all join that single commit — never split across commits.
|
|
212
241
|
|
|
@@ -241,10 +270,17 @@ Use the structured values verbatim when authoring the `## Fix Released` section'
|
|
|
241
270
|
|
|
242
271
|
```bash
|
|
243
272
|
git mv docs/problems/verifying/<NNN>-<title>.md docs/problems/closed/<NNN>-<title>.md
|
|
244
|
-
# ... use the Edit tool to update the Status field
|
|
273
|
+
# ... use the Edit tool to update the Status field per the shape below ...
|
|
245
274
|
git add docs/problems/closed/<NNN>-<title>.md
|
|
246
275
|
```
|
|
247
276
|
|
|
277
|
+
**Write the close's authority basis into the Status field.** The Status line is the only place the basis survives — the `Likely verified?` cell lives in the README's Verification Queue table, and that row is deleted by this very transition, so a downstream reader (Step 7b's upstream leg) would find nothing there. Shape, matching what the 2026-07-15 closes already wrote (`docs/problems/closed/186-*.md:3`):
|
|
278
|
+
|
|
279
|
+
- Evidence-authorised: `**Status**: Closed (closed-on-evidence <YYYY-MM-DD> — <citation>. Recovery: rerun /wr-itil:transition-problem <NNN> known-error to reopen)`
|
|
280
|
+
- User-confirmed: `**Status**: Closed (user-confirmed <YYYY-MM-DD>)`
|
|
281
|
+
|
|
282
|
+
`closed-on-evidence` is what the outbound leg reads to keep a foreign issue open on our evidence alone. The inbound leg uses committed issue-channel provenance instead: ambiguity fails closed before any issue operation.
|
|
283
|
+
|
|
248
284
|
### 7. Refresh docs/problems/README.md (the "Problem 062: `manage-problem` does not refresh `docs/problems/README.md` on single-ticket transitions; fast-path cache goes stale silently" problem)
|
|
249
285
|
|
|
250
286
|
Every Step 7 status transition 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.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: transition-problems
|
|
3
3
|
description: "Batch-advance multiple problem tickets through the lifecycle in one invocation — Open → Known Error, Known Error → Verification Pending, Verification Pending → Closed. Loops the per-ticket /wr-itil:transition-problem mechanic (rename, Status edit, the "Problem 057: `git mv` + Edit + `git add` staging-ordering trap drops content edits from the commit" problem re-stage, the "Problem 063: manage-problem does not trigger /wr-itil:report-upstream when root cause is external" problem external-root-cause detection, 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) without paying N× SKILL.md reload latency or violating split-skill execution ownership. Produces ONE shared commit covering all surviving transitions per the "Governance Skills Commit Their Own Completed Work" architecture rule batch-grain. Use when closing the Verification Queue at the end of a `/wr-retrospective:run-retro` Step 4a pass, batch-closing release-aged verifyings during `/wr-itil:work-problems` AFK orchestration, or confirming multiple Step 9d verifications in `/wr-itil:manage-problem review`. Singular sibling — `/wr-itil:transition-problem` (one ticket per invocation)."
|
|
4
4
|
allowed-tools: Read, Write, Edit, Bash, Glob, Grep, request_user_input, Skill, Agent
|
|
5
5
|
---
|
|
@@ -46,7 +46,7 @@ A space-separated list of `<NNN> <status>` pairs. Repeating the singular skill's
|
|
|
46
46
|
- `<status>` — destination status. One of:
|
|
47
47
|
- `known-error` — Open → Known Error (root cause + workaround documented).
|
|
48
48
|
- `verifying` — Known Error → Verification Pending (fix released; awaiting user verification per the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule).
|
|
49
|
-
- `close` — Verification Pending → Closed (user has confirmed the fix works in production).
|
|
49
|
+
- `close` — Verification Pending → Closed (cited evidence meets the ticket's own close criterion, OR the user has confirmed the fix works in production — see Step 2c).
|
|
50
50
|
|
|
51
51
|
**Examples:**
|
|
52
52
|
|
|
@@ -111,13 +111,19 @@ If no file is found OR multiple files are found (suffix-exclusive lifecycle viol
|
|
|
111
111
|
| `.open.md` | `known-error` | yes |
|
|
112
112
|
| `.known-error.md` | `verifying` | yes |
|
|
113
113
|
| `.verifying.md` | `close` | yes |
|
|
114
|
+
| `.verifying.md` | `known-error` | yes — **flip-back**: the fix recurred or proved incomplete. `review-problems` Bucket 3 already instructs this and had no batch path. |
|
|
115
|
+
| `.closed.md` | `known-error` | yes — **reopen**: a close was wrong. The recovery path every evidence-authorised close reports (the "The Verification Pending → Closed transition is reserved for the maintainer, so evidence-based closure never fires and the verification queue grows without bound" problem). |
|
|
114
116
|
| any other pairing | — | no — record as `invalid-transition` and continue |
|
|
115
117
|
|
|
118
|
+
Lockstep with `/wr-itil:transition-problem` Step 3 per the drift clause below — the singular and plural tables move together or neither moves. The two backward pairings are what make an agent-authorised close safe: the argument for closing on evidence without asking is that the close is cheap and reversible, and a reopen route either skill refuses would make that argument false. Both are ordinary renames; neither re-runs the Open → Known Error pre-flight (root cause and workaround were established the first time round) and neither fires the "Problem 063: manage-problem does not trigger /wr-itil:report-upstream when root cause is external" problem detection at 2d.
|
|
119
|
+
|
|
116
120
|
**2c. Run pre-flight checks** for the destination (same gating as the singular):
|
|
117
121
|
|
|
118
122
|
- Open → Known Error (`known-error`): root cause documented; ≥ 1 investigation task ticked; reproduction test or reference; workaround documented; effort bucket re-rated if scope shifted (the "Problem 047: WSJF effort buckets are coarse and not re-rated at lifecycle transitions" problem); status multiplier re-rated from Open 1.0 to Known Error 2.0 and WSJF recomputed with the post-transition status and current Effort (the "WSJF uses the pre-transition status multiplier" problem).
|
|
119
123
|
- Known Error → Verification Pending (`verifying`): fix implemented; release marker available (version, commit SHA, or date) for the `## Fix Released` section.
|
|
120
|
-
- Verification Pending → Closed (`close`): user
|
|
124
|
+
- Verification Pending → Closed (`close`): cited observed evidence or explicit user confirmation authorizes closure. Evidence-backed closure is mechanical and does not require another question. Record the citation and recovery path (`/wr-itil:transition-problem <NNN> known-error`) in each ticket's Status line. A provenance-proven GitHub issue on this project's tracker receives the gated comment and closes; unresolved or non-issue inbound provenance performs no issue mutation. A foreign issue receives the comment but stays open on local evidence alone; that upstream party's confirmation may authorize closure. Pull requests remain comment-only.
|
|
125
|
+
|
|
126
|
+
**Never close on inference** — absence of evidence is not evidence. A pair whose ticket carries no citation records as `pre-flight-failed` with reason `no-evidence` and stays Verification Pending; age, plausibility, and "the fix is on disk" are not observations. **Do-not-close marker check** — run `<itil-plugin-root>/bin/wr-itil-is-close-blocked <NNN> docs/problems` per pair before closing. Exit 0 → record the pair as `pre-flight-failed` with reason `close-blocked` plus the matched marker line, and continue to the next pair; do NOT close it whatever the evidence says. Exit 2 (unresolvable ref) is a pre-flight failure, not permission.
|
|
121
127
|
|
|
122
128
|
If any pre-flight fails, record the pair as `pre-flight-failed` with the failed-check list and continue to the next pair.
|
|
123
129
|
|
|
@@ -162,10 +168,18 @@ git add docs/problems/verifying/<NNN>-<title>.md
|
|
|
162
168
|
```bash
|
|
163
169
|
# Verification Pending → Closed
|
|
164
170
|
git mv docs/problems/verifying/<NNN>-<title>.md docs/problems/closed/<NNN>-<title>.md
|
|
165
|
-
# Edit Status field
|
|
171
|
+
# Edit Status field per the shape below
|
|
166
172
|
git add docs/problems/closed/<NNN>-<title>.md
|
|
167
173
|
```
|
|
168
174
|
|
|
175
|
+
**Write the close's authority basis into the Status field.** The Status line is the only place the basis survives — the `Likely verified?` cell lives in the README's Verification Queue table, and that row is deleted by this very transition, so a downstream reader (Step 7b's upstream leg) would find nothing there. Shape, matching what the 2026-07-15 closes already wrote (`docs/problems/closed/186-*.md:3`):
|
|
176
|
+
|
|
177
|
+
- Evidence-authorised: `**Status**: Closed (closed-on-evidence <YYYY-MM-DD> — <citation>. Recovery: rerun /wr-itil:transition-problem <NNN> known-error to reopen)`
|
|
178
|
+
- User-confirmed: `**Status**: Closed (user-confirmed <YYYY-MM-DD>)`
|
|
179
|
+
|
|
180
|
+
`closed-on-evidence` is what the outbound leg reads to keep a foreign issue open on our evidence alone. The inbound leg uses committed issue-channel provenance instead: ambiguity fails closed before any issue operation.
|
|
181
|
+
|
|
182
|
+
|
|
169
183
|
If `git mv` or `git add` fails for a pair (e.g. the file has been moved by a parallel process), record the pair as `git-failed` with the error and continue to the next pair. Do NOT attempt to roll back prior pairs' staged renames — those are now part of the in-progress batch.
|
|
170
184
|
|
|
171
185
|
Record each pair's outcome (succeeded / failed-with-reason) for the summary in Step 5.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: update-upstream
|
|
3
3
|
description: Post a lifecycle-update comment to an upstream issue when a local problem ticket transitions. Drafts a transition-specific update (root-cause confirmed / fix released / closed), composes the prose through the external-comms risk gate + voice-tone gate, auto-posts within appetite, queues above-appetite. Reciprocal sibling to /wr-itil:report-upstream — initial-filing vs lifecycle-update split per the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule amendment (the "Problem 080: No bidirectional update of upstream-reported problems — local lifecycle transitions never propagate back to the reporter" problem).
|
|
4
4
|
allowed-tools: Read, Write, Edit, Bash, Glob, Grep, request_user_input, Skill, Agent
|
|
5
5
|
---
|
|
@@ -178,7 +178,7 @@ Update from <downstream-repo-url>/<local-ticket-relative-path>:
|
|
|
178
178
|
|
|
179
179
|
<one-sentence summary from the local ticket's ## Fix Released section>
|
|
180
180
|
|
|
181
|
-
Please upgrade and verify when convenient. We'll close this issue after your confirmation
|
|
181
|
+
Please upgrade and verify when convenient. We'll close this issue after your confirmation. If you'd rather we closed it without one, say so here. Local tracking: P<NNN>.
|
|
182
182
|
```
|
|
183
183
|
|
|
184
184
|
#### Verification Pending → Closed template
|
|
@@ -186,12 +186,38 @@ Please upgrade and verify when convenient. We'll close this issue after your con
|
|
|
186
186
|
```markdown
|
|
187
187
|
Update from <downstream-repo-url>/<local-ticket-relative-path>:
|
|
188
188
|
|
|
189
|
-
**Status**: Closed locally after
|
|
189
|
+
**Status**: Closed locally after verification.
|
|
190
190
|
|
|
191
|
-
|
|
191
|
+
Thanks for the report — your filing is what got this on the queue. Local tracking: P<NNN>.
|
|
192
192
|
```
|
|
193
193
|
|
|
194
|
-
After posting the Verifying → Closed comment, the
|
|
194
|
+
After posting the Verifying → Closed comment, leave the foreign issue open by default. Closing it requires the target-bound upstream-party confirmation below.
|
|
195
|
+
|
|
196
|
+
#### Foreign issues close only on target-bound upstream-party confirmation
|
|
197
|
+
|
|
198
|
+
Local evidence or local user confirmation can close our ticket, but neither decides another maintainer's tracker state. Post the lifecycle comment and **stop there** unless the local ticket's `## Reported Upstream` section carries this durable, target-bound signal:
|
|
199
|
+
|
|
200
|
+
```markdown
|
|
201
|
+
- **Closure authority**: upstream-confirmed <exact GitHub issue-comment URL>
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Before running `gh issue close`, validate that URL read-only: it MUST be an `#issuecomment-<id>` URL on the exact `UPSTREAM_OWNER_REPO/issues/UPSTREAM_ISSUE_NUMBER` target; `gh api repos/<owner>/<repo>/issues/comments/<id>` MUST return that exact issue URL; `author_association` MUST be `OWNER`, `MEMBER`, or `COLLABORATOR`; and the comment body MUST unambiguously authorize closing this issue. A missing marker, URL mismatch, API failure, non-maintainer association, or ambiguous body leaves the issue open. Never infer this authority from a local `user-confirmed` Status marker.
|
|
205
|
+
|
|
206
|
+
Read the Status line, not the README's `Likely verified?` cell: the close deletes that row from the Verification Queue before this step runs, so the cell is gone by the time anything could read it.
|
|
207
|
+
|
|
208
|
+
Confirmation from the upstream party may authorize closing their issue; their word, not our evidence, supplies the missing authority. Do not promise a quiet-period close that no mechanism delivers.
|
|
209
|
+
|
|
210
|
+
When target-bound confirmation is absent, use the evidence-authorised local-close-only variant below and record `posted-comment-local-close-only` in the back-write disclosure path. When validation succeeds, use the ordinary Closed template and record `posted-comment-and-closed`.
|
|
211
|
+
|
|
212
|
+
```markdown
|
|
213
|
+
Update from <downstream-repo-url>/<local-ticket-relative-path>:
|
|
214
|
+
|
|
215
|
+
**Status**: Closed locally. We verified the fix on our side — <one-line evidence citation>.
|
|
216
|
+
|
|
217
|
+
Leaving this issue open for you. Close it whenever you have confirmed the fix works in your setup. Local tracking: P<NNN>.
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
On this leg, without validated target-bound confirmation from them: comment, do not close. Pull requests are always comment-only, even if they carry a confirmation marker.
|
|
195
221
|
|
|
196
222
|
#### Template-filling rules
|
|
197
223
|
|
|
@@ -267,7 +293,7 @@ gh issue comment "${UPSTREAM_ISSUE_NUMBER}" \
|
|
|
267
293
|
|
|
268
294
|
Capture the returned comment URL (gh prints `https://github.com/<owner>/<repo>/issues/<n>#issuecomment-<id>`).
|
|
269
295
|
|
|
270
|
-
On the **Verifying → Closed** transition, after posting the comment,
|
|
296
|
+
On the **Verifying → Closed** transition, after posting the comment, close the upstream issue only when the target-bound `Closure authority` validation above passed:
|
|
271
297
|
|
|
272
298
|
```bash
|
|
273
299
|
gh issue close "${UPSTREAM_ISSUE_NUMBER}" \
|
|
@@ -298,7 +324,7 @@ Append a log entry to the local ticket's `## Upstream Lifecycle Updates` section
|
|
|
298
324
|
- **<YYYY-MM-DD>** — Open → Known Error
|
|
299
325
|
- **Target URL**: <upstream-issue-url>
|
|
300
326
|
- **Comment URL**: <posted-comment-url> (or "queued — see ## Queued Upstream Update" when above-appetite)
|
|
301
|
-
- **Disclosure path**: posted-comment | posted-pr-comment (pull-request target
|
|
327
|
+
- **Disclosure path**: posted-comment | posted-pr-comment (pull-request target — never closed) | posted-comment-and-closed (confirmed Verifying → Closed, issue targets only) | posted-comment-local-close-only (outbound evidence-authorised close) | queued-above-appetite | closed-already-upstream | skipped-out-of-band
|
|
302
328
|
- **Gate verdict**: external-comms <band/score> + voice-tone <pass|fail>
|
|
303
329
|
|
|
304
330
|
- **<YYYY-MM-DD>** — Known Error → Verification Pending
|
|
@@ -317,7 +343,51 @@ This leg runs **in addition to** Steps 2–6 (the outbound `## Reported Upstream
|
|
|
317
343
|
|
|
318
344
|
#### I1. Parse the inbound origin
|
|
319
345
|
|
|
320
|
-
From the `**Origin**: inbound-reported (#NN)` field, extract the
|
|
346
|
+
From the `**Origin**: inbound-reported (#NN)` field, extract the candidate number `NN`. That untyped number is not proof of an issue: issues, discussions, and advisories have distinct mutation paths, and numeric identifiers can collide.
|
|
347
|
+
|
|
348
|
+
Before any inbound `gh issue view`, `gh issue comment`, or `gh issue close`, prove the channel from the committed discovery cache:
|
|
349
|
+
|
|
350
|
+
```bash
|
|
351
|
+
OWN_OWNER_REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner)
|
|
352
|
+
LOCAL_TICKET_ID="P${LOCAL_ID}"
|
|
353
|
+
ISSUE_CHANNEL="github-issues:${OWN_OWNER_REPO}"
|
|
354
|
+
CACHE_REF="HEAD:docs/problems/.upstream-cache.json"
|
|
355
|
+
CACHE_JSON=$(git show "${CACHE_REF}" 2>/dev/null) || CACHE_JSON='{}'
|
|
356
|
+
|
|
357
|
+
ISSUE_NUMBER_MATCHES=$(printf '%s' "${CACHE_JSON}" | jq \
|
|
358
|
+
--arg channel "${ISSUE_CHANNEL}" \
|
|
359
|
+
--argjson number "${NN}" \
|
|
360
|
+
'[.channels[$channel].reports[]? | select(.number == $number)] | length' \
|
|
361
|
+
2>/dev/null) || ISSUE_NUMBER_MATCHES=0
|
|
362
|
+
|
|
363
|
+
ISSUE_TICKET_MATCHES=$(printf '%s' "${CACHE_JSON}" | jq \
|
|
364
|
+
--arg channel "${ISSUE_CHANNEL}" \
|
|
365
|
+
--argjson number "${NN}" \
|
|
366
|
+
--arg ticket "${LOCAL_TICKET_ID}" \
|
|
367
|
+
'[.channels[$channel].reports[]? |
|
|
368
|
+
select(.number == $number and .matched_local_ticket == $ticket)] | length' \
|
|
369
|
+
2>/dev/null) || ISSUE_TICKET_MATCHES=0
|
|
370
|
+
|
|
371
|
+
NON_ISSUE_MATCHES=$(printf '%s' "${CACHE_JSON}" | jq \
|
|
372
|
+
--arg issue_channel "${ISSUE_CHANNEL}" \
|
|
373
|
+
--arg repo_suffix ":${OWN_OWNER_REPO}" \
|
|
374
|
+
--argjson number "${NN}" \
|
|
375
|
+
'[.channels | to_entries[] |
|
|
376
|
+
select(.key != $issue_channel and (.key | endswith($repo_suffix))) |
|
|
377
|
+
.value.reports[]? | select(.number == $number)] | length' \
|
|
378
|
+
2>/dev/null) || NON_ISSUE_MATCHES=0
|
|
379
|
+
|
|
380
|
+
if [ "${ISSUE_NUMBER_MATCHES}" -ne 1 ] || \
|
|
381
|
+
[ "${ISSUE_TICKET_MATCHES}" -ne 1 ] || \
|
|
382
|
+
[ "${NON_ISSUE_MATCHES}" -ne 0 ]; then
|
|
383
|
+
echo "inbound-channel-unresolved: ${LOCAL_TICKET_ID} #${NN}"
|
|
384
|
+
INBOUND_CHANNEL_RESOLVED=0
|
|
385
|
+
else
|
|
386
|
+
INBOUND_CHANNEL_RESOLVED=1
|
|
387
|
+
fi
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
When `INBOUND_CHANNEL_RESOLVED=0`, skip I2–I6 and perform no inbound issue operation; an independent outbound leg may still continue. Missing committed cache data, zero or multiple issue matches, a repository mismatch, a wrong `matched_local_ticket`, or a discussion/advisory collision all take this path. If the Origin field is `internal` or absent, this leg does not run.
|
|
321
391
|
|
|
322
392
|
#### I2. Determine the transition (same suffix logic as Step 3)
|
|
323
393
|
|
|
@@ -441,12 +511,14 @@ Above-appetite handling is identical to Step 5c (silent risk-reduce + re-score;
|
|
|
441
511
|
gh issue comment "${NN}" --repo "${OWN_OWNER_REPO}" --body "${INBOUND_BODY}"
|
|
442
512
|
```
|
|
443
513
|
|
|
444
|
-
On the **Verification Pending → Closed** transition, after the comment,
|
|
514
|
+
On the **Verification Pending → Closed** transition, after the comment, close the provenance-proven issue on this project's tracker whether the local close was confirmed or evidence-authorised:
|
|
445
515
|
|
|
446
516
|
```bash
|
|
447
517
|
gh issue close "${NN}" --repo "${OWN_OWNER_REPO}" --comment "" --reason completed
|
|
448
518
|
```
|
|
449
519
|
|
|
520
|
+
This outbound guard does not apply to a provenance-proven GitHub issue on this project's own repository. After the gated comment, close it whether the local close was evidence-authorised or confirmed; the reporter can reopen it. Unknown or non-issue inbound channels already stopped at the provenance guard.
|
|
521
|
+
|
|
450
522
|
If the issue is already closed (someone closed it manually), `gh issue close` returns a benign error — record `closed-already` in the disclosure path and continue.
|
|
451
523
|
|
|
452
524
|
#### I6. Back-write to the lifecycle log
|
|
@@ -457,7 +529,7 @@ Append to the same `## Upstream Lifecycle Updates` log (Step 6 shape), tagged fo
|
|
|
457
529
|
- **<YYYY-MM-DD>** — Known Error → Verification Pending (inbound)
|
|
458
530
|
- **Target**: inbound #<NN> (own repo <OWN_OWNER_REPO>)
|
|
459
531
|
- **Comment URL**: <posted-comment-url> (or "skipped — already-posted-inbound" when the idempotency guard matched, or "queued — see ## Queued Upstream Update" when above-appetite)
|
|
460
|
-
- **Disclosure path**: posted-inbound-comment | posted-inbound-comment-and-closed (
|
|
532
|
+
- **Disclosure path**: posted-inbound-comment | posted-inbound-comment-and-closed (proven owned issue, confirmed or evidence-authorised close) | already-posted-inbound | queued-above-appetite | closed-already | inbound-channel-unresolved
|
|
461
533
|
- **Gate verdict**: external-comms <band/score> + voice-tone <pass|fail>
|
|
462
534
|
```
|
|
463
535
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: work-problem
|
|
3
3
|
description: Pick the highest-WSJF open or known-error problem ticket and work it — investigate, implement, commit, and release per the standard manage-problem workflow. Selection is framework-mediated (WSJF + documented tie-break ladder per the "— Decision-Delegation Contract: when agents act on the framework vs ask the user" architecture rule); singular variant; distinct from /wr-itil:work-problems (plural AFK orchestrator). Use this when the user asks to "work the next problem", "work the top of the queue", or "grind through one ticket".
|
|
4
4
|
allowed-tools: Read, Write, Edit, Bash, Glob, Grep, request_user_input, Skill, Agent
|
|
5
5
|
---
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
3
|
-
description: Drain the ITIL problem backlog in WSJF order using
|
|
2
|
+
name: work-problems
|
|
3
|
+
description: Drain the ITIL problem backlog in WSJF order using isolated Codex CLI iterations, governed commits, pushes, and releases.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
<!-- Generated from the runtime-neutral skill source. Do not edit. -->
|
|
@@ -16,32 +16,85 @@ description: Drain the ITIL problem backlog in WSJF order using native Codex sub
|
|
|
16
16
|
|
|
17
17
|
# Work Problems in Codex
|
|
18
18
|
|
|
19
|
-
Continuously work the highest-priority actionable problem until the backlog is drained, the user stops, or a real governance dependency requires human direction.
|
|
19
|
+
Continuously work the highest-priority actionable problem until the backlog is drained, the user stops, or a real governance dependency requires human direction. Run each selected problem in one fresh `codex exec` process and consume its structured result before continuing.
|
|
20
20
|
|
|
21
21
|
## Preflight
|
|
22
22
|
|
|
23
23
|
1. If `docs/problems/` is absent, direct the user to `/wr-itil:scaffold-intake` and stop.
|
|
24
24
|
2. Run the installed ITIL maintenance commands required by the repository, including layout migration, README reconciliation, catch-up scanning, stale upstream-cache checks, and unresolved-response checks. Resolve them from the plugin's bundled `bin/`; do not use source-repository paths.
|
|
25
|
-
3. Preserve unrelated working-tree changes. Revert only
|
|
26
|
-
4. If the task has a persistent Codex goal, keep it active until this drain reaches a genuine terminal state. A slow
|
|
25
|
+
3. Resolve the exact checkout with `git rev-parse --show-toplevel`. Preserve unrelated working-tree changes and record the pre-iteration status. Revert only paths proven to have been created by a failed iteration.
|
|
26
|
+
4. If the task has a persistent Codex goal, keep it active until this drain reaches a genuine terminal state. A slow process is not a blocker.
|
|
27
27
|
|
|
28
28
|
## Loop
|
|
29
29
|
|
|
30
30
|
1. Read the problem index and current ticket files. Select the highest WSJF problem in the highest non-empty actionable tier. Use the documented tie-break rules.
|
|
31
31
|
2. Skip tickets whose required JTBD, decision, risk, or story-map oversight is unconfirmed. Record one structured outstanding question for each genuinely user-answerable dependency; do not ask mid-loop.
|
|
32
32
|
3. Run the relevance and stop-condition checks. Before declaring `ALL_DONE`, run the repository's unconditional pre-completion gates and rescan the backlog.
|
|
33
|
-
4.
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
- run focused tests and the required architecture/risk checks;
|
|
37
|
-
- create the required changeset for shippable plugin behavior;
|
|
38
|
-
- commit the completed iteration, but do not push or release;
|
|
39
|
-
- return one `ITERATION_SUMMARY` JSON object containing ticket, action, commits, tests, risks, outstanding questions, and remaining work.
|
|
40
|
-
5. Wait for that same subagent. Do not cancel, replace, retry, or fan out merely because Cruise or normal model execution makes the call slow. When it completes, consume its summary and close it.
|
|
41
|
-
6. Validate the summary with `<itil-plugin-root>/bin/wr-itil-verify-iter-summary`. If the subagent failed after changing the checkout, inspect and safely complete or revert only its own partial work before continuing.
|
|
33
|
+
4. Dispatch exactly the selected ticket through the isolated Codex command below. Do not select or work a second ticket inside that process.
|
|
34
|
+
5. Wait for that same process. Do not cancel, replace, retry, or fan out merely because normal model execution is slow.
|
|
35
|
+
6. Classify the exit and JSONL metadata before reading the final-output file. On success, validate the summary with `<itil-plugin-root>/bin/wr-itil-verify-iter-summary` and consume it. On failure, apply the recovery contract below and halt.
|
|
42
36
|
7. Run inter-iteration verification. If the iteration produced committed shippable work, complete the repository's governed push and release cadence when risk is within appetite. Above-appetite risk is a remediation instruction: reduce scope or split the change; never ask the user to approve risk above appetite.
|
|
43
37
|
8. Report only material progress, then rescan and repeat.
|
|
44
38
|
|
|
39
|
+
## Isolated Codex iteration
|
|
40
|
+
|
|
41
|
+
Build a self-contained prompt containing the selected ticket ID and title, the exact checkout, applicable confirmed decisions, and these requirements:
|
|
42
|
+
|
|
43
|
+
- invoke `/wr-itil:manage-problem <number>` and work only that problem;
|
|
44
|
+
- preserve unrelated work and use path-scoped staging;
|
|
45
|
+
- load and obey the installed governance skills, agents, and hooks;
|
|
46
|
+
- run focused tests and required architecture, JTBD, voice, accessibility, and risk checks when their gates apply;
|
|
47
|
+
- add a changeset for shippable package behavior;
|
|
48
|
+
- commit completed iteration work, but do not push or release;
|
|
49
|
+
- invoke `/wr-retrospective:run-retro` before the final response, commit any retro-owned briefing refresh through its governed path, and continue to the summary even if retro reports a non-blocking failure;
|
|
50
|
+
- end with one `ITERATION_SUMMARY` containing ticket, action, outcome, commit state, tests, risks, outstanding questions, remaining work, and notes.
|
|
51
|
+
|
|
52
|
+
Run the nested process in the outer session's installed Codex environment. Do not replace `CODEX_HOME` or ignore user configuration: the inherited plugin registry and hooks are the governance surface. Export the three AFK guards so pending interactive questions, oversight nudges, and machine-authored correction text do not leak into the isolated turn.
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
ITERATION_CHECKOUT="$(git rev-parse --show-toplevel)"
|
|
56
|
+
ITERATION_JSONL="$(mktemp)"
|
|
57
|
+
ITERATION_FINAL="$(mktemp)"
|
|
58
|
+
|
|
59
|
+
export WR_SUPPRESS_PENDING_QUESTIONS=1
|
|
60
|
+
export WR_SUPPRESS_OVERSIGHT_NUDGE=1
|
|
61
|
+
export WR_SUPPRESS_CORRECTION_DETECT=1
|
|
62
|
+
|
|
63
|
+
codex exec \
|
|
64
|
+
--ephemeral \
|
|
65
|
+
--dangerously-bypass-approvals-and-sandbox \
|
|
66
|
+
--dangerously-bypass-hook-trust \
|
|
67
|
+
--cd "$ITERATION_CHECKOUT" \
|
|
68
|
+
--json \
|
|
69
|
+
--output-last-message "$ITERATION_FINAL" \
|
|
70
|
+
"$ITERATION_PROMPT" \
|
|
71
|
+
>"$ITERATION_JSONL" 2>&1
|
|
72
|
+
ITERATION_EXIT=$?
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The two output channels are load-bearing and must stay separate:
|
|
76
|
+
|
|
77
|
+
- `ITERATION_JSONL` carries progress and error metadata only. Parse it as JSONL; never scrape the final agent message from this stream.
|
|
78
|
+
- `ITERATION_FINAL` carries the final agent message. Read `ITERATION_SUMMARY` only from this file after the exit and metadata checks pass.
|
|
79
|
+
|
|
80
|
+
Always remove both temporary files after their contents have been classified and consumed.
|
|
81
|
+
|
|
82
|
+
## Error classification and recovery
|
|
83
|
+
|
|
84
|
+
Classify in this order:
|
|
85
|
+
|
|
86
|
+
1. A non-zero process exit halts the loop. Use the exit code plus JSONL error messages to report `quota exhausted`, `rate limited`, `authentication failed`, `service overloaded`, or `execution failed`; do not call a quota failure merely unavailable.
|
|
87
|
+
2. Exit zero with a JSONL `error` or `turn.failed` event also halts before summary parsing. Apply the same message classification. A final-output file does not override an error event.
|
|
88
|
+
3. Exit zero without an error event permits final-output parsing. The file must contain exactly one valid `ITERATION_SUMMARY` for the selected ticket; otherwise halt as `invalid iteration summary`.
|
|
89
|
+
|
|
90
|
+
After every exit, record the checkout delta against the pre-iteration status for diagnosis, without mutation. Recovery may begin only after exit zero, error-free JSONL, and exactly one valid `ITERATION_SUMMARY` for the selected ticket. Missing, multiple, or wrong-ticket summaries halt without recovery. Then compare the checkout with the recorded pre-iteration status:
|
|
91
|
+
|
|
92
|
+
- A clean checkout proceeds normally.
|
|
93
|
+
- A coherent commit named by the valid summary proceeds to inter-iteration verification.
|
|
94
|
+
- Coherent staged work attributable only to the selected ticket may be recovered only after its focused tests and governance gates pass again in the outer session.
|
|
95
|
+
- Ambiguous, unstaged, or unrelated changes hard-block recovery. Report their paths and halt without mutation.
|
|
96
|
+
- When a failed iteration created known disposable paths, restore only the explicit verified path list with path-scoped Git commands. Never use a broad reset, clean, checkout, restore, or stash operation.
|
|
97
|
+
|
|
45
98
|
## Fix Proposal Rule
|
|
46
99
|
|
|
47
100
|
A fix proposal is a release row on an existing story map, never a new file under `docs/rfcs/`. The row has an identity from `<itil-plugin-root>/bin/wr-itil-next-rfc-id`, at least one story card, and a story whose `problems:` list names the driving problem. Creating a new map, activity column, job, or uncovered architectural choice requires a queued human decision rather than a silent edit.
|
|
@@ -50,9 +103,9 @@ A fix proposal is a release row on an existing story map, never a new file under
|
|
|
50
103
|
|
|
51
104
|
- Batch outstanding questions at loop end with `request_user_input`, no more than four per call. Brief substance before IDs.
|
|
52
105
|
- Continue past skipped tickets when another actionable ticket exists.
|
|
53
|
-
- Stop only for an explicit user stop, a fully drained backlog, a governance dependency that blocks every remaining ticket, or an unrecoverable
|
|
54
|
-
- Never describe a delayed
|
|
106
|
+
- Stop only for an explicit user stop, a fully drained backlog, a governance dependency that blocks every remaining ticket, confirmed quota exhaustion, or an unrecoverable process or repository failure.
|
|
107
|
+
- Never describe a delayed process as unavailable, hung, or blocked without an actual error or terminal failure.
|
|
55
108
|
|
|
56
109
|
## Final Report
|
|
57
110
|
|
|
58
|
-
Report completed and skipped tickets, commits, tests, push
|
|
111
|
+
Report completed and skipped tickets, commits, tests, push and release outcomes, remaining backlog, and outstanding design questions. Preserve the distinction between committed, pushed, released, and production-verified states.
|