@windyroad/itil 0.12.0-preview.150 → 0.13.0-preview.152

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.12.0",
3
+ "version": "0.13.0",
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.12.0-preview.150",
3
+ "version": "0.13.0-preview.152",
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"
@@ -116,21 +116,43 @@ Record the category alongside the skip reason in the iteration report so Step 2.
116
116
 
117
117
  If a problem is skipped by this step, add it to a "skipped" list with the reason and loop back to step 3 for the next one.
118
118
 
119
- ### Step 5: Work the problem (delegate via Agent tool, per P077)
119
+ ### Step 5: Work the problem (dispatch via `claude -p` subprocess, per P084)
120
120
 
121
- **Delegate each iteration to a subagent via the Agent tool** do NOT invoke `/wr-itil:manage-problem` inline via the Skill tool. Inline Skill-tool invocation expands manage-problem's SKILL.md (500+ lines) into the main orchestrator's context every iteration, accumulates across the AFK loop, and causes silent early-stop (`ALL_DONE` without a documented stop condition firing). This delegation is the AFK iteration-isolation wrapper sub-pattern under ADR-032.
121
+ **Dispatch each iteration to a fresh `claude -p` subprocess via Bash** — do NOT spawn via the Agent tool, do NOT invoke `/wr-itil:manage-problem` inline via the Skill tool.
122
122
 
123
- **Agent call shape:**
123
+ - **Skill-tool inline invocation** expands manage-problem's SKILL.md (500+ lines) into the main orchestrator's context every iteration, accumulates across the AFK loop, and causes silent early-stop (`ALL_DONE` without a documented stop condition firing). This was the original pre-P077 failure mode.
124
+ - **Agent-tool dispatch to a `general-purpose` subagent** (the P077 amendment) works for context isolation but fails at the governance-gate layer: subagents spawned via the Agent tool do NOT have the Agent tool in their own surface (three-source evidence — ToolSearch probe, Claude Code docs at `code.claude.com/docs/en/subagents.md`, empirical runtime error `"No such tool available: Agent. Agent is not available inside subagents."`). Without Agent, the iteration worker cannot set architect + JTBD PreToolUse edit-gate markers (only settable via Agent-tool PostToolUse hook), cannot satisfy the risk-scorer commit gate, and silently halts on every gate-covered iteration. P084 diagnoses and closes this gap.
125
+ - **`claude -p` subprocess dispatch** (this step, per P084 / ADR-032 amendment): the subprocess is a full main Claude Code session with Agent available in its own surface. Governance review runs at full depth via the normal `wr-architect:agent` / `wr-jtbd:agent` / `wr-risk-scorer:pipeline` delegation path inside the subprocess; PostToolUse marker hooks fire correctly matching the subprocess's own `$CLAUDE_SESSION_ID`; the commit gate unlocks natively. Context isolation preserved by the process boundary (each subprocess is a distinct process with its own session state; orchestrator's main context only sees the stdout). This is the AFK iteration-isolation wrapper — subprocess-boundary variant under ADR-032.
124
126
 
125
- - `subagent_type`: `general-purpose` — Option B pinned in P077. Iteration work is general engineering, not specialised domain expertise, and `general-purpose` has `Tools: *` so the subagent can recursively invoke architect / jtbd / risk-scorer subagents for its own gate reviews. Promotion to a typed `wr-itil:work-problems-iteration-worker` subagent remains available if a specialised constraint ever emerges; until then, typing it would just duplicate manage-problem's "always do X" preamble.
126
- - `description`: `Work P<NNN> (<title>)` — one iteration, identified by the highest-WSJF ticket selected in Steps 3–4.
127
- - `prompt` (self-contained — the subagent has no prior conversation context):
128
- 1. **Context**: this is one iteration of the AFK work-problems loop. The user is AFK. The orchestrator selected `P<NNN> (<title>)` as the highest-WSJF actionable ticket.
129
- 2. **Task**: apply the `/wr-itil:manage-problem` workflow for `work highest WSJF problem that can be progressed non-interactively as the user is AFK`. Follow manage-problem SKILL.md verbatim, including architect / jtbd / style-guide / voice-tone gate reviews and the commit gate (manage-problem Step 11).
130
- 3. **Constraints**: commit the completed work per ADR-014. Do NOT push, do NOT run `push:watch`, do NOT run `release:watch` — the orchestrator's Step 6.5 owns release cadence. Do NOT invoke `capture-*` background skills (AFK carve-out — ADR-032). Non-interactive defaults apply per ADR-013 Rule 6.
131
- 4. **Return the iteration summary** (see contract below).
127
+ **Dispatch command shape (Bash):**
132
128
 
