@windyroad/itil 0.47.7-preview.546 → 0.47.8-preview.548
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
|
@@ -64,7 +64,7 @@ After the fetch/divergence check, Step 0 MUST run a session-continuity detection
|
|
|
64
64
|
|---|---|
|
|
65
65
|
| Untracked `docs/decisions/*.proposed.md` | `git status --porcelain docs/decisions/` filtered for `??` entries ending `.proposed.md` — drafted but unlanded ADRs from a prior iter. |
|
|
66
66
|
| Untracked `docs/problems/*.md` | `git status --porcelain docs/problems/` filtered for `??` entries ending `.md` — drafted but unlanded problem tickets. |
|
|
67
|
-
| `.afk-run-state/iter-*.json` error markers | Files under `.afk-run-state/` containing `"is_error": true` OR `"api_error_status" >= 400` —
|
|
67
|
+
| `.afk-run-state/iter-*.json` error markers | Files under `.afk-run-state/` containing `"is_error": true` OR `"api_error_status" >= 400` AND **fresh per the staleness filter** — file mtime is newer than HEAD's commit time (`git log -1 --format=%at HEAD`) OR within the last 24h, whichever is more permissive. Stale residuals (mtime older than HEAD's commit time AND older than 24h) are skipped silently — they represent prior-session partial work whose load-bearing trace has since been verified/landed via a subsequent commit, and the directional asymmetry of the contract is fresh = halt, stale = silent skip (P333; closes the indefinite false-positive halt where e.g. an iter-4-p246.json from 2026-05-18 was still firing the gate on 2026-05-30 despite P246 having been verified-closed on a subsequent session). Success files (`"is_error": false`) are ignored regardless of freshness. When ≥1 stale iter-error-marker is silently skipped, emit a one-line iter-summary annotation per JTBD-006 audit-trail outcome: `Step 0: N stale iter-error-markers skipped (oldest: iter-X-pNNN.json, age: D days). Run \`ls .afk-run-state/iter-*.json\` to inspect.` — preserves traceability of the skip action at near-zero cost and gives a recovery path if a stale-skipped marker was actually load-bearing. Contract source: ADR-032 subprocess artefact + P333 staleness refinement. |
|
|
68
68
|
| Stale `.claude/worktrees/*` dirs + matching `claude/*` branches | `git worktree list` filtered on `claude/*` branches adjacent to `.claude/worktrees/*` directories — prior subagent worktrees that were not cleaned up. Detection only — mutation (cleanup) is out of scope and requires a separate ADR. |
|
|
69
69
|
| Uncommitted modifications to SKILL.md / source / ADR files | `git status --porcelain` filtered for `M ` / ` M` entries on `packages/*/skills/*/SKILL.md`, `packages/*/hooks/*`, `docs/decisions/*.proposed.md`, or other source paths the prior session was mid-authoring. |
|
|
70
70
|
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
#!/usr/bin/env bats
|
|
2
|
+
# Contract-assertion bats for work-problems Step 0 session-continuity
|
|
3
|
+
# detection — staleness filter on .afk-run-state/iter-*.json error markers
|
|
4
|
+
# (per P333).
|
|
5
|
+
#
|
|
6
|
+
# Per ADR-037 SKILL.md is a contract document; these assertions check the
|
|
7
|
+
# contract strings the skill prose authoritatively pins for the staleness
|
|
8
|
+
# filter that distinguishes load-bearing partial-work markers from stale
|
|
9
|
+
# residuals. Companion to work-problems-preflight-session-continuity.bats
|
|
10
|
+
# (which covers the broader signal-enumeration + interactive/AFK routing
|
|
11
|
+
# invariants from P109).
|
|
12
|
+
#
|
|
13
|
+
# Cross-reference:
|
|
14
|
+
# @problem P333 (Step 0 session-continuity has no staleness filter on
|
|
15
|
+
# .afk-run-state/iter-*.json error markers — stale residuals
|
|
16
|
+
# indefinitely false-positive the halt/ask gate)
|
|
17
|
+
# @problem P109 (parent session-continuity detection extension)
|
|
18
|
+
# ADR-019 (AFK orchestrator preflight — extension surface)
|
|
19
|
+
# ADR-032 (subprocess artefact contract — iter-*.json shape)
|
|
20
|
+
# ADR-037 (skill testing strategy — contract-assertion framing)
|
|
21
|
+
# @jtbd JTBD-006 (Progress the Backlog While I'm Away — false-positive
|
|
22
|
+
# halts violate the AFK forward-progress outcome)
|
|
23
|
+
|
|
24
|
+
setup() {
|
|
25
|
+
SKILL_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
|
|
26
|
+
SKILL_FILE="${SKILL_DIR}/SKILL.md"
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@test "SKILL.md exists" {
|
|
30
|
+
[ -f "$SKILL_FILE" ]
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@test "SKILL.md Step 0 cites P333 as the staleness-filter driver" {
|
|
34
|
+
# Contract criterion: the staleness predicate is traceable to its
|
|
35
|
+
# driver ticket so a reader can find the failure mode the filter
|
|
36
|
+
# closes.
|
|
37
|
+
run grep -nE "P333" "$SKILL_FILE"
|
|
38
|
+
[ "$status" -eq 0 ]
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@test "SKILL.md Step 0 names the staleness filter for iter-*.json markers" {
|
|
42
|
+
# Contract criterion: the iter-*.json error-marker row names a
|
|
43
|
+
# staleness / freshness predicate (not merely the is_error /
|
|
44
|
+
# api_error_status field check).
|
|
45
|
+
run grep -niE "stale|staleness|freshness|fresh per" "$SKILL_FILE"
|
|
46
|
+
[ "$status" -eq 0 ]
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@test "SKILL.md Step 0 names mtime + HEAD-commit-time as the staleness primitive" {
|
|
50
|
+
# Contract criterion: the staleness predicate is specified as mtime
|
|
51
|
+
# vs HEAD-commit-time (the engineering primitive). The "more
|
|
52
|
+
# permissive of two" disjunction is asserted in a sibling test below.
|
|
53
|
+
run grep -niE "mtime" "$SKILL_FILE"
|
|
54
|
+
[ "$status" -eq 0 ]
|
|
55
|
+
run grep -niE "HEAD.commit|HEAD's commit|commit.time" "$SKILL_FILE"
|
|
56
|
+
[ "$status" -eq 0 ]
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
@test "SKILL.md Step 0 names the 24h fallback for the staleness predicate" {
|
|
60
|
+
# Contract criterion: the "OR within 24h" disjunction protects the
|
|
61
|
+
# fresh-repo-no-commits-since-marker edge case.
|
|
62
|
+
run grep -niE "24h|24 hour|last 24" "$SKILL_FILE"
|
|
63
|
+
[ "$status" -eq 0 ]
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
@test "SKILL.md Step 0 names the silent-skip directive for stale residuals" {
|
|
67
|
+
# Contract criterion: the action on stale-classified markers is
|
|
68
|
+
# silent-skip, not halt-with-report. This is the directional
|
|
69
|
+
# asymmetry the contract pins (fresh = halt, stale = skip).
|
|
70
|
+
run grep -niE "skip.*silent|silently.*skip|silent skip" "$SKILL_FILE"
|
|
71
|
+
[ "$status" -eq 0 ]
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
@test "SKILL.md Step 0 retains the is_error / api_error_status field names alongside the staleness filter" {
|
|
75
|
+
# Contract criterion: the existing P109 signal field-name contract
|
|
76
|
+
# MUST coexist with the new staleness predicate — the staleness
|
|
77
|
+
# filter narrows the load-bearing signal, it does not replace the
|
|
78
|
+
# field check.
|
|
79
|
+
run grep -niE "is_error.*true|api_error_status" "$SKILL_FILE"
|
|
80
|
+
[ "$status" -eq 0 ]
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
@test "SKILL.md Step 0 names the iter-summary annotation for skipped stale markers" {
|
|
84
|
+
# Contract criterion per JTBD-006 audit-trail outcome (line 34 of
|
|
85
|
+
# docs/jtbd/developer/JTBD-006.md): "every action taken during AFK
|
|
86
|
+
# mode should be traceable via git history and the progress
|
|
87
|
+
# summary". A silent-skip without an iter-summary annotation drops
|
|
88
|
+
# an action from the audit trail; the contract names the annotation
|
|
89
|
+
# shape so a stale-skipped-but-actually-load-bearing marker is
|
|
90
|
+
# recoverable on user return.
|
|
91
|
+
run grep -niE "stale iter.error|stale.*marker.*skip|iter.error.markers? skipped" "$SKILL_FILE"
|
|
92
|
+
[ "$status" -eq 0 ]
|
|
93
|
+
}
|