@windyroad/itil 0.30.4 → 0.31.0-preview.323
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
|
@@ -555,6 +555,18 @@ After the iteration's commit lands but before starting the next iteration, check
|
|
|
555
555
|
1. Run `npm run push:watch` (push + wait for CI to pass).
|
|
556
556
|
2. If `.changeset/` is non-empty after push, run `npm run release:watch` (merge the release PR + wait for npm publish).
|
|
557
557
|
3. Resume the loop only after the release lands on npm.
|
|
558
|
+
4. **Post-release cache refresh (P233)**: if step 2 actually ran AND succeeded (a release shipped to npm), chain `/install-updates` to refresh the plugin cache before the next iter dispatches. Skipped when step 2 was a no-op (empty `.changeset/` after push; no new plugin version exists). See the **Post-release cache refresh** subsection below for the full contract.
|
|
559
|
+
|
|
560
|
+
**Post-release cache refresh (P233) — fires only after within-appetite Drain action step 4 (above):**
|
|
561
|
+
|
|
562
|
+
After a successful release-cadence drain has shipped a new plugin version to npm, the orchestrator chains `/install-updates` to refresh the plugin cache before the next iter dispatches. Empirical evidence in `docs/briefing/afk-subprocess.md` ("Just-shipped gate-class hooks DON'T protect the immediate-next iter" entry) confirms iter subprocesses re-resolve plugin cache on spawn — so a just-shipped gate-class hook is inactive in the next iter unless the cache is refreshed first. The orchestrator IS the "restart" boundary for the next iter subprocess (each subprocess is a fresh `claude -p` per ADR-032 + `afk-subprocess-mechanics.md`); the cache refresh between release:watch and next-iter dispatch is the load-bearing step.
|
|
563
|
+
|
|
564
|
+
- **Conditional on actual release**: only fires when `release:watch` actually published (step 2 of the Drain action above ran AND returned success). Skipped when `push:watch` ran alone (empty `.changeset/`; no new plugin version). Without this guard, every iter burns wall-clock + npm-API noise on a no-op cache refresh.
|
|
565
|
+
- **Non-blocking on /install-updates failure**: if `/install-updates` fails (transient marketplace fetch error, P106-class quirk re-emergence, cache-miss + Non-interactive fallback dry-run), the orchestrator logs the failure and continues the loop. Degrades to current behaviour — cache stays stale; next iter may recur the just-shipped issue, equivalent to pre-amendment behaviour. The cache-refresh chain MUST NOT halt the loop on `/install-updates` failure under any circumstance.
|
|
566
|
+
- **Policy authorisation (ADR-013 Rule 5)**: rides the same Rule 5 silent-proceed that already covers `push:watch` / `release:watch` in the drain — the post-release cache refresh is mechanically downstream of release and shares its authorisation. Composes with P106's claude-plugin-install no-op-when-already-installed factor (the chained `/install-updates` handles the uninstall+install dance per P106).
|
|
567
|
+
- **Mid-loop ask discipline (P130) preserved**: if `/install-updates` Step 5b/5c consent gate fires (cache miss / scope delta / `INSTALL_UPDATES_RECONFIRM=1`), the orchestrator main turn treats this AS the **Non-interactive fallback** documented in `scripts/repo-local-skills/install-updates/SKILL.md` "Non-interactive fallback" subsection — log the dry-run output, do not interrupt the loop. The orchestrator's `.claude/.install-updates-consent` is normally present (install-updates Step 5a cache hit) so the gate fires silently. **ADR-044 framework-resolution boundary** authorises this AskUserQuestion-available-but-forbidden routing: invocation between iters is a mechanical-stage transition the framework has resolved; surfacing it to the user would dilute the Step 2.5b accumulated-question discipline.
|
|
568
|
+
|
|
569
|
+
**Composition with the Above-appetite branch (below)**: the cache refresh is anchored to the within-appetite Drain action step 4 — it does NOT fire after the above-appetite Rule 5 halt (no release shipped → nothing to refresh) and it does NOT fire mid-loop in the above-appetite auto-apply loop. When the auto-apply loop converges and re-enters the within-appetite Drain action, the cache refresh fires there per step 4. The chain's site is the Drain action only.
|
|
558
570
|
|
|
559
571
|
**Failure handling (P140)**: When `push:watch` or `release:watch` reports a CI failure or publish failure, the orchestrator follows a diagnose-then-classify routing — fix-and-continue for the documented mechanically-fixable allow-list, halt for everything else. The previous uniform halt rule converted mechanically-fixable failures (1-line stale-grep-string updates, transient flakes) into ~45min queue stalls, regressing JTBD-006 "Progress the Backlog While I'm Away" without any governance benefit.
|
|
560
572
|
|
|
@@ -665,6 +677,7 @@ When `AskUserQuestion` is unavailable or the user is AFK, the skill (and the del
|
|
|
665
677
|
| Commit when risk within appetite | Auto-commit (manage-problem step 9e fallback) |
|
|
666
678
|
| Commit when risk above appetite | Skip commit, report uncommitted state |
|
|
667
679
|
| Pipeline risk at appetite (push or release = 4/25) | Drain release queue (`push:watch` then `release:watch`) before next iteration — per ADR-018 (Step 6.5) |
|
|
680
|
+
| Post-release plugin cache refresh between iters (P233) | After a successful within-appetite Drain action shipped a release to npm, chain `/install-updates` to refresh the plugin cache before the next iter dispatches. Conditional on actual release (skipped when `push:watch` ran alone with no changeset); non-blocking on `/install-updates` failure (degrades to cache-stays-stale, equivalent to pre-amendment behaviour). Mid-loop ask discipline preserved by treating any `/install-updates` AskUserQuestion surface AS the Non-interactive fallback dry-run path. Per ADR-013 Rule 5 + ADR-044 + P130 + P106 + P233 (Step 6.5 Post-release cache refresh subsection). |
|
|
668
681
|
| CI failure during Step 6.5 drain (within-appetite branch) | Diagnose via `gh run view --log-failed`, classify against the closed fixable-in-iter allow-list (P081-class stale-grep-string, hook stub mismatch, test ID drift, environmental flake), fix-and-continue for fixable classes (each retry rides its own ADR-014 commit gate), 3-retry cap per iteration, halt for unrecoverable classes. Ambiguous classification defaults to halt. ADR-013 Rule 5 policy-authorised. Per ADR-026 grounding + ADR-044 framework-resolution boundary + P140 (Step 6.5 Failure handling). |
|
|
669
682
|
| Pipeline risk above appetite (push or release >= 5/25) | Auto-apply scorer remediations incrementally (ADR-042 Rule 2). The agent reads suggestions and decides what to do. Re-score after each apply; drain when within appetite. **Never release above appetite** (ADR-042 Rule 1) — no AskUserQuestion shortcut. Halt the loop with `outcome: halted-above-appetite` if the loop exhausts without convergence (ADR-042 Rule 5). Verification Pending commits excluded from auto-revert (Rule 2b). Per ADR-042 (Step 6.5 Above-appetite branch). |
|
|
670
683
|
| 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) |
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
#!/usr/bin/env bats
|
|
2
|
+
|
|
3
|
+
# P233: /wr-itil:work-problems Step 6.5 Drain action must chain
|
|
4
|
+
# /install-updates AFTER successful release:watch so the next iter
|
|
5
|
+
# subprocess loads the just-shipped plugin from cache rather than the
|
|
6
|
+
# pre-release cached version.
|
|
7
|
+
#
|
|
8
|
+
# Empirical driver (briefing/afk-subprocess.md:18): iter subprocesses
|
|
9
|
+
# re-resolve plugin cache on spawn; without cache refresh between
|
|
10
|
+
# release:watch and next-iter dispatch, the just-shipped hook is
|
|
11
|
+
# inactive in the next iter — defeating the "ship a hook to prevent
|
|
12
|
+
# recurrence" pattern for the immediate-next-iter case.
|
|
13
|
+
#
|
|
14
|
+
# Doc-lint contract assertions per ADR-037 Permitted Exception
|
|
15
|
+
# (contract-assertion class — same shape as the P140 / P130 / P126 / P135
|
|
16
|
+
# sibling fixtures). The asserted prose IS the load-bearing policy
|
|
17
|
+
# surface — the chained invocation is documentation-only (the orchestrator
|
|
18
|
+
# is a prose-driven agent, not a script); the SKILL.md is the contract.
|
|
19
|
+
# Behavioural assertion would require a fixture project + real claude -p
|
|
20
|
+
# subprocess that observes a freshly-installed plugin — outside scope.
|
|
21
|
+
#
|
|
22
|
+
# @problem P233
|
|
23
|
+
# @adr ADR-013 (Rule 5 — policy-authorised silent action; chains the
|
|
24
|
+
# same authorisation that covers push:watch / release:watch)
|
|
25
|
+
# @adr ADR-014 (one-commit-per-iter; this edit lands in one commit)
|
|
26
|
+
# @adr ADR-018 (inter-iteration release cadence; this refines its
|
|
27
|
+
# Drain action sub-block with the post-release cache refresh)
|
|
28
|
+
# @adr ADR-030 (repo-local skills — install-updates is the chained
|
|
29
|
+
# skill)
|
|
30
|
+
# @adr ADR-037 (skill-testing strategy — contract-assertion class)
|
|
31
|
+
# @adr ADR-044 (decision-delegation contract — framework-resolution
|
|
32
|
+
# boundary; install-updates' AskUserQuestion-bearing branches
|
|
33
|
+
# fall through to its Non-interactive fallback under P130)
|
|
34
|
+
# @jtbd JTBD-006 (Progress the Backlog While I'm Away — primary;
|
|
35
|
+
# outcome 7 "risk never silently accumulates across AFK iterations"
|
|
36
|
+
# extends to "just-shipped hooks effective on next iter")
|
|
37
|
+
# @jtbd JTBD-001 (Enforce Governance Without Slowing Down — composes;
|
|
38
|
+
# just-shipped governance hooks become effective immediately,
|
|
39
|
+
# not after manual /install-updates re-run)
|
|
40
|
+
# @jtbd JTBD-007 (Keep Plugins Current Across Projects — persona-level
|
|
41
|
+
# currency anchor that JTBD-006's AFK use case extends)
|
|
42
|
+
|
|
43
|
+
setup() {
|
|
44
|
+
REPO_ROOT="$(cd "$(dirname "$BATS_TEST_FILENAME")/../../../../.." && pwd)"
|
|
45
|
+
SKILL_MD="$REPO_ROOT/packages/itil/skills/work-problems/SKILL.md"
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
@test "work-problems P233: SKILL.md exists" {
|
|
49
|
+
[ -f "$SKILL_MD" ]
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
# ── Cache-refresh chain identity ───────────────────────────────────────────
|
|
53
|
+
|
|
54
|
+
@test "work-problems P233: Step 6.5 Drain action carries a post-release cache-refresh subsection citing P233" {
|
|
55
|
+
# The amendment must self-identify so future readers tracing back from
|
|
56
|
+
# the ticket find the load-bearing prose without keyword-guessing.
|
|
57
|
+
run grep -nE 'cache.refresh.*P233|P233.*cache.refresh|post.release.cache.*P233|P233.*post.release.cache' "$SKILL_MD"
|
|
58
|
+
[ "$status" -eq 0 ]
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@test "work-problems P233: Drain action chains /install-updates after successful release:watch" {
|
|
62
|
+
# Core contract: after release:watch returns success, the orchestrator
|
|
63
|
+
# invokes /install-updates to refresh the plugin cache. Without this
|
|
64
|
+
# chain, the next iter subprocess loads the pre-release cached version
|
|
65
|
+
# (P233's empirical root cause).
|
|
66
|
+
run grep -nE '/install-updates|install-updates skill' "$SKILL_MD"
|
|
67
|
+
[ "$status" -eq 0 ]
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
@test "work-problems P233: cache-refresh is conditional on actual release (skipped when no changeset)" {
|
|
71
|
+
# The chain MUST NOT fire when release:watch was a no-op (empty
|
|
72
|
+
# .changeset/ after push). No new plugin version exists → nothing to
|
|
73
|
+
# refresh. Without this guard, the orchestrator burns wall-clock and
|
|
74
|
+
# noise on a no-op /install-updates invocation every iter.
|
|
75
|
+
run grep -niE 'only.*release.*actually|when.*release.*shipped|skip.*when.*no.changeset|conditional on.*release' "$SKILL_MD"
|
|
76
|
+
[ "$status" -eq 0 ]
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@test "work-problems P233: cache-refresh is non-blocking on /install-updates failure" {
|
|
80
|
+
# If /install-updates fails (cache miss + non-interactive fallback,
|
|
81
|
+
# marketplace fetch error, transient flake), the orchestrator MUST NOT
|
|
82
|
+
# halt the loop. Degrades to current behaviour — cache stays stale;
|
|
83
|
+
# equivalent to pre-amendment behaviour. Loop continues.
|
|
84
|
+
run grep -niE 'non.blocking.*install.updates|install.updates.*non.blocking|do not halt.*install.updates|install.updates.*failure.*continue' "$SKILL_MD"
|
|
85
|
+
[ "$status" -eq 0 ]
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
# ── Empirical evidence citation ────────────────────────────────────────────
|
|
89
|
+
|
|
90
|
+
@test "work-problems P233: cache-refresh subsection cites briefing/afk-subprocess.md evidence" {
|
|
91
|
+
# The architect FLAG resolution required the evidence that subprocesses
|
|
92
|
+
# re-resolve cache on spawn (rather than inherit parent-resolved
|
|
93
|
+
# plugins). The briefing entry is dispositive — cite it inline so
|
|
94
|
+
# future readers don't re-litigate the question.
|
|
95
|
+
run grep -nE 'afk-subprocess|briefing.*subprocess.*cache' "$SKILL_MD"
|
|
96
|
+
[ "$status" -eq 0 ]
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
# ── ADR-013 Rule 5 policy authorisation ────────────────────────────────────
|
|
100
|
+
|
|
101
|
+
@test "work-problems P233: cache-refresh chain rides ADR-013 Rule 5 (same authorisation as push:watch / release:watch)" {
|
|
102
|
+
# The chain MUST be silent — invocation between iters is a mechanical
|
|
103
|
+
# post-release step the framework has resolved. Same ADR-013 Rule 5
|
|
104
|
+
# citation already covers push:watch / release:watch in the within-
|
|
105
|
+
# appetite drain; the cache-refresh extends the same authorisation.
|
|
106
|
+
run grep -nE 'ADR-013 Rule 5|Rule 5 policy-authorised|policy-authorised.*ADR-013' "$SKILL_MD"
|
|
107
|
+
[ "$status" -eq 0 ]
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
# ── Mid-loop ask discipline preservation (P130) ────────────────────────────
|
|
111
|
+
|
|
112
|
+
@test "work-problems P233: cache-refresh prose cites install-updates Non-interactive fallback for AskUserQuestion routing" {
|
|
113
|
+
# If install-updates' Step 5b/5c consent gate fires (cache miss /
|
|
114
|
+
# scope delta / INSTALL_UPDATES_RECONFIRM=1), the orchestrator main
|
|
115
|
+
# turn MUST NOT surface AskUserQuestion mid-loop per P130. Cite the
|
|
116
|
+
# install-updates Non-interactive fallback as the routing.
|
|
117
|
+
run grep -niE 'Non.interactive fallback|non-interactive fallback' "$SKILL_MD"
|
|
118
|
+
[ "$status" -eq 0 ]
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
@test "work-problems P233: cache-refresh prose cites ADR-044 framework-resolution boundary for AskUserQuestion-available-but-forbidden routing" {
|
|
122
|
+
# Architect advisory: cite ADR-044 alongside the Non-interactive
|
|
123
|
+
# fallback ref so future readers can trace the "AskUserQuestion-
|
|
124
|
+
# available-but-forbidden" reasoning back to the framework-resolution
|
|
125
|
+
# boundary — not just the install-updates-side dry-run mechanic.
|
|
126
|
+
run grep -nE 'ADR-044' "$SKILL_MD"
|
|
127
|
+
[ "$status" -eq 0 ]
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
# ── Composition with above-appetite branch ─────────────────────────────────
|
|
131
|
+
|
|
132
|
+
@test "work-problems P233: cache-refresh fires only after within-appetite Drain action (not after above-appetite Rule 5 halt)" {
|
|
133
|
+
# Above-appetite Rule 5 halt terminates without a release; no cache
|
|
134
|
+
# refresh fires. Within-appetite convergence loops back to Drain
|
|
135
|
+
# action; cache refresh fires there. The prose must not place the
|
|
136
|
+
# chain inside the above-appetite branch.
|
|
137
|
+
run grep -niE 'within.appetite.*drain.*cache|cache.refresh.*within.appetite|after.*drain.*action' "$SKILL_MD"
|
|
138
|
+
[ "$status" -eq 0 ]
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
# ── Non-Interactive Decision Making table row ──────────────────────────────
|
|
142
|
+
|
|
143
|
+
@test "work-problems P233: Decision Making table carries a post-release cache-refresh row" {
|
|
144
|
+
# The decision table is the AFK reader's quick-reference; without a
|
|
145
|
+
# row here the cache-refresh chain is buried in Step 6.5.
|
|
146
|
+
run grep -nE '\|.*[Pp]ost.release cache|\|.*[Cc]ache refresh|\|.*[Pp]lugin cache refresh' "$SKILL_MD"
|
|
147
|
+
[ "$status" -eq 0 ]
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
@test "work-problems P233: Decision Making table row cites P233" {
|
|
151
|
+
# Per ADR-037 doc-lint pattern + existing P140 / P126 / P135 sibling
|
|
152
|
+
# rows — every Decision Making table row that documents a P-driven
|
|
153
|
+
# refinement cites the driver ticket.
|
|
154
|
+
run grep -nE '\|.*cache refresh.*P233|\|.*P233.*cache refresh|\|.*post.release.*P233|\|.*P233.*post.release' "$SKILL_MD"
|
|
155
|
+
[ "$status" -eq 0 ]
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
# ── Composition cross-references ───────────────────────────────────────────
|
|
159
|
+
|
|
160
|
+
@test "work-problems P233: cache-refresh prose cross-references P106 (claude plugin install no-op-when-already-installed)" {
|
|
161
|
+
# P106 is the compounding factor that makes /install-updates' explicit
|
|
162
|
+
# uninstall + install dance necessary (vs. naive claude plugin
|
|
163
|
+
# install which silent-no-ops). Cite it so future readers don't try
|
|
164
|
+
# to simplify the chain.
|
|
165
|
+
run grep -nE 'P106' "$SKILL_MD"
|
|
166
|
+
[ "$status" -eq 0 ]
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
@test "work-problems P233: cache-refresh prose cross-references P130 (orchestrator main-turn ask discipline preserved)" {
|
|
170
|
+
# P130 is the constraint the Non-interactive fallback routing exists
|
|
171
|
+
# to satisfy. Citation makes the dependency auditable.
|
|
172
|
+
run grep -nE 'P130' "$SKILL_MD"
|
|
173
|
+
[ "$status" -eq 0 ]
|
|
174
|
+
}
|