133
- **Return-summary contract.** The subagent's final message MUST end with a structured summary block the orchestrator parses without re-reading tool calls. Required fields:
129
+ ```bash
130
+ ITERATION_PROMPT=$(cat <<'PROMPT_EOF'
131
+ <iteration prompt body — see below>
132
+ PROMPT_EOF
133
+ )
134
+
135
+ claude -p \
136
+ --permission-mode bypassPermissions \
137
+ --output-format json \
138
+ "$ITERATION_PROMPT"
139
+ ```
140
+
141
+ **Flag rationale:**
142
+
143
+ - `--permission-mode bypassPermissions` — handles non-interactive permission prompts. Without this, Bash/Edit/Write calls inside the subprocess halt on approval prompts (no TTY). Alternative modes (`acceptEdits`, `auto`, `dontAsk`) are acceptable if adopters need narrower permission scopes; `bypassPermissions` is the broadest and the empirically-verified path.
144
+ - `--output-format json` — deterministic structured output. The subprocess's final agent message lands in the JSON response's `.result` field; orchestrator extracts `ITERATION_SUMMARY` from that field. Plain-text output would require fragile scraping.
145
+
146
+ **No per-iteration budget cap.** The dispatch deliberately omits `--max-budget-usd`. Per user direction 2026-04-21: the natural stop condition for an AFK loop is quota exhaustion, not an arbitrary per-iteration dollar cap. A cap would halt iterations before quota is actually exhausted, wasting remaining budget. Runaway-iteration risk is bounded by quota + the orchestrator's Step 6.75 halt on unexpected dirty state + exit-code handling below.
147
+
148
+ **Iteration prompt body (self-contained — the subprocess has no prior conversation context):**
149
+
150
+ 1. **Context**: this is one iteration of the AFK work-problems loop. The user is AFK. The orchestrator selected `P<NNN> (<title>)` as the highest-WSJF actionable ticket.
151
+ 2. **Task**: apply the `/wr-itil:manage-problem` workflow for `work highest WSJF problem that can be progressed non-interactively as the user is AFK`. Follow manage-problem SKILL.md verbatim, including architect / jtbd / style-guide / voice-tone gate reviews and the commit gate (manage-problem Step 11). Because this subprocess has the Agent tool in its own surface, the normal review-via-subagent paths work — no inline-verdict fallback needed.
152
+ 3. **Constraints**: commit the completed work per ADR-014. Do NOT push, do NOT run `push:watch`, do NOT run `release:watch` — the orchestrator's Step 6.5 owns release cadence. Do NOT invoke `capture-*` background skills (AFK carve-out — ADR-032). Do NOT use `ScheduleWakeup` under any circumstance (P083 — iteration workers must not self-reschedule). Non-interactive defaults apply per ADR-013 Rule 6.
153
+ 4. **Output**: end the final message with the `ITERATION_SUMMARY` block defined below — this is how the orchestrator consumes the iteration's result.
154
+
155
+ **Return-summary contract** (unchanged from the P077 amendment — the parse shape is dispatch-mechanism-agnostic). The subprocess's final message MUST end with this structured block, extracted by the orchestrator from the JSON `.result` field:
134
156
 
