@windyroad/itil 0.7.0-preview.120 → 0.7.1-preview.122
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.
package/package.json
CHANGED
|
@@ -169,6 +169,25 @@ After the iteration's commit lands but before starting the next iteration, check
|
|
|
169
169
|
|
|
170
170
|
`push:watch` and `release:watch` are policy-authorised actions when residual risk is within appetite per RISK-POLICY.md, so no `AskUserQuestion` is required for the drain itself (ADR-013 Rule 6).
|
|
171
171
|
|
|
172
|
+
### Step 6.75: Inter-iteration verification (P036)
|
|
173
|
+
|
|
174
|
+
Before spawning the next iteration's subagent, verify the working tree state against the expected outcome of the iteration that just completed. This is defence-in-depth: P035 closed the most-likely commit-gate failure path, but a subagent could still fail to commit for reasons the fallback does not cover (a failure inside `/wr-risk-scorer:assess-release`, a git conflict, a malformed commit message). Without this check, silent failures accumulate across iterations and the final summary reports commits that did not land.
|
|
175
|
+
|
|
176
|
+
**Mechanism:**
|
|
177
|
+
|
|
178
|
+
1. Run `git status --porcelain`.
|
|
179
|
+
2. Classify the output into one of three cases:
|
|
180
|
+
|
|
181
|
+
| Status | Expected when | Action |
|
|
182
|
+
|---|---|---|
|
|
183
|
+
| Clean (empty output) | The subagent committed successfully (the default happy path) | Proceed to Step 7 |
|
|
184
|
+
| Dirty for a known reason | A deliberate hand-off to the next iteration (e.g. the subagent chose to skip the commit and report "uncommitted state" because risk was above appetite — per the Non-Interactive Decision Making table above). Reason MUST be stated in the iteration report. | Include the dirty state in the next iteration's subagent context and proceed to Step 7 |
|
|
185
|
+
| Dirty for an unknown reason | Neither of the above — the subagent reported success but the tree is not clean, or the tree is dirty without a documented reason in the iteration report | **Halt the loop.** Report the `git status --porcelain` output, the last subagent's reported outcome, and the divergence. Do NOT spawn the next iteration. |
|
|
186
|
+
|
|
187
|
+
**Rationale**: the orchestrator previously treated the subagent's reported outcome as truth. Any lie, partial write, or silent failure in the subagent propagated into the summary. The `git status --porcelain` check is the cheapest possible independent verification — policy-authorised, no network, no judgement required — and it catches exactly the class of failure the subagent cannot self-report.
|
|
188
|
+
|
|
189
|
+
**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.
|
|
190
|
+
|
|
172
191
|
### Step 7: Loop
|
|
173
192
|
|
|
174
193
|
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.
|
|
@@ -188,6 +207,7 @@ When `AskUserQuestion` is unavailable or the user is AFK, the skill (and the del
|
|
|
188
207
|
| 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) |
|
|
189
208
|
| Fix verification needed | Skip problem, add to "needs verification" list |
|
|
190
209
|
| 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). |
|
|
210
|
+
| 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. |
|
|
191
211
|
|
|
192
212
|
## Edge Cases
|
|
193
213
|
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
#!/usr/bin/env bats
|
|
2
|
+
# Doc-lint guard: work-problems SKILL.md must include an inter-iteration
|
|
3
|
+
# verification check (P036). After each subagent returns, the orchestrator
|
|
4
|
+
# must verify via `git status --porcelain` that the tree is clean (or
|
|
5
|
+
# dirty for a known deliberate reason) before spawning the next iteration.
|
|
6
|
+
#
|
|
7
|
+
# Structural assertion — Permitted Exception to the source-grep ban
|
|
8
|
+
# (ADR-005 / P011). Asserts the skill specification document contains the
|
|
9
|
+
# inter-iteration check so a silent subagent commit failure cannot
|
|
10
|
+
# compound across iterations.
|
|
11
|
+
#
|
|
12
|
+
# Cross-reference:
|
|
13
|
+
# P036 (work-problems orchestrator does not verify commit-landing between iterations)
|
|
14
|
+
# P035 (commit-gate fallback, the primary mitigation this backstops)
|
|
15
|
+
# @jtbd JTBD-006 (progress the backlog while I'm away)
|
|
16
|
+
|
|
17
|
+
setup() {
|
|
18
|
+
SKILL_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
|
|
19
|
+
SKILL_FILE="${SKILL_DIR}/SKILL.md"
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
@test "SKILL.md cites P036 (inter-iteration verification)" {
|
|
23
|
+
run grep -n "P036" "$SKILL_FILE"
|
|
24
|
+
[ "$status" -eq 0 ]
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@test "SKILL.md has an inter-iteration verification step (after commit, before next iteration)" {
|
|
28
|
+
# The step should appear between the commit/release-cadence step and
|
|
29
|
+
# the "Step 7: Loop" section, with a recognisable heading.
|
|
30
|
+
run grep -niE "inter-iteration verification|verif.*iteration|post-iteration verif" "$SKILL_FILE"
|
|
31
|
+
[ "$status" -eq 0 ]
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@test "SKILL.md inter-iteration check uses git status --porcelain" {
|
|
35
|
+
run grep -n "git status --porcelain" "$SKILL_FILE"
|
|
36
|
+
[ "$status" -eq 0 ]
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@test "SKILL.md inter-iteration check halts the loop on unexpected dirty state" {
|
|
40
|
+
# Must describe halting / stopping when the tree is dirty without a
|
|
41
|
+
# known-deliberate reason.
|
|
42
|
+
run grep -niE "halt|stop the loop|dirty.*(halt|stop|block)|uncommitted.*(halt|stop|block|detected)" "$SKILL_FILE"
|
|
43
|
+
[ "$status" -eq 0 ]
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@test "SKILL.md inter-iteration check distinguishes clean tree from deliberate dirty state" {
|
|
47
|
+
# Not all dirty states are errors — e.g. a governance doc transition
|
|
48
|
+
# the subagent deliberately left for the next iteration to pick up.
|
|
49
|
+
# The check should permit a documented dirty state and halt on an
|
|
50
|
+
# undocumented one.
|
|
51
|
+
run grep -niE "deliberate|known reason|expected|documented.*dirty|known.*dirty" "$SKILL_FILE"
|
|
52
|
+
[ "$status" -eq 0 ]
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@test "SKILL.md Non-Interactive Decision Making table covers unexpected dirty state" {
|
|
56
|
+
# AFK mode: inter-iteration dirty state should have a default action.
|
|
57
|
+
run grep -niE "inter[- ]iteration|unexpected dirty" "$SKILL_FILE"
|
|
58
|
+
[ "$status" -eq 0 ]
|
|
59
|
+
}
|