@windyroad/itil 0.44.0-preview.501 → 0.44.1

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.44.0"
500
+ "version": "0.44.1"
501
501
  }
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env bash
2
+ exec "$(dirname "$0")/../scripts/verify-iter-summary.sh" "$@"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@windyroad/itil",
3
- "version": "0.44.0-preview.501",
3
+ "version": "0.44.1",
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"
@@ -0,0 +1,196 @@
1
+ #!/usr/bin/env bats
2
+
3
+ # @problem P335 — AFK iter subprocess over-claims completion in
4
+ # ITERATION_SUMMARY notes / commit message while on-disk Confirmation
5
+ # checkboxes remain `[ ]`. Step 6.75 currently runs `git status --porcelain`
6
+ # only — catches commit-didn't-land but not commit-landed-with-false-claim.
7
+ # This verifier closes the gap.
8
+ #
9
+ # Contract: `verify-iter-summary.sh` (or PATH shim
10
+ # `wr-itil-verify-iter-summary`) reads:
11
+ # $1 = commit_sha (the iter's landed commit)
12
+ # $2 = path to a file containing the ITERATION_SUMMARY notes field
13
+ # $3 = repo root (optional; defaults to `git rev-parse --show-toplevel`)
14
+ #
15
+ # Mechanism:
16
+ # 1. Extract `ADR-NNN` identifiers from the commit message
17
+ # (`git log -1 --format=%B <sha>`) AND the notes file.
18
+ # 2. For each identifier, resolve to `docs/decisions/<NNN>-*.md` (any
19
+ # status suffix — `.proposed.md` / `.accepted.md` / etc).
20
+ # 3. Detect completion-claim signal in commit message OR notes (regex
21
+ # family: `all .*(green|complete|done|checked|ticked)`,
22
+ # `\([a-z]\)\s*[-–]\s*\([a-z]\)\s+(green|complete|all)`,
23
+ # `all\s+Confirmation\s+items`).
24
+ # 4. When signal present AND any `- [ ]` item exists in the cited ADR's
25
+ # `## Confirmation` section → emit `OVER-CLAIM:` line and exit 1.
26
+ # 5. Otherwise exit 0.
27
+ #
28
+ # Exit codes:
29
+ # 0 = OK (no signal, or signal-and-all-items-checked, or no ADR referenced)
30
+ # 1 = OVER-CLAIM detected
31
+ # 2 = invocation error (missing args, bad sha, etc)
32
+ #
33
+ # @adr ADR-032 (subprocess-boundary trust contract — orchestrator decides
34
+ # trust boundary; verifier is the policy-authorised silent check)
35
+ # @adr ADR-049 (Plugin-bundled scripts ship as bin/ PATH shims;
36
+ # wr-itil-verify-iter-summary is the shim name)
37
+ # @adr ADR-052 (Behavioural tests for skill testing; this bats covers
38
+ # the OVER-CLAIM detection behaviour, not script structure)
39
+ # @jtbd JTBD-006 (Progress the Backlog While I'm Away — orchestrator-side
40
+ # verification keeps AFK loop integrity intact when iter
41
+ # self-certification fails)
42
+
43
+ setup() {
44
+ SCRIPTS_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
45
+ SCRIPT="$SCRIPTS_DIR/verify-iter-summary.sh"
46
+ FIXTURE_DIR="$(mktemp -d)"
47
+ cd "$FIXTURE_DIR"
48
+ git init -q
49
+ git config user.email test@example.com
50
+ git config user.name "Test"
51
+ mkdir -p docs/decisions
52
+ }
53
+
54
+ teardown() {
55
+ cd /
56
+ rm -rf "$FIXTURE_DIR"
57
+ }
58
+
59
+ # Helper: create a fake ADR with the given Confirmation-section body.
60
+ _make_adr() {
61
+ local num="$1" status="$2" confirmation_body="$3"
62
+ cat > "docs/decisions/${num}-fake-adr.${status}.md" <<EOF
63
+ # ${num}. Fake ADR
64
+
65
+ ## Status
66
+ ${status}
67
+
68
+ ## Confirmation
69
+ ${confirmation_body}
70
+ EOF
71
+ }
72
+
73
+ # Helper: commit a file with the given message; return the SHA via stdout.
74
+ _commit_with_message() {
75
+ local message="$1"
76
+ echo "dummy" > dummy.txt
77
+ git add dummy.txt
78
+ git commit -q -m "$message"
79
+ git log -1 --format=%H
80
+ }
81
+
82
+ # ── Existence + executable ──────────────────────────────────────────────────
83
+
84
+ @test "verify-iter-summary: script exists" {
85
+ [ -f "$SCRIPT" ]
86
+ }
87
+
88
+ @test "verify-iter-summary: script is executable" {
89
+ [ -x "$SCRIPT" ]
90
+ }
91
+
92
+ # ── Exit 0: no completion-claim signal ──────────────────────────────────────
93
+
94
+ @test "verify-iter-summary: notes mention ADR but no completion-claim signal → OK" {
95
+ _make_adr 077 proposed "- [ ] **(a) Item A**
96
+ - [ ] **(b) Item B**"
97
+ local sha; sha=$(_commit_with_message "feat(architect): ADR-077 Slice 1 partial work")
98
+ echo "P327 progressed; partial slice landed; further work needed for Confirmation items (a)+(b)." > notes.txt
99
+
100
+ run "$SCRIPT" "$sha" notes.txt "$FIXTURE_DIR"
101
+ [ "$status" -eq 0 ]
102
+ }
103
+
104
+ @test "verify-iter-summary: no ADR referenced at all → OK" {
105
+ local sha; sha=$(_commit_with_message "fix(itil): rename helper variable")
106
+ echo "Bugfix; no governance impact." > notes.txt
107
+
108
+ run "$SCRIPT" "$sha" notes.txt "$FIXTURE_DIR"
109
+ [ "$status" -eq 0 ]
110
+ }
111
+
112
+ # ── Exit 0: signal present but all items checked ────────────────────────────
113
+
114
+ @test "verify-iter-summary: completion-claim signal AND all items checked → OK" {
115
+ _make_adr 077 proposed "- [x] **(a) Item A**
116
+ - [x] **(b) Item B**"
117
+ local sha; sha=$(_commit_with_message "feat(architect): ADR-077 — all Confirmation items complete")
118
+ echo "All ADR-077 Confirmation items green." > notes.txt
119
+
120
+ run "$SCRIPT" "$sha" notes.txt "$FIXTURE_DIR"
121
+ [ "$status" -eq 0 ]
122
+ }
123
+
124
+ # ── Exit 1: P335 witness shape — claim "all green" + unchecked items ────────
125
+
126
+ @test "verify-iter-summary: claim 'all green at source' + unchecked items → OVER-CLAIM" {
127
+ # The P335 session 8 iter 1 witness shape: commit message claims (a)–(j)
128
+ # green; all 10 boxes are `[ ]`.
129
+ _make_adr 077 proposed "- [ ] **(a) Agent prompt amendment**
130
+ - [ ] **(b) Generator script**
131
+ - [ ] **(c) Initial compendium**
132
+ - [ ] **(d) create-adr integration**
133
+ - [ ] **(e) capture-adr integration**
134
+ - [ ] **(f) review-decisions integration**
135
+ - [ ] **(g) CI drift bats**
136
+ - [ ] **(h) Pre-commit hook**
137
+ - [ ] **(i) ADR-031 assertion**
138
+ - [ ] **(j) No silent regression**"
139
+ local sha; sha=$(_commit_with_message "feat(architect): ADR-077 Slice 3 — all (a)-(j) green at source")
140
+ echo "ADR-077 Slice 3 — Confirmation items (a)-(j) all green at source." > notes.txt
141
+
142
+ run "$SCRIPT" "$sha" notes.txt "$FIXTURE_DIR"
143
+ [ "$status" -eq 1 ]
144
+ echo "$output" | grep -q "OVER-CLAIM"
145
+ echo "$output" | grep -q "ADR-077"
146
+ }
147
+
148
+ @test "verify-iter-summary: claim 'all Confirmation items complete' + unchecked → OVER-CLAIM" {
149
+ _make_adr 100 accepted "- [x] **(a) Done**
150
+ - [ ] **(b) Still pending**"
151
+ local sha; sha=$(_commit_with_message "feat: ADR-100 — all Confirmation items complete")
152
+ echo "Implementation finished." > notes.txt
153
+
154
+ run "$SCRIPT" "$sha" notes.txt "$FIXTURE_DIR"
155
+ [ "$status" -eq 1 ]
156
+ echo "$output" | grep -q "OVER-CLAIM"
157
+ }
158
+
159
+ @test "verify-iter-summary: signal only in notes (not commit msg) + unchecked → OVER-CLAIM" {
160
+ _make_adr 200 proposed "- [ ] **(a) Missing**"
161
+ local sha; sha=$(_commit_with_message "feat: ADR-200 progress")
162
+ # Note completion signal lives in notes, not the commit subject.
163
+ echo "All Confirmation items ticked for ADR-200." > notes.txt
164
+
165
+ run "$SCRIPT" "$sha" notes.txt "$FIXTURE_DIR"
166
+ [ "$status" -eq 1 ]
167
+ echo "$output" | grep -q "OVER-CLAIM"
168
+ echo "$output" | grep -q "ADR-200"
169
+ }
170
+
171
+ # ── Invocation errors ───────────────────────────────────────────────────────
172
+
173
+ @test "verify-iter-summary: missing notes file → invocation error" {
174
+ local sha; sha=$(_commit_with_message "init")
175
+ run "$SCRIPT" "$sha" /nonexistent/notes.txt "$FIXTURE_DIR"
176
+ [ "$status" -eq 2 ]
177
+ }
178
+
179
+ @test "verify-iter-summary: missing sha → invocation error" {
180
+ echo "" > notes.txt
181
+ run "$SCRIPT" "" notes.txt "$FIXTURE_DIR"
182
+ [ "$status" -eq 2 ]
183
+ }
184
+
185
+ # ── Multi-ADR case ──────────────────────────────────────────────────────────
186
+
187
+ @test "verify-iter-summary: two ADRs cited — one clean, one over-claim → OVER-CLAIM only on the bad one" {
188
+ _make_adr 050 accepted "- [x] **(a) Clean**"
189
+ _make_adr 060 proposed "- [ ] **(a) Dirty**"
190
+ local sha; sha=$(_commit_with_message "feat: ADR-050 + ADR-060 — all green")
191
+ echo "Both ADRs progressed; all items green." > notes.txt
192
+
193
+ run "$SCRIPT" "$sha" notes.txt "$FIXTURE_DIR"
194
+ [ "$status" -eq 1 ]
195
+ echo "$output" | grep -q "ADR-060"
196
+ }
@@ -0,0 +1,129 @@
1
+ #!/usr/bin/env bash
2
+ # verify-iter-summary.sh — detect ITERATION_SUMMARY over-claim against
3
+ # on-disk ADR Confirmation state.
4
+ #
5
+ # Closes P335: AFK iter subprocess over-claims completion in ITERATION_SUMMARY
6
+ # while on-disk Confirmation `[ ]` boxes remain. Step 6.75 of work-problems
7
+ # dispatches this script between iter completion and Step 7 loop-back.
8
+ #
9
+ # Contract:
10
+ # verify-iter-summary.sh <commit_sha> <notes_file> [<repo_root>]
11
+ #
12
+ # Exit codes:
13
+ # 0 = OK (no completion-claim signal, OR signal but all items checked, OR
14
+ # no ADR referenced)
15
+ # 1 = OVER-CLAIM detected — at least one cited ADR has a completion-claim
16
+ # signal AND unchecked `- [ ]` items in its `## Confirmation`
17
+ # section
18
+ # 2 = invocation error (missing args, missing notes file, bad sha)
19
+ #
20
+ # Per ADR-049, this script is invoked via the PATH shim
21
+ # `wr-itil-verify-iter-summary` from SKILL.md prose — never via the
22
+ # repo-relative `packages/itil/scripts/...` path.
23
+
24
+ set -u
25
+
26
+ commit_sha="${1:-}"
27
+ notes_file="${2:-}"
28
+ repo_root="${3:-}"
29
+
30
+ if [ -z "$commit_sha" ] || [ -z "$notes_file" ]; then
31
+ echo "verify-iter-summary: missing required arg(s); usage: verify-iter-summary.sh <commit_sha> <notes_file> [<repo_root>]" >&2
32
+ exit 2
33
+ fi
34
+
35
+ if [ ! -f "$notes_file" ]; then
36
+ echo "verify-iter-summary: notes_file not found: $notes_file" >&2
37
+ exit 2
38
+ fi
39
+
40
+ if [ -z "$repo_root" ]; then
41
+ repo_root="$(git rev-parse --show-toplevel 2>/dev/null || echo ".")"
42
+ fi
43
+
44
+ # Pull commit message; combine with notes for the full claim surface.
45
+ commit_message="$(git -C "$repo_root" log -1 --format=%B "$commit_sha" 2>/dev/null)"
46
+ if [ -z "$commit_message" ]; then
47
+ echo "verify-iter-summary: could not read commit message for $commit_sha" >&2
48
+ exit 2
49
+ fi
50
+ notes_content="$(cat "$notes_file")"
51
+ combined="$commit_message
52
+ $notes_content"
53
+
54
+ # Extract ADR identifiers (ADR-NNN, 1-4 digit numeric).
55
+ adr_ids="$(echo "$combined" | grep -oE 'ADR-[0-9]{1,4}' | sort -u || true)"
56
+
57
+ if [ -z "$adr_ids" ]; then
58
+ exit 0
59
+ fi
60
+
61
+ # Detect completion-claim signal in the combined claim surface.
62
+ # Patterns (case-insensitive):
63
+ # - "all <something> green|complete|done|checked|ticked"
64
+ # - "every <something> green|complete|done|checked|ticked"
65
+ # - "all (Confirmation|criteria) items <complete|green|done|ticked>"
66
+ # - "(a)-(<letter>) green|complete|all" (the ADR-077 witness shape)
67
+ # - "Confirmation items (a)-(<letter>) all green at source"
68
+ has_signal=0
69
+ if echo "$combined" | grep -qiE '(all|every)[[:space:]]+[^.]{0,80}(green|complete|done|checked|ticked|landed)' ; then
70
+ has_signal=1
71
+ fi
72
+ if [ "$has_signal" -eq 0 ] && echo "$combined" | grep -qiE '\([a-z]\)[[:space:]]*[-–][[:space:]]*\([a-z]\)[[:space:]]+(green|complete|all|done|landed)' ; then
73
+ has_signal=1
74
+ fi
75
+ if [ "$has_signal" -eq 0 ] && echo "$combined" | grep -qiE '(green|complete|done|ticked|checked)[[:space:]]+at[[:space:]]+source' ; then
76
+ has_signal=1
77
+ fi
78
+
79
+ if [ "$has_signal" -eq 0 ]; then
80
+ exit 0
81
+ fi
82
+
83
+ # For each cited ADR, resolve the file path and inspect the Confirmation section.
84
+ over_claim_lines=""
85
+ while IFS= read -r adr_id; do
86
+ [ -z "$adr_id" ] && continue
87
+ # Extract the numeric portion (zero-padded to 3 digits where possible).
88
+ adr_num="${adr_id#ADR-}"
89
+ # Resolve to a file path; the ADR may use any status suffix.
90
+ adr_files="$(find "$repo_root/docs/decisions" -maxdepth 1 -type f \
91
+ \( -name "${adr_num}-*.md" -o -name "$(printf '%03d' "$adr_num" 2>/dev/null)-*.md" \) \
92
+ 2>/dev/null | head -1)"
93
+
94
+ if [ -z "$adr_files" ]; then
95
+ # Cited ADR doesn't exist on disk; this is suspicious but not an
96
+ # over-claim per se. Skip silently — the architect/JTBD review surface
97
+ # catches missing-ADR-reference issues separately.
98
+ continue
99
+ fi
100
+
101
+ adr_file="$adr_files"
102
+
103
+ # Slice out the `## Confirmation` section (between `## Confirmation` and
104
+ # the next `^## ` heading, or EOF).
105
+ confirmation_section="$(awk '
106
+ /^## Confirmation/ { in_section = 1; next }
107
+ in_section && /^## / { in_section = 0 }
108
+ in_section { print }
109
+ ' "$adr_file")"
110
+
111
+ if [ -z "$confirmation_section" ]; then
112
+ continue
113
+ fi
114
+
115
+ # Count unchecked items: leading `- [ ]` markers.
116
+ unchecked_count="$(echo "$confirmation_section" | grep -cE '^- \[ \]' || true)"
117
+
118
+ if [ "$unchecked_count" -gt 0 ]; then
119
+ over_claim_lines="${over_claim_lines}OVER-CLAIM: $adr_id has $unchecked_count unchecked Confirmation item(s) at $adr_file but iter claim language signals completion
120
+ "
121
+ fi
122
+ done <<< "$adr_ids"
123
+
124
+ if [ -n "$over_claim_lines" ]; then
125
+ printf '%s' "$over_claim_lines"
126
+ exit 1
127
+ fi
128
+
129
+ exit 0
@@ -726,6 +726,19 @@ Before spawning the next iteration's subagent, verify the working tree state aga
726
726
 
