@windyroad/itil 0.49.1 → 0.49.2

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.
@@ -497,5 +497,5 @@
497
497
  }
498
498
  },
499
499
  "name": "wr-itil",
500
- "version": "0.49.1"
500
+ "version": "0.49.2"
501
501
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@windyroad/itil",
3
- "version": "0.49.1",
3
+ "version": "0.49.2",
4
4
  "description": "ITIL-aligned IT service management for Claude Code (problem, and future incident/change skills)",
5
5
  "bin": {
6
6
  "windyroad-itil": "./bin/install.mjs"
@@ -733,6 +733,40 @@ Update the "Status" field in the file to "Known Error".
733
733
 
734
734
  When the fix for a Known Error ships, transition the ticket in a single commit.
735
735
 
736
+ #### Conditional-deferral check BEFORE the rename (P184)
737
+
738
+ 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, transitioned the parent ticket, and would have lost the Phase 2 work if the user hadn't asked an orthogonal question that surfaced the misreading.
739
+
740
+ **Detection** (run in order):
741
+
742
+ 1. Grep the ticket body for phase-tracking section headers — regex `^### (Phase|Slice|Tier) [0-9]+` covers the canonical shapes.
743
+ 2. For each detected section, count the unticked `- [ ]` checkboxes inside it (up to the next `^### ` boundary or EOF).
744
+ 3. Grep the body (any section, not just the phase-tracking one) for conditional-deferral markers:
745
+ - `deferred (?:to|pending|until) (?:post-)?[A-Za-z0-9-]+(?:-graduation)?`
746
+ - `Phase [0-9]+ (?:SHIP )?deferred`
747
+ - `deferred-pending-[a-z-]+`
748
+ 4. For each conditional-deferral marker, resolve whether the **gating condition** has fired. The gating condition typically names another phase, ticket, or RFC — check whether that artefact has reached `.closed.md` / `.verifying.md` (for tickets), or `closed` lifecycle (for RFCs / stories per ADR-060).
749
+
750
+ **Halt-and-route** (when ANY conditional deferral has lifted with unticked work remaining):
751
+
752
+ Emit a structured report naming each deferred section + the lifted condition + the unticked task count, then **halt the transition**:
753
+
754
+ - **Interactive**: fire `AskUserQuestion` with `header: "Conditional deferral lifted"` + options:
755
+ 1. `Re-open Phase N — work the deferred tasks now (Recommended)` — halt the K→V transition; route to working the deferred Phase N tasks; revert to Known Error.
756
+ 2. `Confirm Phase N permanently out of scope — proceed with K→V` — user explicit acknowledgement that the deferral was misclassified as conditional and is in fact terminal; proceed with the K→V transition; append `<!-- P184: user-confirmed Phase N permanently OOS -->` marker to the deferred section so re-detection skips it.
757
+ 3. `Split Phase N into a new ticket — proceed with K→V on this one` — halt the K→V transition; route to `/wr-itil:capture-problem` for a new ticket carrying the Phase N scope; once captured, resume the K→V transition on the original ticket.
758
+ - **AFK** (per ADR-013 Rule 6 + P352 queue-and-continue universal default): queue an `outstanding_questions` entry naming the local ticket ID + the lifted-condition citation + the unticked task count + the three options above. **Do NOT auto-transition.** The orchestrator main turn surfaces the queued question at loop end via the existing batched-`AskUserQuestion` end-of-loop gate. Brief the substance BEFORE referencing IDs per `feedback_brief_before_id.md` — the user reads the prompt without project filesystem access.
759
+
760
+ **Proceed silently** (no halt) when:
761
+ - No phase-tracking sections exist in the ticket body (the common case).
762
+ - Phase-tracking sections exist but every task is ticked.
763
+ - Phase-tracking sections exist with unticked tasks BUT the deferral marker explicitly states "permanently out of scope" / "won't fix" / "rejected" without a conditional clause.
764
+ - The conditional-deferral marker carries the `<!-- P184: user-confirmed Phase N permanently OOS -->` marker from a prior surfacing.
765
+
766
+ **Why halt-and-route not silent-default-with-marker**: P184's failure mode is "work silently lost if user doesn't notice"; the P063 silent-default-with-marker shape leaves the lost-work-detection burden on the user reading the marker in the Verification Queue. The halt-and-route shape catches the failure at the transition surface where the loss occurs. Authority: ADR-044 category 2 (deviation-approval) — the agent surfaces a deviation candidate with citations + evidence + a proposed shape; user picks. Driver: user direction in P184 Workaround line 37 — *"explicitly ask the user 'is Phase N still deferred or is it now in-scope?' before transitioning when the ticket body shows phase-tracking sections."*
767
+
768
+ This check fires BEFORE the P330 Release-vehicle seed below — halt-on-conditional-deferral is the outer gate, seed-and-rename is the inner mechanic.
769
+
736
770
  **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 eliminates the `wr-itil-derive-release-vehicle <NNN>` helper's exit-2 routing on standalone K→V iters — the helper greps the ticket body for `.changeset/<name>.md` and exits 2 when absent; seeding the reference at fix-ship time (when the changeset name is fresh in scope, since the fix commit just created it) makes the helper exit 0 deterministically on first call. The exit-2 recovery routing documented in `/wr-itil:transition-problem` Step 6 remains as the legacy-ticket fallback. Matches the user's documented workaround pattern across 3 of 4 standalone K→V dogfoods in the 2026-05-30 session (P316 / P281 / P302 — see P330 § Symptoms).
737
771
 
738
772
  > **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.
@@ -88,6 +88,33 @@ Destination-specific pre-flight checks gate the transition. If any check fails,
88
88
 
89
89
  - [ ] The fix has been implemented (the transition typically rides with the `fix(<scope>): ... (closes P<NNN>)` commit)
90
90
  - [ ] A release marker is available (version, commit SHA, or date) so the `## Fix Released` section can name it
91
+ - [ ] **Conditional-deferral check (P184)** — see the dedicated subsection below; halt the transition if any conditional deferral has lifted with unticked work remaining
92
+
93
+ #### Conditional-deferral check on K→V (P184) — copy-not-move sibling
94
+
95
+ 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](../../../docs/decisions/010-rename-wr-problem-to-wr-itil.proposed.md) 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.
96
+
97
+ 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.
98
+
99
+ **Detection** (run in order):
100
+
101
+ 1. Grep the ticket body for phase-tracking section headers — regex `^### (Phase|Slice|Tier) [0-9]+` covers the canonical shapes.
102
+ 2. For each detected section, count the unticked `- [ ]` checkboxes inside it (up to the next `^### ` boundary or EOF).
103
+ 3. 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-]+`.
104
+ 4. 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).
105
+
106
+ **Halt-and-route** (when ANY conditional deferral has lifted with unticked work remaining):
107
+
108
+ 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.
109
+
110
+ - **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`).
111
+ - **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`.
112
+
113
+ **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.
114
+
115
+ **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."*
116
+
117
+ 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.
91
118
 
92
119
  **Verification Pending → Closed** (`<status>` = `close`) requires:
93
120