| name | wr-itil:transition-problem |
| 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, P057 staging-trap handling, P063 external-root-cause detection, P062 README refresh, ADR-014 commit) per ADR-010 amended "Split-skill execution ownership". Use when the user asks to "transition", "close", "mark known-error", or "release" a specific ticket. |
| allowed-tools | Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion, Skill |
Transition Problem — Lifecycle Advance
Advance a specific problem ticket along the ITIL lifecycle: Open → Known Error → Verification Pending → Closed. The skill is the authoritative executor for the user-initiated transition path — it identifies the ticket and the destination status, then executes the transition inline: pre-flight checks, external-root-cause detection (P063), git mv + Status edit with staging re-stage (P057), ## Fix Released section write for the verifying destination, README.md refresh (P062), and ADR-014 commit.
This skill is phase 4 of the P071 phased-landing split of /wr-itil:manage-problem <NNN> <status> per ADR-010's amended Skill Granularity rule (one skill per distinct user intent). Per ADR-010's "Split-skill execution ownership" rule (P093), the skill does not re-invoke /wr-itil:manage-problem to run Step 7 (no round-trip); the deprecation-window forwarder on manage-problem routes one-way to this skill and returns its output verbatim. The in-skill Step 7 block on manage-problem remains in place for in-skill callers (Step 9b auto-transition, Parked path, Step 9d closure inside review) — "copy, not move" per ADR-010 amended.
The deprecated /wr-itil:manage-problem <NNN> known-error subcommand route remains as a one-way forwarder during the deprecation window but is scheduled for removal in @windyroad/itil's next major version.
Arguments
<NNN> — the ticket ID (data parameter, e.g. 042). Required.
<status> — the destination status. One of:
known-error — Open → Known Error (root cause identified AND workaround documented; fix not yet proposed — per ADR-022 corrected semantics, fix proposal produces the RFC per ADR-072).
verifying — Known Error → Verification Pending (fix released, awaiting user verification per ADR-022).
close — Verification Pending → Closed (user has confirmed the fix works in production).
The <NNN> and <status> tokens are data parameters, not word-subcommands. Per the P071 split rule (ADR-010 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>.
Scope
In scope:
- Validate that the ticket file exists and the destination status is reachable from the current status (e.g. an
.open.md file cannot transition directly to Verification Pending — it must go through Known Error first).
- Execute the transition inline: pre-flight checks, P063 external-root-cause detection (for the Open → Known Error destination),
git mv to the new suffix, Status field edit, ## Fix Released section write (for the Known Error → Verification Pending destination), P057 staging re-stage, P062 README.md refresh, ADR-014 commit.
- Report the outcome (new filename, new Status, commit SHA).
Out of scope:
- Backlog re-ranking — that's
/wr-itil:review-problems.
- Ticket creation or bare-update flows — that's
/wr-itil:manage-problem (no-args form for creation, <NNN> bare for update).
- Parking a ticket — that's a distinct lifecycle move handled by
/wr-itil:manage-problem directly (the .parked.md suffix has its own pre-flight path including P063 external-root-cause detection for upstream-blocked reasons).
- Auto-transitions fired inside
/wr-itil:review-problems Step 9b (Open → Known Error when root cause + workaround are documented) — those use manage-problem's in-skill Step 7 block per ADR-010 amended "Split-skill execution ownership" ("copy, not move").
Steps
1. Parse the arguments
From $ARGUMENTS, extract the ticket ID (<NNN>, three digits) and the destination status (one of known-error, verifying, close). If either is missing or malformed, emit a usage message and stop:
Usage: /wr-itil:transition-problem <NNN> <status>
<NNN> — three-digit ticket ID (e.g. 042)
<status> — one of: known-error, verifying, close
2. Discover the ticket file
Locate the ticket file by ID — dual-tolerant lookup spans both the flat layout (docs/problems/<NNN>-<title>.<state>.md) AND the per-state subdir layout (docs/problems/<state>/<NNN>-<title>.md) per RFC-002 migration window:
ls docs/problems/<NNN>-*.md docs/problems/*/<NNN>-*.md 2>/dev/null
If no file is found, emit: No ticket found for ID <NNN> and stop.
If multiple files are found (should not happen — suffix-exclusive lifecycle), emit a warning and list the matches; stop and let the user resolve.
3. Validate the transition path
Check the current filename suffix and verify the destination status is reachable in one step:
| Current suffix | Destination argument | Valid? |
|---|
.open.md | known-error | yes |
.known-error.md | verifying | yes |
.verifying.md | close | yes |
| any other pairing | — | no — emit an error and stop |
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.
4. Run pre-flight checks
Destination-specific pre-flight checks gate the transition. If any check fails, report which ones and stop — do not auto-remediate.
Open → Known Error (<status> = known-error) requires:
Known Error → Verification Pending (<status> = verifying) requires:
Conditional-deferral check on K→V (P184) — copy-not-move sibling
This subsection is the copy-not-move sibling of /wr-itil:manage-problem SKILL.md Step 7's "Conditional-deferral check BEFORE the rename (P184)" block per ADR-010 amended "Split-skill execution ownership" rule (P093). Both surfaces must carry the check; drift between the two copies re-opens P184's silent-loss failure mode on whichever surface lacks the check.
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. P184's driver case (P170 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 and would have lost the Phase 2 work if the user hadn't asked an orthogonal question.
Detection (run in order):
- Grep the ticket body for phase-tracking section headers — regex
^### (Phase|Slice|Tier) [0-9]+ covers the canonical shapes.
- For each detected section, count the unticked
- [ ] checkboxes inside it (up to the next ^### boundary or EOF).
- Grep the body for conditional-deferral markers:
deferred (?:to|pending|until) (?:post-)?[A-Za-z0-9-]+(?:-graduation)?, Phase [0-9]+ (?:SHIP )?deferred, deferred-pending-[a-z-]+.
- For each conditional-deferral marker, resolve whether the gating condition has fired — check whether the named phase/ticket/RFC has reached
.closed.md / .verifying.md (for tickets) or closed lifecycle (for RFCs / stories per ADR-060).
Halt-and-route (when ANY conditional deferral has lifted with unticked work remaining):
Emit a structured report naming each deferred section + the lifted condition + the unticked task count, then halt the transition. Per ADR-044 category 2 (deviation-approval), this is NOT a per-transition lazy ask — it is a class-of-behaviour deviation surface that the user owns.
- Interactive: fire
AskUserQuestion with header: "Conditional deferral lifted" + three options: (1) re-open Phase N and work the deferred tasks now (recommended; revert to Known Error); (2) confirm Phase N is permanently out of scope (proceed with K→V; append <!-- P184: user-confirmed Phase N permanently OOS --> marker to suppress re-detection); (3) split Phase N into a new ticket (halt K→V; route to /wr-itil:capture-problem).
- AFK (per ADR-013 Rule 6 + P352 queue-and-continue): queue an
outstanding_questions entry naming the local ticket ID + the lifted-condition citation + the unticked task count + the three options. Do NOT auto-transition. Brief the substance BEFORE referencing IDs per feedback_brief_before_id.md.
Proceed silently (no halt) when no phase-tracking sections exist, every task in such sections is ticked, the deferral marker explicitly states "permanently out of scope" / "won't fix" / "rejected" without a conditional clause, OR the section carries the <!-- P184: user-confirmed Phase N permanently OOS --> marker from a prior surfacing.
Why halt-and-route not silent-default-with-marker: P184's failure mode is "work silently lost if user doesn't notice"; the halt-and-route shape catches the failure at the transition surface where the loss occurs. Driver: user direction in P184 Workaround section — "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."
This check fires BEFORE the P330 Release-vehicle seed step in Step 6 — halt-on-conditional-deferral is the outer gate, seed-and-rename is the inner mechanic.
Verification Pending → Closed (<status> = close) requires:
5. External-root-cause detection (P063 — Open → Known Error only)
Fires on the Open → Known Error transition only. Parking with the upstream-blocked reason reuses the same mechanism but is handled by /wr-itil:manage-problem's Step 7 (this skill does not park).
Strict detection tokens (any of the following within the Root Cause Analysis section counts as a hit):
- Literal label words:
upstream, third-party, external, vendor.
- Scoped npm package pattern:
@[\w-]+/[\w-]+ (e.g. @anthropic/claude-code, @windyroad/itil).
Bash heuristic:
if grep -iE '\b(upstream|third-party|external|vendor)\b|@[[:alnum:]_-]+/[[:alnum:]_-]+' "$problem_file"; then
external_root_cause_detected=1
fi
Detection is intentionally strict (explicit label or scoped-npm package only) to avoid prompt fatigue (P063 Direction decision). A passing reference to a bare package name (gh, npm) does NOT trigger the prompt.
Already-noted check — before firing the prompt, grep the ticket for the stable marker - **Upstream report pending** -- (canonical ASCII form per P210) 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 ADR-024 Confirmation criterion 3a). If any of those are already present, skip the prompt — the detection has already fired on a prior run.
If the detection fires and nothing has been noted yet (per ADR-044 framework-resolution boundary): the agent applies the AFK fallback default WITHOUT firing AskUserQuestion. Per ADR-044, this decision IS framework-resolved — the safe action is "defer and note marker", and the user can correct via authentic-correction (ADR-044 category 6) if a manual /wr-itil:report-upstream invocation is wanted instead. Per-transition AskUserQuestion for upstream-detection is sub-contracting framework-resolved decisions back to the user (lazy deferral per Step 2d Ask Hygiene Pass classification).
Default behaviour (silent agent action, per ADR-044): append the 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
ASCII -- per P210 — ASCII-only in machine-parseable identifiers; em-dash permitted in pure narrative prose. The legacy em-dash variant is matched by the already-noted check for backward compatibility.
The marker wording is fixed so subsequent runs (and the work-problems upstream-blocked skip path) can detect "already noted" without re-firing. The transition proceeds normally after the marker is appended.
Recovery / override paths (user-initiated, not asked-per-transition):
- If the detection misfired (false positive — not actually upstream), user appends
- **Upstream report pending** -- false positive; detection misfire directly to the ticket's ## Related section (ASCII -- per P210; legacy em-dash variant remains matched for backward compatibility). The next detection-pass observes the marker and skips firing again.
- If the user wants to invoke
/wr-itil:report-upstream immediately rather than deferring, they invoke it directly (/wr-itil:report-upstream <NNN> <upstream-repo-url>). The skill writes the ## Reported Upstream appendage per ADR-024.
AFK and interactive modes use identical behaviour — the silent-default-with-recovery-path shape is the framework-resolution boundary application; there's no AskUserQuestion-vs-fallback differentiation.
6. Rename the file, edit content, and re-stage (P057 staging trap)
Per destination, run the rename + edit + explicit re-stage sequence. The explicit re-stage after Edit is mandatory — without it the content edit leaks into the next commit and the audit trail breaks.
Staging trap (P057). 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.
Open → Known Error:
git mv docs/problems/open/<NNN>-<title>.md docs/problems/known-error/<NNN>-<title>.md
git add docs/problems/known-error/<NNN>-<title>.md
Known Error → Verification Pending (per ADR-022, on release):
Seed Release vehicle reference BEFORE the rename (P330). 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 makes the wr-itil-derive-release-vehicle <NNN> helper invocation below exit 0 deterministically on first call (the helper greps the ticket body for .changeset/<name>.md and exits 2 when absent — Option B-codified per P330 closes that exit-2 routing on standalone K→V iters). The exit-2 fallback in the routing table below remains as the legacy-ticket recovery path for tickets shipped before P330's codification. Mirrors the /wr-itil:manage-problem Step 7 seed step (copy-not-move per ADR-010 amended / P093).
Two P057 staging-trap windows on K→V (seed + rename). The seed Edit on .known-error.md is the FIRST P057 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.
git mv docs/problems/known-error/<NNN>-<title>.md docs/problems/verifying/<NNN>-<title>.md
git add docs/problems/verifying/<NNN>-<title>.md
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 user-side verification — no file-body scan needed.
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.
Release-vehicle citation (P267): derive the release marker deterministically — never hand-type it from git log browse output. Hand-typed citations are fragile to wrong-release-cited errors when a session pre-applies transitions for multiple sibling tickets before working any of them (origin: 2026-05-18 session 7 iter 1 — P250's K→V cited P247's release refs). Invoke the helper:
wr-itil-derive-release-vehicle <NNN>
wr-itil-derive-release-vehicle is the ADR-049 $PATH shim (adopter-safe — resolves the canonical derive-release-vehicle.sh relative to the script, NOT cwd; P317/RFC-009) that reads the ticket body for the .changeset/<name>.md reference, walks git log --diff-filter=D for the deletion commit (chore: version packages), resolves the merge PR via the first-parent ancestry-path merge commit (or gh pr list fallback when available), and emits a structured citation block on stdout:
RELEASE_VEHICLE:
changeset: .changeset/<name>.md
version-packages-commit: <SHA>
pr: #<N>
merge-commit: <SHA>
release-date: <YYYY-MM-DD>
Use the structured values verbatim when authoring the ## Fix Released section's release marker (e.g. Released in @windyroad/itil@<version> (merge commit <merge-commit>, PR #<N>, released <release-date>)). The helper is mechanical per ADR-044 framework-resolution — no AskUserQuestion per transition.
Helper exit-code routing:
- Exit 0 (full citation emitted): use the values in the
## Fix Released section.
- Exit 1 (ticket file not found): the upstream ticket-discovery step (Step 2) should have caught this; if it fires here, halt and report.
- Exit 2 (no
.changeset/<name>.md reference in ticket body): add the changeset reference to the ticket's Fix Strategy section, OR cite the release marker manually with explicit <!-- no-changeset-reference --> comment so a future review can audit the gap.
- Exit 3 (changeset still in working tree — unreleased): the fix has not yet been released to npm. Halt the transition —
.known-error.md → .verifying.md requires a shipped release per ADR-022. The orchestrator's Step 6.5 drain should fire first.
- Exit 4 (deletion commit found but no merge PR resolvable): direct-to-main commit (no PR), or
gh pr list unavailable + first-parent walk did not match. Cite the deletion commit SHA manually in the ## Fix Released section with an explicit <!-- no-pr --> comment.
Verification Pending → Closed:
git mv docs/problems/verifying/<NNN>-<title>.md docs/problems/closed/<NNN>-<title>.md
git add docs/problems/closed/<NNN>-<title>.md
7. Refresh docs/problems/README.md (P062)
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.
The refresh uses the same rendering rules as /wr-itil:review-problems Step 9e (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) 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.
Verification Queue sort direction (P150): Verification Queue rows are sorted by Released date ASC (oldest at row 1; same-day releases tiebreak by ID ASC) per ADR-022 + P048 user-task semantics — older entries are the most likely-verified candidates the user wants to surface first when closing the queue. Drift here re-opens P150.
Likely-verified cell shape (P186): the Likely verified? column carries an evidence-first cell — yes — observed: <evidence> / no — not observed / no — observed regression. 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). On a Verification Pending → Closed transition the closing commit's session-observed evidence should populate the cell as yes — observed: <evidence> before the row exits the queue. Drift on the cell shape re-opens P186.
Mechanism:
-
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.
-
git add docs/problems/README.md — stage the refreshed README with the same commit as the transition.
-
Update the "Last reviewed" line per the inline P134 rotation mechanism below. The mechanism is inlined here at the execution site (not deferred via cross-document reference to manage-problem SKILL.md Step 5) 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 P331 (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:
- 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).
- 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.
- 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 ADR-040 Tier 3 envelope; advisory-only enforcement via packages/itil/scripts/check-problems-readme-budget.sh.
- Stage both —
git add docs/problems/README.md docs/problems/README-history.md so the same single commit per ADR-014 single-commit grain captures both files.
Canonical rationale anchor: manage-problem SKILL.md Step 5 § Last-reviewed line discipline (P134). The cross-reference is preserved for the "why"; the "what" is inlined above for execution-time legibility per P331.
7b. Bidirectional upstream lifecycle update (P080 — advisory)
After the rename + README refresh land but BEFORE the Step 8 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 ADR-014 single-commit grain. This is the outbound-lifecycle-update leg of the reporter loop (the inbound-discovery leg is owned by ADR-062's assessment pipeline; together they close the reporter relationship per JTBD-301 + JTBD-201).
The trigger fires whenever the ticket carries a ## Reported Upstream section (outbound) OR an **Origin**: inbound-reported (#NN) field (inbound, P363) — 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 (P362). 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: ADR-054 (SKILL.md runtime-budget policy; ADR-038 progressive-disclosure as the ancestor principle); ADR-024 amendment (P363) for the inbound-origin alternation.
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 8. Only when it matches, invoke the sibling skill via the Skill tool:
/wr-itil:update-upstream <NNN>
Behaviour matrix:
- 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 8. (The sibling skill retains its own Step 1 no-op exit as defence-in-depth for any path that reaches it directly.)
**Origin**: inbound-reported (#NN) present → the sibling skill runs its inbound-origin verdict dispatch leg (P363): 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.
## 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 8 commit captures the back-write alongside the transition.
## 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 8 commit captures the ## Queued Upstream Update appendage alongside the transition. The orchestrator continues per P352 queue-and-continue — do NOT halt the transition on an above-appetite upstream update.
If /wr-itil:update-upstream is not installed (the @windyroad/itil package version pre-dates P080 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 8 — do NOT halt the transition.
Per ADR-013 Rule 6 (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.
Authority: ADR-024 amendment (P080) — bidirectional lifecycle-update sibling skill. Per ADR-010 amended "Split-skill execution ownership" (P093), an equivalent advisory subsection ALSO lives in /wr-itil:manage-problem's in-skill Step 7 block ("copy, not move") so the in-skill callers (Step 9b auto-transition, Step 9d closure inside review, the Parked path) fire the same lifecycle update.
8. Commit per ADR-014
Governance skills commit their own work. Transition commits include the renamed ticket file + any content edits + the refreshed docs/problems/README.md.
Commit gate — satisfy via one of two paths (either produces a bypass marker):
- Primary: delegate to subagent type
wr-risk-scorer:pipeline via the Agent tool.
- Fallback: if
wr-risk-scorer:pipeline is not available in the current tool set (e.g. this skill is running inside a spawned subagent), invoke /wr-risk-scorer:assess-release via the Skill tool. Per ADR-015 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 P035).
Land the commit via wr-risk-scorer-restage-commit — atomic re-stage + commit (P326 wrapper). The Agent-tool delegation above can silently clear the index; the helper re-adds the renamed + edited ticket file (plus docs/problems/README.md + docs/problems/README-history.md from Step 7's P134 rotation), asserts non-empty staging, then runs git commit with the supplied -m args:
wr-risk-scorer-restage-commit \
-m "<message per convention below>" \
-- docs/problems/<dest-state>/<NNN>-<title>.md docs/problems/README.md docs/problems/README-history.md
Omit docs/problems/README-history.md from the path list when the P134 rotation did NOT append (same-session same-verb near-duplicate suppression). When the transition is folded into a fix(<scope>): ... (closes P<NNN>) commit shipping the actual fix, include the source-tree paths the fix touched alongside the ticket file in the -- path list.
Commit message conventions:
- Open → Known Error transition (standalone):
docs(problems): P<NNN> known error — <root cause summary>
- Known Error → Verification Pending (folded with fix):
fix(<scope>): <description> (closes P<NNN>) — per ADR-022, include the rename-to-.verifying.md + ## Fix Released section in the same commit
- Known Error → Verification Pending (standalone, no fix riding with it):
docs(problems): P<NNN> verification pending — <release marker>
- Verification Pending → Closed:
docs(problems): close P<NNN> <title>
If commit risk is above appetite: auto-apply scorer remediations per ADR-042 Rule 1 until residual risk is within appetite, OR halt per ADR-042 Rule 5 if the scorer cannot converge. MUST NOT commit above appetite; MUST NOT call AskUserQuestion to ask whether to commit anyway (P377/RFC-029 — above-appetite is framework-mediated, not a one-time-override). If AskUserQuestion is unavailable (AFK), the ADR-013 Rule 6 fail-safe applies as the terminal fallback: skip the commit and report the uncommitted state. This applies only to the risk-above-appetite branch, not to the delegation-unavailable case above.
9. Report the outcome
Report: ticket ID, previous Status, new Status, new filename, commit SHA. If the destination was verifying, name the ## Fix Released section's release marker so the user can correlate with the shipped version.
Release draining is owned by the caller — /wr-itil:manage-problem Step 12 (interactive) or the /wr-itil:work-problems orchestrator (AFK, Step 6.5 cadence). This skill does not invoke npm run push:watch / release:watch on its own.
Ownership boundary
transition-problem owns (for the user-initiated transition path):
- Argument parsing (
<NNN> <status>).
- Ticket-file discovery via the dual-tolerant lookup
ls docs/problems/<NNN>-*.md docs/problems/*/<NNN>-*.md (RFC-002 transitional shape; both layouts).
- Destination-reachability validation (Open → Known Error → Verification Pending → Closed, one step at a time).
- Pre-flight checks for the supplied destination.
- P063 external-root-cause detection (Open → Known Error only) — including the AFK fallback that appends the stable
- **Upstream report pending** — marker.
git mv rename + Status field edit + (for verifying) ## Fix Released section write + explicit P057 re-stage.
docs/problems/README.md refresh (P062) staged alongside the transition.
- ADR-014 commit through the risk-scorer commit gate.
transition-problem does NOT:
- Re-invoke
/wr-itil:manage-problem to run Step 7 — the deprecation-window forwarder on manage-problem is one-way (P093 / ADR-010 amended "Split-skill execution ownership", no round-trip).
- Re-rank the backlog — that's
/wr-itil:review-problems.
- Create tickets or run the bare-
<NNN> update flow — those stay on /wr-itil:manage-problem.
- Park tickets — the
.parked.md suffix has its own path on /wr-itil:manage-problem (P063 AFK fallback fires there too).
- Auto-transition inside review — Step 9b's Open → Known Error auto-transition uses manage-problem's in-skill Step 7 block ("copy, not move").
- Drain the release queue —
push:watch / release:watch are owned by the caller (/wr-itil:manage-problem Step 12, or the /wr-itil:work-problems orchestrator).
Related
- P071 (
docs/problems/071-argument-based-skill-subcommands-are-not-discoverable.open.md) — originating ticket. This skill is phase 4 of the P071 phased-landing plan (list-problems was phase 1; review-problems was phase 2; work-problem was phase 3).
- ADR-010 amended (
docs/decisions/010-rename-wr-problem-to-wr-itil.proposed.md — Skill Granularity section) — canonical skill-split naming + forwarder contract + deprecated-arguments: true frontmatter flag.
- ADR-013 (
docs/decisions/013-structured-user-interaction-for-governance-decisions.proposed.md) — Rule 1 for interactive prompts; Rule 6 for the AFK non-interactive branch.
- ADR-014 — governance skills commit their own work. This skill owns the per-transition commit (P093 — authoritative executor for the user-initiated path).
- ADR-022 —
.verifying.md suffix on release; Verification Pending is a first-class status distinct from Known Error. Known Error → Verification Pending is the most common transition this skill forwards.
- ADR-032 — governance skill invocation patterns.
/wr-itil:work-problems may delegate transition iterations to this skill during AFK release orchestration.
- ADR-037 (
docs/decisions/037-skill-testing-strategy.proposed.md) — contract-assertion bats pattern applied to this skill.
- P057 —
git mv + Edit staging trap rationale; the delegated Step 7 block implements the re-stage. Named here as a transitive contract so callers can reason about the dependency.
- P062 —
/wr-itil:review-problems is the canonical README.md cache writer, but Step 7 transitions also refresh README.md in-place per P062's mechanism. Named here as a transitive contract.
- P186 — evidence-first
Likely verified? cell shape (yes — observed: <evidence> / no — not observed / no — observed regression); <!-- LIKELY-VERIFIED-CELL-SHAPE: evidence-based per P186 --> marker drives cross-skill drift detection (P138 / P150 fix-shape precedent).
- P063 — external-root-cause detection at Open → Known Error and at the
upstream-blocked park path. The delegated Step 7 block owns the prompt; this skill inherits the AFK fallback without re-implementing.
- JTBD-001 (
docs/jtbd/developer/JTBD-001-enforce-governance.proposed.md) — discoverable surface via /wr-itil: autocomplete. Users type /wr-itil:transition-problem 042 known-error rather than remembering the manage-problem <NNN> known-error subcommand.
- JTBD-101 (
docs/jtbd/plugin-developer/JTBD-101-extend-suite.proposed.md) — one skill per distinct user intent.
packages/itil/skills/manage-problem/SKILL.md — hosts the deprecation-window forwarder for the manage-problem <NNN> <status> form (one-way to this skill, no round-trip per P093). Also retains its own in-skill Step 7 block for in-skill callers (Step 9b auto-transition, Parked path, Step 9d closure) per ADR-010 amended "Split-skill execution ownership" — copy, not move.
- P093 (
docs/problems/093-transition-problem-and-manage-problem-circular-delegation-for-nnn-status-args.*.md) — the circular-delegation ticket that authorised this skill's absorbing the Step 7 block inline.
packages/itil/skills/review-problems/SKILL.md — sibling refresh skill; this skill's transitions trigger the same README.md regeneration mechanism P062 codifies.
packages/itil/skills/list-problems/SKILL.md — sibling read-only display skill; same cache contract.
packages/itil/skills/work-problem/SKILL.md — sibling selection skill; delegates per-ticket execution (including transitions) through /wr-itil:manage-problem.
$ARGUMENTS