135
157
  ```
136
158
  ITERATION_SUMMARY
@@ -149,14 +171,24 @@ notes: <one-line>
149
171
 
150
172
  Architect review (R2) requires the commit state fields (`committed` / `commit_sha` / `reason`) so **Step 6.75's Dirty-for-known-reason branch stays evaluable** from the summary alone. JTBD review requires `ticket_id` / `action` / `skip_reason_category` / `outstanding_questions` so Step 2.5 and the Output Format's Completed / Skipped / Outstanding Design Questions tables can be populated deterministically without the orchestrator having to re-parse ticket files.
151
173
 
152
- **Inter-iteration continuity.** Step 6.5 (release-cadence check) and Step 6.75 (inter-iteration verification) stay in the **main orchestrator's turn**, NOT the iteration subagent. Rationale: release-cadence and `git status --porcelain` are orchestration-level concerns; `push:watch`/`release:watch` are long-running waits that would waste iteration-subagent context; the orchestrator needs to see the summary from one iteration before deciding whether to drain before the next.
174
+ **Exit-code semantics.** `claude -p` exits non-zero when the subprocess fails hard subprocess crash, auth failure, unresolvable permission denial, API/quota exhaustion. The orchestrator reads the exit code BEFORE parsing `.result`:
175
+
176
+ - Exit 0 → parse `ITERATION_SUMMARY` from `.result` field; proceed to Step 6.
177
+ - Non-zero exit → halt the loop; report the exit code, stderr, and any partial `.result` in the final summary. Do NOT spawn the next iteration. The user returns to a stopped loop with a clear failure reason (e.g. "quota exhausted — resume when quota resets").
178
+
179
+ **Quota as the natural stop.** The AFK loop runs until quota is exhausted or a stop-condition from Step 2 fires. There is no per-iteration dollar cap; running iterations until quota is actually exhausted maximises backlog progress per quota cycle. Quota-exhaust on a `claude -p` invocation surfaces as a non-zero exit and the orchestrator halts cleanly per the rule above.
180
+
181
+ **Hook session-id isolation.** Each `claude -p` subprocess has its own `$CLAUDE_SESSION_ID`. Gate markers at `/tmp/architect-reviewed-<ID>`, `/tmp/jtbd-reviewed-<ID>`, `/tmp/risk-scorer-*-<ID>` are scoped to the subprocess's own hook interactions and never shared with the orchestrator's main-turn SESSION_ID. This is the correct behaviour — the orchestrator's main turn runs its own gate flow if it edits gated paths; the subprocess's gate flow is independent. Implementations MUST NOT wire cross-process marker sharing.
182
+
183
+ **Inter-iteration continuity.** Step 6.5 (release-cadence check) and Step 6.75 (inter-iteration verification) stay in the **main orchestrator's turn**, NOT the iteration subprocess. Rationale: release-cadence and `git status --porcelain` are orchestration-level concerns; `push:watch`/`release:watch` are long-running waits that would waste iteration-subprocess context; the orchestrator needs to see the summary from one iteration before deciding whether to drain before the next. Orchestrator detects subprocess commits by reading the working tree (`git status --porcelain`) and the parsed `ITERATION_SUMMARY.commit_sha` — not session-state continuity with the subprocess.
153
184
 
154
- The manage-problem skill (running inside the iteration subagent) will:
185
+ The manage-problem skill (running inside the iteration subprocess) will:
155
186
 
156
187
  - Run a review if the cache is stale.
157
188
  - Select and work the highest-WSJF problem.
158
189
  - Use its built-in non-interactive fallbacks (auto-split multi-concern problems, auto-commit when risk is within appetite).
159
- - Commit completed work per ADR-014 (the iteration subagent's commit the orchestrator does NOT commit from its main turn).
190
+ - Delegate architect / JTBD / risk-scorer reviews via the Agent tool (available in the subprocess's surface) at the depth defined in each review skill's SKILL.md.
191
+ - Commit completed work per ADR-014 (the iteration subprocess's commit inside its own session — the orchestrator does NOT commit from its main turn).
160
192
 
161
193
  ### Step 6: Report progress
162
194
 
@@ -226,7 +258,7 @@ When `AskUserQuestion` is unavailable or the user is AFK, the skill (and the del
226
258
 
227
259
  | Decision Point | Non-Interactive Default |
228
260
  |---|---|
229
- | How each iteration runs (iteration delegation) | Delegate to `subagent_type: general-purpose` via the Agent tool per Step 5 — NOT inline Skill-tool invocation. This is the AFK iteration-isolation wrapper sub-pattern under ADR-032; the main orchestrator consumes the iteration subagent's return-summary contract and does not re-read the subagent's tool calls. Per P077 + ADR-032. |
261
+ | How each iteration runs (iteration delegation) | Dispatch to a fresh `claude -p --permission-mode bypassPermissions --output-format json` subprocess via Bash per Step 5 — NOT Agent-tool dispatch (the Agent-tool-spawned subagent has no Agent in its own surface, so governance gates cannot be satisfied P084), and NOT inline Skill-tool invocation (expands manage-problem into the orchestrator's context and burns turns — P077). The subprocess is a full main Claude Code session with Agent available, so architect / JTBD / risk-scorer reviews run at full depth; the orchestrator consumes the `ITERATION_SUMMARY` return-shape from the subprocess's JSON stdout. No per-iteration budget cap natural stop is quota exhaustion. This is the AFK iteration-isolation wrapper — subprocess-boundary variant under ADR-032. Per P084 + P077 + ADR-032. |
230
262
  | Which problem to work | Highest WSJF, no prompt needed |
231
263
  | Multi-concern split | Auto-split (manage-problem step 4b fallback) |
232
264
  | Scope expansion during work | Update problem file, re-score WSJF, move to next problem instead of continuing |
@@ -288,7 +320,9 @@ When every skipped ticket is in the `upstream-blocked` category (stop-condition
288
320
 
289
321
  ## Related
290
322
 
291
- - **P077** (`docs/problems/077-work-problems-step-5-does-not-delegate-to-subagent.verifying.md`) — driver for Step 5's Agent-tool delegation and the return-summary contract.
323
+ - **P084** (`docs/problems/084-work-problems-iteration-worker-has-no-agent-tool-so-architect-jtbd-gates-block.open.md`) — driver for Step 5's subprocess-boundary dispatch. Supersedes P077's Agent-tool dispatch on the same Step 5 surface because Agent-tool-spawned subagents cannot themselves invoke Agent (platform restriction), which prevents governance gate markers from being set inside the iteration worker.
324
+ - **P077** (`docs/problems/077-work-problems-step-5-does-not-delegate-to-subagent.verifying.md`) — parent amendment. Established the AFK iteration-isolation wrapper sub-pattern and the `ITERATION_SUMMARY` return contract. P084 is the refinement that swaps the spawn mechanism; the isolation intent and return contract are preserved verbatim.
325
+ - **P083** (`docs/problems/083-work-problems-iteration-worker-prompt-does-not-forbid-schedulewakeup.open.md`) — iteration prompt body forbids `ScheduleWakeup`. Applies equally to subprocess-dispatched iterations.
292
326
  - **P036** — inter-iteration verification (Step 6.75); remains in the orchestrator's main turn.
293
327
  - **P040** — origin-fetch preflight (Step 0); unchanged.
294
328
  - **P041** — release-cadence drain (Step 6.5); remains in the orchestrator's main turn.
@@ -299,6 +333,6 @@ When every skipped ticket is in the `upstream-blocked` category (stop-condition
299
333
  - **ADR-018** (`docs/decisions/018-release-cadence.proposed.md`) — release cadence stays in the orchestrator's main turn, not the iteration subagent.
300
334
  - **ADR-019** (`docs/decisions/019-afk-orchestrator-preflight.proposed.md`) — preflight stays in the orchestrator's main turn.
301
335
  - **ADR-022** (`docs/decisions/022-problem-verification-pending.proposed.md`) — iteration outcomes map into the return-summary's `outcome` field (`verifying` for a released fix, `known-error` for a root-cause-confirmed ticket awaiting release, etc.).
302
- - **ADR-032** (`docs/decisions/032-governance-skill-invocation-patterns.proposed.md`) — pattern taxonomy parent; Step 5 is the canonical AFK iteration-isolation wrapper sub-pattern per the ADR-032 amendment that lands with P077.
336
+ - **ADR-032** (`docs/decisions/032-governance-skill-invocation-patterns.proposed.md`) — pattern taxonomy parent; Step 5 implements the AFK iteration-isolation wrapper — subprocess-boundary variant per the P084 amendment (2026-04-21), refining the P077 Agent-tool amendment. The P077 amendment remains in the ADR as the historical Agent-tool variant; the subprocess variant is the lead for new adopters.
303
337
  - **ADR-037** (`docs/decisions/037-skill-testing-strategy.proposed.md`) — doc-lint bats contract-assertion pattern used by `test/work-problems-step-5-delegation.bats`.
304
338
  - **JTBD-001**, **JTBD-006**, **JTBD-101**, **JTBD-201** — personas whose reliability expectations the iteration-isolation wrapper restores.
@@ -1,100 +1,168 @@
1
1
  #!/usr/bin/env bats
2
2
  # Doc-lint guard: work-problems SKILL.md Step 5 must delegate each iteration
3
- # to a subagent via the Agent tool. Option B is pinned — reuse subagent_type
4
- # `general-purpose`; no typed iteration-worker.
3
+ # by shelling out to a `claude -p` subprocess. Subagents spawned via the Agent
4
+ # tool cannot themselves call Agent (platform restriction — P084 confirmed by
5
+ # three-source evidence 2026-04-21: ToolSearch probe, Claude Code docs at
6
+ # code.claude.com/docs/en/subagents.md, empirical invocation runtime error).
7
+ # So architect + JTBD + risk-scorer gate markers cannot be set from inside an
8
+ # Agent-tool-spawned iteration worker. The subprocess variant has Agent in its
9
+ # surface (empirically verified), so governance review runs at full depth and
10
+ # the commit gate unlocks natively.
5
11
  #
6
- # Structural assertion — Permitted Exception to the source-grep ban (ADR-005
7
- # / P011). These tests assert that the skill specification document encodes
8
- # the delegation contract so context does not accumulate across iterations
9
- # in the main orchestrator's turn.
12
+ # Structural assertion — Permitted Exception to the source-grep ban under
13
+ # ADR-005 + ADR-037 (SKILL.md is explicitly a contract document; doc-lint
14
+ # contract assertion is the named permitted pattern). Behavioural tests for
15
+ # the subprocess integration path would need a full Claude Code session
16
+ # harness, which is out of scope for the skill-level contract layer.
10
17
  #
18
+ # @problem P084
11
19
  # @problem P077
12
20
  # @jtbd JTBD-006
21
+ # @jtbd JTBD-001
13
22
  #
14
23
  # Cross-reference:
15
- # P077 (work-problems Step 5 does not delegate to subagent)
24
+ # P084 (iteration worker has no Agent tool) driver for the subprocess swap
25
+ # P077 (Step 5 does not delegate to subagent) — prior amendment; subprocess
26
+ # is the refinement of the same AFK iteration-isolation wrapper intent
16
27
  # ADR-015 (on-demand assessment skills — Agent-vs-Skill tool precedent)
17
28
  # ADR-032 (governance skill invocation patterns — AFK iteration-isolation
18
- # wrapper sub-pattern)
29
+ # wrapper sub-pattern; amended with subprocess-boundary variant for P084)
19
30
  # ADR-037 (skill testing strategy — contract-assertion pattern)
20
31
  # JTBD-006 (Progress the Backlog While I'm Away)
32
+ # JTBD-001 (Enforce Governance Without Slowing Down)
21
33
 
22
34
  setup() {
23
35
  SKILL_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
24
36
  SKILL_FILE="${SKILL_DIR}/SKILL.md"
25
37
  }
26
38
 
27
- @test "SKILL.md cites P077 (Step 5 delegation)" {
39
+ @test "SKILL.md cites P084 (subprocess dispatch driver)" {
40
+ run grep -n "P084" "$SKILL_FILE"
41
+ [ "$status" -eq 0 ]
42
+ }
43
+
44
+ @test "SKILL.md cites P077 (prior Step 5 delegation amendment)" {
28
45
  run grep -n "P077" "$SKILL_FILE"
29
46
  [ "$status" -eq 0 ]
30
47
  }
31
48
 
32
- @test "SKILL.md Step 5 names the Agent tool explicitly" {
33
- # Bare 'Invoke the manage-problem skill' would read as a Skill-tool
34
- # invocation (in-process expansion). Step 5 must name the Agent tool
35
- # the same way Step 6.5 does (per ADR-015).
36
- run grep -niE "Step 5.{0,160}Agent tool|delegate.{0,60}Agent tool|via the Agent tool" "$SKILL_FILE"
49
+ @test "SKILL.md Step 5 names claude -p as the dispatch mechanism" {
50
+ # The subprocess boundary is how Step 5 achieves iteration isolation post-P084.
51
+ # Bare 'delegate via Agent tool' would re-introduce the tool-surface gap that
52
+ # P084 proved unshippable.
53
+ run grep -nE "claude -p|claude --print" "$SKILL_FILE"
54
+ [ "$status" -eq 0 ]
55
+ }
56
+
57
+ @test "SKILL.md Step 5 specifies --permission-mode bypassPermissions" {
58
+ # Non-interactive permission handling for AFK subprocess (verified by Probe 4).
59
+ # Without this flag, subprocess Bash/Edit/Write calls halt on prompts.
60
+ run grep -nE "permission-mode[[:space:]]+bypassPermissions|--permission-mode[[:space:]]+bypassPermissions" "$SKILL_FILE"
37
61
  [ "$status" -eq 0 ]
38
62
  }
39
63
 
40
- @test "SKILL.md Step 5 cites subagent_type general-purpose" {
41
- # Option B pinned (per ticket 2026-04-21). The subagent_type must be
42
- # explicit so a future refactor cannot silently drop back to Skill-tool.
43
- run grep -nE "subagent_type.{0,20}general-purpose|general-purpose.{0,40}subagent" "$SKILL_FILE"
64
+ @test "SKILL.md Step 5 specifies --output-format json for deterministic parsing" {
65
+ # JSON .result field is the stable parse shape for ITERATION_SUMMARY extraction.
66
+ run grep -nE "output-format[[:space:]]+json|--output-format[[:space:]]+json" "$SKILL_FILE"
44
67
  [ "$status" -eq 0 ]
45
68
  }
46
69
 
70
+ @test "SKILL.md Step 5 does NOT invoke --max-budget-usd in the dispatch command (user direction 2026-04-21)" {
71
+ # Explicit no-cap decision: quota exhaustion is the natural stop, not an
72
+ # arbitrary per-iteration dollar cap. A cap would halt iterations before
73
+ # quota runs out, leaving remaining backlog unprocessed. The assertion is
74
+ # negative to catch regressions that re-introduce a cap by default.
75
+ # Narrowed to the "used-form" pattern (flag followed by a value or envvar);
76
+ # mentions of --max-budget-usd in explanatory prose are allowed because
77
+ # the SKILL.md documents WHY the flag is omitted.
78
+ run grep -nE '\-\-max-budget-usd[[:space:]]+("?\$|"[0-9])' "$SKILL_FILE"
79
+ [ "$status" -ne 0 ]
80
+ }
81
+
82
+ @test "SKILL.md Step 5 does NOT reference WR_ITERATION_BUDGET_USD envvar (cap removed)" {
83
+ # The envvar was part of the earlier cap design that user directed away
84
+ # from. Assertion catches regression that re-introduces the envvar.
85
+ run grep -nE "WR_ITERATION_BUDGET_USD" "$SKILL_FILE"
86
+ [ "$status" -ne 0 ]
87
+ }
88
+
89
+ @test "SKILL.md Step 5 documents quota as the natural stop condition" {
90
+ # User direction 2026-04-21: AFK loop runs until quota exhausted, not until
91
+ # an artificial cap hits. SKILL.md must state this explicitly so future
92
+ # contributors don't re-add a cap "for safety".
93
+ run grep -niE "quota.{0,40}natural|natural.{0,40}quota|quota.{0,60}stop|stop.{0,60}quota|quota exhaust" "$SKILL_FILE"
94
+ [ "$status" -eq 0 ]
95
+ }
96
+
97
+ @test "SKILL.md Step 5 does NOT name subagent_type general-purpose (migrated away)" {
98
+ # Post-P084 the Agent-tool dispatch is removed; Agent-tool-spawned general-purpose
99
+ # subagents cannot satisfy gate markers (no nested Agent). The assertion is
100
+ # negative on purpose: it catches accidental regression to the old dispatch.
101
+ run grep -nE "subagent_type.{0,20}general-purpose" "$SKILL_FILE"
102
+ [ "$status" -ne 0 ]
103
+ }
104
+
47
105
  @test "SKILL.md Step 5 specifies a return-summary contract" {
48
- # The orchestrator must consume a structured summary from the subagent
49
- # (not re-read the subagent's tool calls). Contract fields required by
50
- # architect review (R2) and JTBD review extension.
51
- run grep -niE "return.{0,30}summary|iteration summary|summary shape|summary contract" "$SKILL_FILE"
106
+ # Contract preserved verbatim from P077. Orchestrator reads ITERATION_SUMMARY
107
+ # from subprocess stdout (JSON .result) instead of Agent-tool return value.
108
+ run grep -niE "return.{0,30}summary|iteration summary|summary shape|summary contract|ITERATION_SUMMARY" "$SKILL_FILE"
52
109
  [ "$status" -eq 0 ]
53
110
  }
54
111
 
55
- @test "SKILL.md Step 5 return-summary contract carries commit state (R2)" {
56
- # Architect R2: Step 6.75 inter-iteration verification needs the subagent
57
- # to report committed / commit_sha / reason so the Dirty-for-known-reason
58
- # branch stays evaluable.
112
+ @test "SKILL.md Step 5 return-summary contract carries commit state (Step 6.75 dependency)" {
113
+ # Architect R2 (P077): Step 6.75 inter-iteration verification needs the iteration
114
+ # to report committed / commit_sha / reason so the Dirty-for-known-reason branch
115
+ # stays evaluable. Preserved under subprocess swap.
59
116
  run grep -niE "commit_sha|committed.*true|committed.*false|commit state" "$SKILL_FILE"
60
117
  [ "$status" -eq 0 ]
61
118
  }
62
119
 
63
- @test "SKILL.md Step 5 return-summary contract carries skip-reason category (JTBD extension)" {
64
- # JTBD review: the summary's skip_reason_category is what Step 2.5 reads
65
- # deterministically. Without it the Outstanding Design Questions table
66
- # would have to re-parse ticket files.
120
+ @test "SKILL.md Step 5 return-summary contract carries skip-reason category (Step 2.5 dependency)" {
121
+ # JTBD review (P077): skip_reason_category is what Step 2.5 reads deterministically.
122
+ # Preserved under subprocess swap.
67
123
  run grep -niE "skip_reason_category|skip-reason category" "$SKILL_FILE"
68
124
  [ "$status" -eq 0 ]
69
125
  }
70
126
 
71
- @test "SKILL.md allowed-tools frontmatter includes Agent" {
72
- # P077 pre-existing latent bug (flagged by architect review): the skill
73
- # already requires the Agent tool at Step 6.5 but allowed-tools omits it.
74
- # Fixing Step 5 is the right place to close the latent bug.
127
+ @test "SKILL.md allowed-tools frontmatter includes Bash (for subprocess shell-out)" {
128
+ # Bash is required to invoke `claude -p` from Step 5.
129
+ run grep -nE "^allowed-tools:.*Bash" "$SKILL_FILE"
130
+ [ "$status" -eq 0 ]
131
+ }
132
+
133
+ @test "SKILL.md allowed-tools frontmatter includes Agent (for Step 6.5 risk-scorer)" {
134
+ # Step 6.5 delegates to wr-risk-scorer:pipeline via the Agent tool (orchestrator's
135
+ # main turn, separate from the iteration subprocess). Still required.
75
136
  run grep -nE "^allowed-tools:.*Agent" "$SKILL_FILE"
76
137
  [ "$status" -eq 0 ]
77
138
  }
78
139
 
79
140
  @test "SKILL.md Non-Interactive Decision Making table covers iteration delegation" {
80
- # Architect + ticket requirement: the non-interactive defaults table must
81
- # include a row for 'how each iteration runs' (delegated via Agent tool).
82
- run grep -niE "iteration delegation|delegate.*iteration|iteration.*subagent|iteration.*general-purpose" "$SKILL_FILE"
141
+ # The non-interactive defaults table must include the iteration dispatch row,
142
+ # updated to name claude -p subprocess (not the legacy Agent-tool path).
143
+ run grep -niE "iteration delegation|delegate.*iteration|iteration.*subprocess|claude -p.*iteration|iteration.*claude -p" "$SKILL_FILE"
83
144
  [ "$status" -eq 0 ]
84
145
  }
85
146
 
86
147
  @test "SKILL.md Related section cites ADR-032 (iteration-isolation wrapper)" {
87
- # Architect R3: ADR-032 is amended with the AFK iteration-isolation
88
- # sub-pattern; SKILL.md must cite it so the contract-to-ADR traceability
89
- # ADR-037 requires is complete.
148
+ # ADR-032 is amended with the subprocess-boundary sub-pattern for P084.
90
149
  run grep -nE "ADR-032" "$SKILL_FILE"
91
150
  [ "$status" -eq 0 ]
92
151
  }
93
152
 
94
- @test "SKILL.md Step 5 preserves inter-iteration continuity (Steps 6.5 / 6.75 remain in orchestrator)" {
95
- # Architect review confirmation: Step 6.5 (release cadence) and Step 6.75
96
- # (inter-iteration verification) stay in the main orchestrator's turn.
97
- # The iteration subagent must NOT run push:watch/release:watch.
153
+ @test "SKILL.md Step 5 preserves inter-iteration continuity (Steps 6.5 / 6.75 stay in orchestrator)" {
154
+ # Architect + JTBD review confirmation: Step 6.5 (release cadence) and Step 6.75
155
+ # (inter-iteration verification) stay in the main orchestrator's turn. The
156
+ # iteration subprocess does NOT run push:watch/release:watch.
98
157
  run grep -niE "orchestrator.{0,80}Step 6\\.5|Step 6\\.5.{0,80}orchestrator|Step 6\\.75.{0,80}orchestrator|orchestrator.{0,80}Step 6\\.75|main orchestrator|orchestrator.{0,40}main turn|main.turn.{0,40}orchestrator" "$SKILL_FILE"
99
158
  [ "$status" -eq 0 ]
100
159
  }
160
+
161
+ @test "SKILL.md Step 5 documents hook session-id isolation for subprocess" {
162
+ # Architect advisory (2026-04-21): subprocess has its own $CLAUDE_SESSION_ID,
163
+ # so markers in /tmp/architect-reviewed-<ID> are scoped to subprocess hooks.
164
+ # Intended behaviour, but must be explicitly documented to prevent future
165
+ # contributors from wiring cross-process marker sharing.
166
+ run grep -niE "CLAUDE_SESSION_ID|session.?id isolation|session-id isolation|marker.{0,40}isolated|subprocess.{0,40}SESSION_ID" "$SKILL_FILE"
167
+ [ "$status" -eq 0 ]
168
+ }