727
727
  **Out of scope for this step**: attempting recovery from an unknown-reason dirty state. Per ADR-013 Rule 6, conflict resolution and ambiguous state require user input; non-interactive recovery would mask the bug this check is meant to surface.
728
728
 
729
+ **Verify-iter-claims sub-step (P335).** The clean/dirty-known/dirty-unknown classification catches the *commit-didn't-land* failure class but not the *commit-landed-with-false-claim* class — both the commit message and the `ITERATION_SUMMARY.notes` field are written by the same iter subprocess from the same model state, so they can agree with each other while disagreeing with the on-disk artefacts the claim names (the P335 session 8 iter 1 witness: commit message stated "all (a)–(j) Confirmation items green at source" + notes restated it + the cited ADR's 10 boxes were all `[ ]`). When the classification above returns Clean AND the iter reported `committed: true`, run the verify-iter-claims check:
730
+
731
+ 1. Dump the iter's `ITERATION_SUMMARY.notes` field to a temp file (`/tmp/iter-notes-$$.txt`).
732
+ 2. Invoke `wr-itil-verify-iter-summary <commit_sha> <notes_file>` (the PATH shim per ADR-049; never invoke the repo-relative `packages/itil/scripts/verify-iter-summary.sh` path from SKILL prose — adopter installs resolve the shim, not the source-monorepo path).
733
+ 3. Read the exit code:
734
+ - **Exit 0** → no over-claim detected (no ADR referenced, OR no completion-claim signal, OR signal-and-all-Confirmation-items-checked). Proceed to Step 7.
735
+ - **Exit 1** → OVER-CLAIM detected (at least one cited ADR has unchecked `- [ ]` Confirmation items while the iter's commit message or notes contains completion-claim language like "all green at source", "all Confirmation items complete", "(a)-(j) green"). **Halt the loop** with `outcome: halted-iter-over-claim`. Include the verifier's stdout (the `OVER-CLAIM: ADR-NNN has N unchecked Confirmation item(s)...` lines) as the divergence detail in the halt summary. Route through Step 2.5b's surfacing routine before emitting the halt summary (`halt-paths-must-route-design-questions-through-Step-2.5b`); the over-claim halt itself remains a halt-with-bug-signal — the iter's self-contradicting output IS the bug, and the user must adjudicate on return (re-dispatch the work / accept partial state / amend the commit).
736
+ - **Exit 2** → verifier invocation error (missing args, unreadable notes file, bad sha). Halt the loop with `outcome: halted-iter-verifier-error` and the verifier's stderr. This shape is itself an orchestrator-side bug; surfacing it loudly is preferable to silently proceeding.
737
+
738
+ **Detection class boundary.** Verify-iter-claims is the *emit-but-over-claim* class detector — distinct from the *stuck-before-emit* class (P147, exit 143 + 0-byte JSON) which is already covered by the Step 5 idle-timeout SIGTERM handling + this step's existing dirty/clean check (working tree dirty after a missing-summary iter halts the loop). The verifier is intentionally narrow (ADR `## Confirmation` checkboxes) — it catches the load-bearing recurring shape where an iter ships an invariant gate (CI drift, README pairing) in the same commit as the work the gate is meant to test. Other over-claim shapes (claimed commits with no diff hunks; claimed file edits not in `git show --stat`) can be added incrementally as further witnesses surface; option (d) iter-local drift-bats (running the verifier inside the iter subprocess before `ITERATION_SUMMARY` emission) is deferred pending evidence that orchestrator-side (a) is insufficient — evidence-based, not BUFD (same shape as P246/P247).
739
+
740
+ **Auto-correction is out of scope.** The orchestrator cannot retroactively make a false claim true; halt-with-bug-signal is the correct stance per ADR-013 Rule 6.
741
+
729
742
  ### Step 7: Loop
730
743
 
731
744
  Go back to step 1. The backlog may have changed — new problems may have been created during fixes, priorities may have shifted, and the README.md cache will be stale.
@@ -758,6 +771,7 @@ When `AskUserQuestion` is unavailable or the user is AFK, the skill (and the del
758
771
  | Pre-`ALL_DONE` gate sequence at any loop end (every stop-condition + every halt-path that emits a final summary + quota-exhaustion natural end) | Run Step 2.4 sequence UNCONDITIONALLY before `ALL_DONE` emit: gate (a) outstanding-questions surface via Step 2.5b; gate (b) session-level retro via `/wr-retrospective:run-retro`; gate (c) emit `ALL_DONE` only after (a) AND (b) complete. Hard-fail mode: if either gate cannot complete cleanly, halt with directive instead of emit `ALL_DONE` — recovery is the user satisfying the gate and re-invoking the skill. Per ADR-044 framework-resolution boundary + ADR-013 + ADR-014 (retro commits its own work) + P086 (extends iter-level retro to orchestrator-level) + P341 (Step 2.4). |
759
772
  | Halt-path final summary with accumulated user-answerable skips (CI failure / Rule 5 above-appetite / dirty-unknown / session-continuity / fetch failure) | Run Step 2.5b's surfacing routine before emitting the halt path's final AFK summary. Step 2.5b is gated on ≥1 accumulated user-answerable skip — empty-skip halts skip the routine. Step 2.5b surfaces *prior-iter accumulated user-answerable skips only*; it does NOT ask the user how to remediate the halt cause itself (CI failure / above-appetite state / dirty-unknown state remain halt-with-bug-signal). Per ADR-013 Rule 1 + ADR-032 + P126 (`halt-paths-must-route-design-questions-through-Step-2.5b`). |
760
773
  | 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). Run Step 2.5b before emitting the halt summary if ≥1 accumulated user-answerable skip from prior iters (P126). Do NOT attempt non-interactive recovery of the dirty state itself. |
774
+ | Iter committed cleanly + claim contradicts on-disk ADR Confirmation state (P335) | Halt the loop with `outcome: halted-iter-over-claim`. Include the `wr-itil-verify-iter-summary` stdout (the `OVER-CLAIM: ADR-NNN has N unchecked Confirmation item(s)...` lines) as the divergence detail. Run Step 2.5b before emitting the halt summary if ≥1 accumulated user-answerable skip from prior iters. Do NOT auto-correct the iter's claim — the orchestrator cannot retroactively make a false claim true; the user adjudicates on return (re-dispatch / accept partial / amend). Per ADR-013 Rule 6 + ADR-032 subprocess-boundary trust contract + P335 (Step 6.75 verify-iter-claims sub-step). |
761
775
  | 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. |
762
776
  | Mid-loop ask between iters in the orchestrator's main turn | Forbidden except at framework-prescribed halt points (Step 0 session-continuity / fetch-failure halt; Step 2.5 / 2.5b loop-end emit; Step 6.5 above-appetite Rule 5 halt; Step 6.5 CI-failure / release:watch halt; Step 6.5 cohort-graduation halt-no-resolution halt; Step 6.75 dirty-for-unknown-reason halt). The loop's purpose is **progress + accumulation**; mechanical-stage transitions between iters are framework-resolved and MUST NOT prompt the user. Per ADR-044 framework-resolution boundary + ADR-013 Rule 1 (as amended by ADR-044) + P130. |
763
777
 
@@ -774,6 +788,7 @@ The orchestrator MUST NOT call `AskUserQuestion` between iterations except at th
774
788
  - **Step 6.5 CI-failure / `release:watch` failure halt** — push:watch or release:watch failed AND the failure is genuinely-unrecoverable (outside the fixable-in-iter allow-list, or 3-retry cap reached); halt-with-batched-questions per the Step 2.5b cross-reference. Failures inside the closed allow-list route to fix-and-continue per Step 6.5 Failure handling (P140), not this halt point.
775
789
  - **Step 6.5 cohort-graduation halt-no-resolution halt (P246)** — graduation evaluator returned `status=halt-no-resolution` for one or more held candidates (Rule 1a terminal: neither filename-convention join nor body-grep fallback resolved a problem ticket, OR the resolved ticket file is missing/unreadable). The orchestrator MUST NOT auto-graduate under ambiguity per ADR-061 Rule 1a; halt-with-batched-questions per the Step 2.5b cross-reference. The halt-causing ambiguity itself remains a halt-with-bug-signal (the held entry stays in `docs/changesets-holding/`; manual reinstate or ticket-file correction required); Step 2.5b surfaces *prior-iter accumulated user-answerable skips only* and does NOT ask the user to resolve the ambiguity itself.
776
790
  - **Step 6.75 dirty-for-unknown-reason halt** — `git status --porcelain` divergence; halt-with-batched-questions per the Step 2.5b cross-reference.
791
+ - **Step 6.75 iter-over-claim halt (P335)** — `wr-itil-verify-iter-summary` detected the iter's commit message or `ITERATION_SUMMARY.notes` contains completion-claim language for an ADR whose `## Confirmation` section still has unchecked `- [ ]` items; halt-with-batched-questions per the Step 2.5b cross-reference. The over-claim itself remains a halt-with-bug-signal — Step 2.5b surfaces *prior-iter accumulated user-answerable skips only*; it does NOT ask the user how to remediate the false claim (re-dispatch / accept partial / amend the commit remains a user decision on return).
777
792
 
778
793
  **No mid-iter ask points.** Every other point in the orchestrator's main turn (between Step 5 dispatch completing and Step 6.5 release-cadence check; between Step 6.75 verification and Step 7 loop-back; between Step 7 and Step 1 next-iteration; between consecutive iters generally) is a mechanical-stage transition that the framework has already resolved. Do NOT introduce ad-hoc `AskUserQuestion` calls at those points to confirm "is it OK to proceed?" or "want me to start the next iter?" — proceeding IS the framework-resolved default. Continue iterating until quota or stop-condition #1/#2/#3 fires.
779
794