@windyroad/itil 0.19.5 → 0.19.6

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.
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "wr-itil",
3
- "version": "0.19.5",
3
+ "version": "0.19.6",
4
4
  "description": "ITIL-aligned IT service management for Claude Code"
5
5
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@windyroad/itil",
3
- "version": "0.19.5",
3
+ "version": "0.19.6",
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"
@@ -104,10 +104,10 @@ The skipped tickets that triggered stop-condition #2 frequently carry **user-ans
104
104
 
105
105
  **2. Branch on interactivity per ADR-013 Rule 1 / Rule 6.**
106
106
 
107
- - **Interactive invocation** (AskUserQuestion is available AND the loop was not started in AFK mode): batch the questions into one `AskUserQuestion` call (or more, if >4 questions, issued sequentially). Header: `"Outstanding design questions"`. For each question, set the prompt from the extracted text and the options from the ticket's candidate fixes or option list. Write each answer back to the corresponding ticket file so the next AFK loop does not re-ask.
108
- - **Non-interactive / AFK invocation** (default for this skill per JTBD-006 the persona is AFK): do NOT call `AskUserQuestion`. Instead emit an `### Outstanding Design Questions` section in the post-stop summary listing each question with its Ticket ID, the question text, and one-line context. The user answers on return.
107
+ - **Default branch — call `AskUserQuestion` when available** (the orchestrator's main turn is interactive by construction; the user is presumed at the keyboard). Batch the questions into one `AskUserQuestion` call (or more, if >4 questions, issued sequentially). Header: `"Outstanding design questions"`. For each question, set the prompt from the extracted text and the options from the ticket's candidate fixes or option list. Write each answer back to the corresponding ticket file so the next AFK loop does not re-ask. This is ADR-013 Rule 1 applied to the orchestrator's main-turn surface.
108
+ - **Fallback branch emit `### Outstanding Design Questions` table** when `AskUserQuestion` is unavailable (restricted permission mode, hook-disabled tool surface, or any other context where the structured-question primitive cannot fire). The table lists each question with its Ticket ID, the question text, and one-line context. The user answers on return. This is ADR-013 Rule 6 fail-safe — fall back to a structured summary when the structured-interaction primitive is unavailable.
109
109
 
110
- This branch is the Rule 6 fail-safe applied to stop-condition #2: Rule 1 says route governance decisions through `AskUserQuestion`; Rule 6 says fall back to a structured summary when the tool is unavailable or the user is away. JTBD-006's persona constraint ("autonomously work without needing interactive input") makes the non-interactive path the default for this skill AskUserQuestion is the exception, not the rule.
110
+ **Cross-skill principle (architect FLAG, P122)**: orchestrator main turns default to `AskUserQuestion` when available; the AFK persona (JTBD-006) is served by the **subprocess-boundary contract under ADR-032** (iteration subprocess workers are AFK by construction via `claude -p` — they exit at `ITERATION_SUMMARY` and never reach stop-condition #2), NOT by suppressing `AskUserQuestion` at the orchestrator layer. Step 5's iteration-prompt template carries the per-subprocess AFK contract (constraint: "Do not call `AskUserQuestion`"); stop-condition #2 fires only in the orchestrator's main turn where the user is presumed present. This principle generalises to any future AFK orchestrator that hits the same surface defer the AFK persona to the subprocess boundary, not to the orchestrator's question-surfacing branch.
111
111
 
112
112
  **3. Emit the final summary + `ALL_DONE`.** The summary includes the Outstanding Design Questions table when any user-answerable questions were surfaced (see Output Format).
113
113
 
@@ -425,7 +425,7 @@ When `AskUserQuestion` is unavailable or the user is AFK, the skill (and the del
425
425
  | Origin diverged before start | Pull `--ff-only` if trivial; stop with report (`git log HEAD..origin/<base>` and reverse) if non-fast-forward — per ADR-019 (Step 0) |
426
426
  | Prior-session partial work detected at start (session-continuity dirty: untracked `docs/decisions/*.proposed.md` / `docs/problems/*.md`, `.afk-run-state/iter-*.json` with `is_error: true` or `api_error_status >= 400`, stale `.claude/worktrees/*`, uncommitted SKILL.md/source/ADR edits) | Halt the loop with a structured Prior-Session State report in the AFK summary. Do NOT attempt non-interactive resume. Interactive invocations prompt via `AskUserQuestion` with 4 options (resume / discard / leave-and-lower-priority / halt). Per P109 + ADR-013 Rule 6 (Step 0 session-continuity detection pass). |
427
427
  | Fix verification needed | Skip problem, add to "needs verification" list |
428
- | Stop-condition #2 with user-answerable skip-reasons | Emit Outstanding Design Questions table in summary (do NOT call AskUserQuestion). The persona is AFK by definition per JTBD-006 and ADR-013 Rule 6 so the table is the default. Interactive invocations may batch up to 4 questions through AskUserQuestion instead — per ADR-013 Rule 1 (Step 2.5). |
428
+ | Stop-condition #2 with user-answerable skip-reasons | Default: call AskUserQuestion (batched, ≤4 per call, sequential when >4) the orchestrator's main turn is interactive by construction per ADR-032 subprocess-boundary; user is presumed at the keyboard. Fallback: emit Outstanding Design Questions table when AskUserQuestion is unavailable (Rule 6 fail-safe). Per ADR-013 Rule 1 + P122 (Step 2.5). |
429
429
  | Unexpected dirty state between iterations | Halt the loop. Report the `git status --porcelain` output, the last iteration's reported outcome, and the divergence — per P036 (Step 6.75). Do NOT attempt non-interactive recovery. |
430
430
  | External root cause detected at Open → Known Error, or at park with `upstream-blocked` reason | Append the stable `- **Upstream report pending** — external dependency identified; invoke /wr-itil:report-upstream when ready` marker to the ticket's `## Related` section; do NOT auto-invoke `/wr-itil:report-upstream` (Step 6 security-path branch is interactive — per ADR-024 Consequences). Use the already-noted grep check to avoid duplicate lines. Per P063 + ADR-013 Rule 6. |
431
431
 
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env bats
2
+
3
+ # P122: work-problems Step 2.5 stop-condition #2 routing must default to
4
+ # AskUserQuestion (interactive) and use the table emit only as the
5
+ # AskUserQuestion-unavailable fallback. The "non-interactive default for
6
+ # this skill" prose was wrong-by-design — JTBD-006 (AFK persona) is served
7
+ # by the iteration subprocess workers, not by suppressing AskUserQuestion
8
+ # at the orchestrator's main turn (which is interactive by construction).
9
+ #
10
+ # Doc-lint contract assertions per ADR-037 Permitted Exception (structural
11
+ # checks on prose contract, not behavioural coverage).
12
+
13
+ setup() {
14
+ REPO_ROOT="$(cd "$(dirname "$BATS_TEST_FILENAME")/../../../../.." && pwd)"
15
+ SKILL_MD="$REPO_ROOT/packages/itil/skills/work-problems/SKILL.md"
16
+ }
17
+
18
+ @test "work-problems P122: SKILL.md exists" {
19
+ [ -f "$SKILL_MD" ]
20
+ }
21
+
22
+ @test "work-problems P122: Step 2.5 removes the legacy AFK-as-default prose" {
23
+ # The flipped default — the legacy "non-interactive path the default
24
+ # for this skill" prose at Step 2.5 must be gone. (Note: Step 0's
25
+ # session-continuity AFK branch intentionally retains its own AFK
26
+ # default for a different reason; this test is scoped to Step 2.5's
27
+ # specific phrasing only.)
28
+ run grep -F 'non-interactive path the default for this skill' "$SKILL_MD"
29
+ [ "$status" -ne 0 ]
30
+ }
31
+
32
+ @test "work-problems P122: Step 2.5 explicitly cites AskUserQuestion as the default branch" {
33
+ # The new default-selection prose names a "Default branch" that calls
34
+ # AskUserQuestion. Match the structural phrase rather than the
35
+ # backtick-wrapped tool name to keep the grep portable.
36
+ run grep -F 'Default branch' "$SKILL_MD"
37
+ [ "$status" -eq 0 ]
38
+ }
39
+
40
+ @test "work-problems P122: Step 2.5 cites the orchestrator-vs-subprocess principle" {
41
+ # The flip's load-bearing reasoning: the orchestrator's main turn is
42
+ # interactive by construction; AFK persona is served by the
43
+ # subprocess-boundary contract under ADR-032, not by suppressing
44
+ # AskUserQuestion at the orchestrator layer. (Architect FLAG —
45
+ # cross-skill principle sentence.)
46
+ run grep -F 'subprocess-boundary contract' "$SKILL_MD"
47
+ [ "$status" -eq 0 ]
48
+ run grep -F 'interactive by construction' "$SKILL_MD"
49
+ [ "$status" -eq 0 ]
50
+ }
51
+
52
+ @test "work-problems P122: Step 2.5 preserves the user-answerable skip-reason scoping" {
53
+ # P103 anti-pattern boundary: the AskUserQuestion default must NOT
54
+ # broaden to architect-design or upstream-blocked skip-reasons. The
55
+ # user-answerable scoping from Step 4's classifier remains in force.
56
+ run grep -F 'user-answerable' "$SKILL_MD"
57
+ [ "$status" -eq 0 ]
58
+ }
59
+
60
+ @test "work-problems P122: Step 2.5 preserves the 4-question-per-call cap" {
61
+ # AskUserQuestion's documented per-call limit; sequential calls when
62
+ # the question set exceeds the cap.
63
+ run grep -F '4 questions per' "$SKILL_MD"
64
+ [ "$status" -eq 0 ]
65
+ }
66
+
67
+ @test "work-problems P122: Step 2.5 preserves the table-fallback-when-unavailable branch" {
68
+ # Rule 6 fail-safe: when AskUserQuestion is unavailable (restricted
69
+ # permission mode, etc.), emit the Outstanding Design Questions table.
70
+ run grep -F 'Outstanding Design Questions' "$SKILL_MD"
71
+ [ "$status" -eq 0 ]
72
+ }
73
+
74
+ @test "work-problems P122: Decisions Table row for stop-condition #2 names AskUserQuestion as default" {
75
+ # The Step 6.5 Decisions Table row at the bottom of the SKILL.md
76
+ # must agree with the Step 2.5 prose — the prior "table is the
77
+ # default" wording must be flipped here too.
78
+ run grep -E '^\| Stop-condition #2 .*AskUserQuestion' "$SKILL_MD"
79
+ [ "$status" -eq 0 ]
80
+ }