@windyroad/itil 0.61.1 → 0.61.2
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/.claude-plugin/plugin.json +1 -1
- package/package.json +7 -2
- package/agents/test/fixtures/proceed-new-genuinely-new.md +0 -43
- package/agents/test/fixtures/proceed-new-subtle-sibling.md +0 -47
- package/agents/test/fixtures/regression-p347-vs-p346.md +0 -54
- package/agents/test/hang-off-check.bats +0 -225
- package/hooks/test/block-list.bats +0 -153
- package/hooks/test/command-detect.bats +0 -181
- package/hooks/test/itil-assistant-output-gate.bats +0 -114
- package/hooks/test/itil-assistant-output-review.bats +0 -224
- package/hooks/test/itil-bash-polling-antipattern-detect.bats +0 -154
- package/hooks/test/itil-changeset-discipline.bats +0 -603
- package/hooks/test/itil-claude-space-protection.bats +0 -294
- package/hooks/test/itil-commit-trailer-transition-advisory.bats +0 -80
- package/hooks/test/itil-correction-detect.bats +0 -189
- package/hooks/test/itil-deferral-cadence-gate.bats +0 -187
- package/hooks/test/itil-fictional-defer-detect.bats +0 -292
- package/hooks/test/itil-fix-title-lifecycle-advisory.bats +0 -129
- package/hooks/test/itil-mid-loop-ask-detect.bats +0 -220
- package/hooks/test/itil-no-implement-draft-gate.bats +0 -210
- package/hooks/test/itil-pending-questions-surface.bats +0 -307
- package/hooks/test/itil-readme-refresh-discipline.bats +0 -642
- package/hooks/test/itil-rfc-oversight-nudge.bats +0 -83
- package/hooks/test/itil-rfc-trailer-advisory.bats +0 -375
- package/hooks/test/itil-story-mirror-migration-nudge.bats +0 -122
- package/hooks/test/manage-problem-enforce-create.bats +0 -424
- package/hooks/test/p057-staging-trap-detect.bats +0 -231
- package/hooks/test/pre-publish-intake-gate.bats +0 -144
- package/hooks/test/runtime-sid-marker.bats +0 -90
- package/hooks/test/session-id.bats +0 -370
- package/scripts/migrate-problems-add-type.sh +0 -116
- package/scripts/test/catchup-scan.bats +0 -274
- package/scripts/test/check-afk-accept-eligible.bats +0 -310
- package/scripts/test/check-fail-soft-skip-discipline.bats +0 -172
- package/scripts/test/check-fix-rfc-trace.bats +0 -164
- package/scripts/test/check-locale-discipline.bats +0 -291
- package/scripts/test/check-problems-readme-budget.bats +0 -192
- package/scripts/test/check-rfc-has-stories.bats +0 -69
- package/scripts/test/check-rfc-rejected-alternatives.bats +0 -108
- package/scripts/test/check-rfc-stories-ratified.bats +0 -82
- package/scripts/test/check-upstream-responses.bats +0 -503
- package/scripts/test/classify-readme-drift.bats +0 -392
- package/scripts/test/derive-first-dispatch.bats +0 -274
- package/scripts/test/derive-release-vehicle.bats +0 -454
- package/scripts/test/detect-unratified-stories-maps.bats +0 -60
- package/scripts/test/dual-tolerant-glob-rfc-002-t2.bats +0 -309
- package/scripts/test/effort-tally.bats +0 -170
- package/scripts/test/evaluate-relevance.bats +0 -773
- package/scripts/test/kind-a-commands.bats +0 -46
- package/scripts/test/mark-create-gate.bats +0 -59
- package/scripts/test/mark-story-oversight-confirmed.bats +0 -53
- package/scripts/test/migrate-problems-add-type.bats +0 -280
- package/scripts/test/migrate-story-status-mirror.bats +0 -167
- package/scripts/test/no-type-regression-guard.bats +0 -74
- package/scripts/test/oversight-mirror-corpus-lint.bats +0 -150
- package/scripts/test/plugin-exercise-index.bats +0 -386
- package/scripts/test/plugin-maturity-doc-lint.bats +0 -470
- package/scripts/test/plugin-maturity-populate.bats +0 -631
- package/scripts/test/plugin-maturity-render.bats +0 -469
- package/scripts/test/plugin-validate-ci-gate.bats +0 -208
- package/scripts/test/reconcile-readme.bats +0 -1007
- package/scripts/test/reconcile-rfcs.bats +0 -496
- package/scripts/test/reconcile-stories.bats +0 -173
- package/scripts/test/reconcile-story-maps.bats +0 -74
- package/scripts/test/release-watch-poll-loop.bats +0 -180
- package/scripts/test/resolve-governance-plugin-dirs.bats +0 -78
- package/scripts/test/rfc-stories-extension.bats +0 -175
- package/scripts/test/skill-invocations.bats +0 -535
- package/scripts/test/skill-md-dual-tolerant-coverage-rfc-002-t3.bats +0 -374
- package/scripts/test/story-oversight-lib.bats +0 -190
- package/scripts/test/update-jtbd-references-related-problems.bats +0 -178
- package/scripts/test/update-problem-references-section.bats +0 -242
- package/scripts/test/update-problem-rfcs-section.bats +0 -242
- package/scripts/test/update-references-section-sibling-helpers.bats +0 -80
- package/scripts/test/update-rfc-commits-section.bats +0 -77
- package/scripts/test/verify-iter-summary.bats +0 -196
- package/scripts/test/working-the-problem-traversal.bats +0 -116
- package/skills/capture-problem/test/capture-problem-step-1-5b-jtbd-trace.bats +0 -398
- package/skills/capture-problem/test/capture-problem.bats +0 -389
- package/skills/capture-story/test/capture-story-behavioural.bats +0 -317
- package/skills/capture-story-map/test/capture-story-map-behavioural.bats +0 -98
- package/skills/close-incident/test/close-incident-contract.bats +0 -146
- package/skills/link-incident/test/link-incident-contract.bats +0 -125
- package/skills/list-incidents/test/list-incidents-contract.bats +0 -115
- package/skills/list-problems/test/list-problems-contract.bats +0 -100
- package/skills/list-stories/test/list-stories-contract.bats +0 -127
- package/skills/list-story-maps/test/list-story-maps-contract.bats +0 -46
- package/skills/manage-incident/test/manage-incident-adr-044-contract.bats +0 -206
- package/skills/manage-incident/test/manage-incident-close-forwarder.bats +0 -67
- package/skills/manage-incident/test/manage-incident-link-forwarder.bats +0 -67
- package/skills/manage-incident/test/manage-incident-list-forwarder.bats +0 -68
- package/skills/manage-incident/test/manage-incident-mitigate-forwarder.bats +0 -66
- package/skills/manage-incident/test/manage-incident-restore-forwarder.bats +0 -66
- package/skills/manage-incident/test/manage-incident.bats +0 -171
- package/skills/manage-problem/test/manage-problem-adr-044-step4-derive-first.bats +0 -151
- package/skills/manage-problem/test/manage-problem-auto-migrate-step.bats +0 -53
- package/skills/manage-problem/test/manage-problem-concern-boundary.bats +0 -64
- package/skills/manage-problem/test/manage-problem-effort-buckets.bats +0 -56
- package/skills/manage-problem/test/manage-problem-external-root-cause-detection.bats +0 -119
- package/skills/manage-problem/test/manage-problem-first-run-intake-prompt.bats +0 -43
- package/skills/manage-problem/test/manage-problem-git-mv-restage-reminder.bats +0 -48
- package/skills/manage-problem/test/manage-problem-id-collision-guard.bats +0 -39
- package/skills/manage-problem/test/manage-problem-list-forwarder.bats +0 -66
- package/skills/manage-problem/test/manage-problem-next-id-origin-lookup.bats +0 -50
- package/skills/manage-problem/test/manage-problem-no-prose-options.bats +0 -74
- package/skills/manage-problem/test/manage-problem-output-formatting.bats +0 -30
- package/skills/manage-problem/test/manage-problem-parked-and-cache.bats +0 -73
- package/skills/manage-problem/test/manage-problem-readme-refresh-on-transition.bats +0 -62
- package/skills/manage-problem/test/manage-problem-readme-tie-break-order.bats +0 -318
- package/skills/manage-problem/test/manage-problem-readme-vq-sort-order.bats +0 -206
- package/skills/manage-problem/test/manage-problem-release-vehicle-seed.bats +0 -83
- package/skills/manage-problem/test/manage-problem-review-forwarder.bats +0 -71
- package/skills/manage-problem/test/manage-problem-step-9d-recovery-path.bats +0 -97
- package/skills/manage-problem/test/manage-problem-transition-forwarder.bats +0 -96
- package/skills/manage-problem/test/manage-problem-transitive-dependencies.bats +0 -365
- package/skills/manage-problem/test/manage-problem-verification-detection.bats +0 -64
- package/skills/manage-problem/test/manage-problem-verification-pending.bats +0 -114
- package/skills/manage-problem/test/manage-problem-work-forwarder.bats +0 -88
- package/skills/manage-story/test/manage-story-contract.bats +0 -174
- package/skills/manage-story-map/test/manage-story-map-contract.bats +0 -63
- package/skills/mitigate-incident/test/mitigate-incident-contract.bats +0 -258
- package/skills/reconcile-readme/test/reconcile-readme-contract.bats +0 -201
- package/skills/report-upstream/test/report-upstream-contract.bats +0 -394
- package/skills/restore-incident/test/restore-incident-contract.bats +0 -170
- package/skills/review-problems/test/inbound-channels-cache-shape.bats +0 -127
- package/skills/review-problems/test/inbound-discovery-contract.bats +0 -383
- package/skills/review-problems/test/jtbd-301-verdict-shape-contract.bats +0 -225
- package/skills/review-problems/test/review-problems-contract.bats +0 -235
- package/skills/review-problems/test/review-problems-likely-verified-cell-shape.bats +0 -229
- package/skills/scaffold-intake/test/scaffold-intake-contract.bats +0 -126
- package/skills/scaffold-intake/test/scaffold-intake-fixture.bats +0 -164
- package/skills/scaffold-intake/test/scaffold-intake-secrets-absent.bats +0 -87
- package/skills/transition-problem/test/transition-problem-contract.bats +0 -285
- package/skills/transition-problems/test/transition-problems-contract.bats +0 -331
- package/skills/update-upstream/test/update-upstream-contract.bats +0 -375
- package/skills/work-problem/test/work-problem-contract.bats +0 -294
- package/skills/work-problems/test/work-problems-above-appetite-remediation.bats +0 -139
- package/skills/work-problems/test/work-problems-adr-013-rule-6-p352-amendment.bats +0 -166
- package/skills/work-problems/test/work-problems-auto-migrate-step.bats +0 -57
- package/skills/work-problems/test/work-problems-cost-logging.bats +0 -109
- package/skills/work-problems/test/work-problems-deviation-candidate-shape.bats +0 -121
- package/skills/work-problems/test/work-problems-first-run-intake-prompt.bats +0 -36
- package/skills/work-problems/test/work-problems-inter-iteration-verify.bats +0 -59
- package/skills/work-problems/test/work-problems-mid-loop-userpromptsubmit-handler.bats +0 -69
- package/skills/work-problems/test/work-problems-no-mid-loop-asking.bats +0 -192
- package/skills/work-problems/test/work-problems-p341-pre-all-done-gate.bats +0 -122
- package/skills/work-problems/test/work-problems-p342-r007-derive-then-pass-flags.bats +0 -170
- package/skills/work-problems/test/work-problems-p342-retro-auto-ticket-carveout.bats +0 -120
- package/skills/work-problems/test/work-problems-preflight-failure-handling.bats +0 -248
- package/skills/work-problems/test/work-problems-preflight-session-continuity.bats +0 -139
- package/skills/work-problems/test/work-problems-preflight.bats +0 -69
- package/skills/work-problems/test/work-problems-release-cadence.bats +0 -63
- package/skills/work-problems/test/work-problems-step-0-iter-error-staleness.bats +0 -93
- package/skills/work-problems/test/work-problems-step-0b-cache-staleness-behavioural.bats +0 -138
- package/skills/work-problems/test/work-problems-step-0c-deferred-placeholder-staleness-behavioural.bats +0 -238
- package/skills/work-problems/test/work-problems-step-0d-outbound-responses-staleness-behavioural.bats +0 -174
- package/skills/work-problems/test/work-problems-step-2-5-routing.bats +0 -80
- package/skills/work-problems/test/work-problems-step-2-5b-cross-halt-routing.bats +0 -149
- package/skills/work-problems/test/work-problems-step-3-5-jtbd-ratification-predicate.bats +0 -191
- package/skills/work-problems/test/work-problems-step-5-bats-polling-discipline.bats +0 -91
- package/skills/work-problems/test/work-problems-step-5-delegation.bats +0 -333
- package/skills/work-problems/test/work-problems-step-5-idle-timeout-sigterm.bats +0 -421
- package/skills/work-problems/test/work-problems-step-5-is-error-transient-halt.bats +0 -278
- package/skills/work-problems/test/work-problems-step-5-iter-changeset-required.bats +0 -95
- package/skills/work-problems/test/work-problems-step-5-prompt-body-re-grounding.bats +0 -128
- package/skills/work-problems/test/work-problems-step-5-stream-timeout-salvage.bats +0 -251
- package/skills/work-problems/test/work-problems-step-6-5-always-drain.bats +0 -203
- package/skills/work-problems/test/work-problems-step-6-5-cache-refresh-chain.bats +0 -174
- package/skills/work-problems/test/work-problems-step-6-5-fix-and-continue.bats +0 -254
- package/skills/work-problems/test/work-problems-step-6-5-postrelease-kv-callback.bats +0 -209
- package/skills/work-problems/test/work-problems-stop-condition-questions.bats +0 -85
|
@@ -1,278 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bats
|
|
2
|
-
# tdd-review: structural-permitted (justification: the doc-lint slice below
|
|
3
|
-
# asserts SKILL.md / ADR-032 prose contract — SKILL.md is the contract
|
|
4
|
-
# document per ADR-037 Permitted Exception; these guards catch prose drift
|
|
5
|
-
# away from the behavioural HALT-with-advisory contract exercised above. The
|
|
6
|
-
# load-bearing core of this fixture is behavioural per ADR-052. harness-gap P012)
|
|
7
|
-
#
|
|
8
|
-
# Behavioural test: work-problems Step 5 exit-code semantics — the
|
|
9
|
-
# is_error:true TRANSIENT-API-ERROR HALT branch (P214). When an iter
|
|
10
|
-
# subprocess returns `is_error: true` with `total_cost_usd: 0` AND no staged
|
|
11
|
-
# work in the tree (the 529 Overloaded / 429 rate-limit / 401 auth-expired
|
|
12
|
-
# shape — the API call never landed; nothing was done; metadata records the
|
|
13
|
-
# failure), the orchestrator MUST halt the loop with a class-appropriate
|
|
14
|
-
# advisory line in the final summary — NOT silently treat exit-0 as success
|
|
15
|
-
# and try to parse a missing ITERATION_SUMMARY block.
|
|
16
|
-
#
|
|
17
|
-
# This is the HALT counterpart to the existing P261 SALVAGE branch (covered
|
|
18
|
-
# by work-problems-step-5-stream-timeout-salvage.bats):
|
|
19
|
-
# - SALVAGE: is_error:true + staged work + bats green (stream-timeout class)
|
|
20
|
-
# - HALT: is_error:true + nothing staged (transient-API-error class — P214)
|
|
21
|
-
# Both branches require the orchestrator to read `is_error` BEFORE the
|
|
22
|
-
# Exit-0 → parse-ITERATION_SUMMARY path; without the explicit check-order
|
|
23
|
-
# the loop silently miscounts and may spawn further subprocesses that fail
|
|
24
|
-
# identically (the AFK-promise-breaking shape P214 reports).
|
|
25
|
-
#
|
|
26
|
-
# The fake-shim below re-creates the production 529 Overloaded shape:
|
|
27
|
-
# is_error:true, total_cost_usd:0, no staged work, .result carrying the
|
|
28
|
-
# upstream error string. The harness re-implements the orchestrator's
|
|
29
|
-
# ordered-check decision contract (faithful to SKILL.md Step 5) and asserts
|
|
30
|
-
# the HALT routing + class-appropriate advisory for each transient class.
|
|
31
|
-
#
|
|
32
|
-
# @problem P214
|
|
33
|
-
# @jtbd JTBD-006
|
|
34
|
-
#
|
|
35
|
-
# Cross-reference:
|
|
36
|
-
# P214 (work-problems Step 5 exit-code rule doesn't handle is_error:true
|
|
37
|
-
# transient API failures) — driver ticket
|
|
38
|
-
# P261 (is_error:true stream-timeout salvage carve-out) — sibling SALVAGE
|
|
39
|
-
# branch; this fixture covers the HALT counterpart
|
|
40
|
-
# ADR-032 (governance skill invocation patterns — is_error:true class
|
|
41
|
-
# taxonomy: SALVAGE = stream-timeout; HALT = transient-API-error) — the
|
|
42
|
-
# amended contract this fixture pins
|
|
43
|
-
# ADR-013 Rule 6 (AFK fail-safe — HALT routing is non-interactive; no
|
|
44
|
-
# AskUserQuestion) — invariant honoured
|
|
45
|
-
# ADR-037 / ADR-052 (skill testing strategy — behavioural default; doc-lint
|
|
46
|
-
# contract assertion is the Permitted Exception, marked above)
|
|
47
|
-
|
|
48
|
-
setup() {
|
|
49
|
-
TEST_TMP="$(mktemp -d)"
|
|
50
|
-
FAKE_BIN="${TEST_TMP}/bin"
|
|
51
|
-
mkdir -p "$FAKE_BIN"
|
|
52
|
-
|
|
53
|
-
# Fake `claude` binary simulating the transient-API-error shape: exits 0,
|
|
54
|
-
# emits an is_error:true JSON envelope with total_cost_usd:0 and the
|
|
55
|
-
# transient-class error string in `.result`. No staged work — the API call
|
|
56
|
-
# never landed; nothing was done.
|
|
57
|
-
cat > "$FAKE_BIN/claude" <<'FAKE_EOF'
|
|
58
|
-
#!/usr/bin/env bash
|
|
59
|
-
# Test fake for work-problems Step 5 P214 transient-API-error halt fixture.
|
|
60
|
-
# Emits is_error:true with total_cost_usd:0 and a class-specific .result string.
|
|
61
|
-
# FAKE_ERROR_CLASS selects the transient class: overloaded | rate-limit | auth-expired
|
|
62
|
-
case "${FAKE_ERROR_CLASS:-overloaded}" in
|
|
63
|
-
overloaded)
|
|
64
|
-
RESULT='API Error (529): Overloaded'
|
|
65
|
-
;;
|
|
66
|
-
rate-limit)
|
|
67
|
-
RESULT='API Error (429): Rate limit exceeded'
|
|
68
|
-
;;
|
|
69
|
-
auth-expired)
|
|
70
|
-
RESULT='API Error (401): Authentication expired'
|
|
71
|
-
;;
|
|
72
|
-
*)
|
|
73
|
-
RESULT='API Error: Unknown'
|
|
74
|
-
;;
|
|
75
|
-
esac
|
|
76
|
-
printf '%s\n' "{\"is_error\":true,\"result\":\"${RESULT}\",\"total_cost_usd\":0,\"duration_ms\":1500,\"usage\":{\"input_tokens\":0,\"output_tokens\":0,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0}}"
|
|
77
|
-
FAKE_EOF
|
|
78
|
-
chmod +x "$FAKE_BIN/claude"
|
|
79
|
-
export PATH="$FAKE_BIN:$PATH"
|
|
80
|
-
|
|
81
|
-
# A throwaway git repo so staged-work detection is real (and empty — no
|
|
82
|
-
# staged work is the load-bearing characteristic of this class).
|
|
83
|
-
REPO="${TEST_TMP}/repo"
|
|
84
|
-
mkdir -p "$REPO"
|
|
85
|
-
git -C "$REPO" init -q
|
|
86
|
-
git -C "$REPO" config user.email "test@example.com"
|
|
87
|
-
git -C "$REPO" config user.name "Test"
|
|
88
|
-
git -C "$REPO" commit -q --allow-empty -m "root"
|
|
89
|
-
|
|
90
|
-
SKILL_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
|
|
91
|
-
SKILL_FILE="${SKILL_DIR}/SKILL.md"
|
|
92
|
-
ADR_FILE="$(cd "${SKILL_DIR}/../../../.." && pwd)/docs/decisions/032-governance-skill-invocation-patterns.proposed.md"
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
teardown() {
|
|
96
|
-
if [ -n "${TEST_TMP:-}" ] && [ -d "$TEST_TMP" ]; then
|
|
97
|
-
rm -rf "$TEST_TMP"
|
|
98
|
-
fi
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
# Faithful re-implementation of SKILL.md Step 5's ORDERED-CHECK decision
|
|
102
|
-
# contract (P214 amendment to the P261 carve-out). The orchestrator reads
|
|
103
|
-
# (1) exit code, (2) is_error, (3) ITERATION_SUMMARY — in that order. On
|
|
104
|
-
# is_error:true + nothing staged, emit a class-appropriate advisory.
|
|
105
|
-
ordered_check_decision() {
|
|
106
|
-
local exit_code="$1"
|
|
107
|
-
local json="$2"
|
|
108
|
-
local repo="$3"
|
|
109
|
-
|
|
110
|
-
# (1) Non-zero exit → halt per the exit-code contract.
|
|
111
|
-
if [ "$exit_code" -ne 0 ]; then
|
|
112
|
-
printf 'DECISION=HALT reason=non-zero-exit\n'
|
|
113
|
-
return 0
|
|
114
|
-
fi
|
|
115
|
-
|
|
116
|
-
# (2) Parse is_error BEFORE attempting to parse ITERATION_SUMMARY (the
|
|
117
|
-
# ordered-check rule P214 amends in).
|
|
118
|
-
local is_error result
|
|
119
|
-
is_error=$(printf '%s' "$json" | python3 -c 'import json,sys; print(str(json.load(sys.stdin).get("is_error")).lower())')
|
|
120
|
-
result=$(printf '%s' "$json" | python3 -c 'import json,sys; print(json.load(sys.stdin).get("result",""))')
|
|
121
|
-
|
|
122
|
-
if [ "$is_error" = "true" ]; then
|
|
123
|
-
# is_error:true with staged work → defer to existing P261 SALVAGE branch
|
|
124
|
-
# (covered by sibling fixture work-problems-step-5-stream-timeout-salvage.bats).
|
|
125
|
-
local staged
|
|
126
|
-
staged=$(git -C "$repo" diff --cached --name-only)
|
|
127
|
-
if [ -n "$staged" ]; then
|
|
128
|
-
printf 'DECISION=DEFER_TO_SALVAGE_BRANCH\n'
|
|
129
|
-
return 0
|
|
130
|
-
fi
|
|
131
|
-
|
|
132
|
-
# is_error:true with NO staged work → HALT with class-appropriate advisory.
|
|
133
|
-
local advisory
|
|
134
|
-
case "$result" in
|
|
135
|
-
*"529"*|*"Overloaded"*|*"overloaded"*)
|
|
136
|
-
advisory='API overloaded; retry when service recovers'
|
|
137
|
-
;;
|
|
138
|
-
*"429"*|*"Rate limit"*|*"rate limit"*|*"rate-limit"*)
|
|
139
|
-
advisory='API rate-limited; retry when limit window resets'
|
|
140
|
-
;;
|
|
141
|
-
*"401"*|*"Authentication"*|*"auth"*)
|
|
142
|
-
advisory='API auth expired; refresh credentials before resuming'
|
|
143
|
-
;;
|
|
144
|
-
*)
|
|
145
|
-
advisory='transient API error; inspect .result and resume manually'
|
|
146
|
-
;;
|
|
147
|
-
esac
|
|
148
|
-
printf 'DECISION=HALT reason=is-error-transient advisory=%s\n' "$advisory"
|
|
149
|
-
return 0
|
|
150
|
-
fi
|
|
151
|
-
|
|
152
|
-
# (3) Exit 0 AND is_error:false → parse ITERATION_SUMMARY.
|
|
153
|
-
printf 'DECISION=PARSE_SUMMARY\n'
|
|
154
|
-
return 0
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
# ---------------------------------------------------------------------------
|
|
158
|
-
# Behavioural cases (the load-bearing core per ADR-052).
|
|
159
|
-
# ---------------------------------------------------------------------------
|
|
160
|
-
|
|
161
|
-
@test "P214: is_error:true + 529 Overloaded + no staged work -> HALT with API-overloaded advisory" {
|
|
162
|
-
export FAKE_ERROR_CLASS=overloaded
|
|
163
|
-
local json
|
|
164
|
-
json=$( cd "$REPO" && claude -p --output-format json "TEST" < /dev/null )
|
|
165
|
-
run ordered_check_decision 0 "$json" "$REPO"
|
|
166
|
-
[ "$status" -eq 0 ]
|
|
167
|
-
[[ "$output" == *"DECISION=HALT"* ]]
|
|
168
|
-
[[ "$output" == *"reason=is-error-transient"* ]]
|
|
169
|
-
[[ "$output" == *"API overloaded"* ]]
|
|
170
|
-
[[ "$output" == *"retry when service recovers"* ]]
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
@test "P214: is_error:true + 429 rate-limit + no staged work -> HALT with rate-limited advisory" {
|
|
174
|
-
export FAKE_ERROR_CLASS=rate-limit
|
|
175
|
-
local json
|
|
176
|
-
json=$( cd "$REPO" && claude -p --output-format json "TEST" < /dev/null )
|
|
177
|
-
run ordered_check_decision 0 "$json" "$REPO"
|
|
178
|
-
[ "$status" -eq 0 ]
|
|
179
|
-
[[ "$output" == *"DECISION=HALT"* ]]
|
|
180
|
-
[[ "$output" == *"reason=is-error-transient"* ]]
|
|
181
|
-
[[ "$output" == *"rate-limited"* ]]
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
@test "P214: is_error:true + 401 auth-expired + no staged work -> HALT with refresh-credentials advisory" {
|
|
185
|
-
export FAKE_ERROR_CLASS=auth-expired
|
|
186
|
-
local json
|
|
187
|
-
json=$( cd "$REPO" && claude -p --output-format json "TEST" < /dev/null )
|
|
188
|
-
run ordered_check_decision 0 "$json" "$REPO"
|
|
189
|
-
[ "$status" -eq 0 ]
|
|
190
|
-
[[ "$output" == *"DECISION=HALT"* ]]
|
|
191
|
-
[[ "$output" == *"reason=is-error-transient"* ]]
|
|
192
|
-
[[ "$output" == *"auth expired"* ]]
|
|
193
|
-
[[ "$output" == *"refresh credentials"* ]]
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
@test "P214: is_error MUST be checked BEFORE ITERATION_SUMMARY parse on Exit 0 (ordered-check invariant)" {
|
|
197
|
-
# The load-bearing P214 invariant: when exit 0 AND is_error:true, the
|
|
198
|
-
# decision is HALT, NOT PARSE_SUMMARY. Without the ordered-check rule the
|
|
199
|
-
# loop would silently route to PARSE_SUMMARY and miss the failure.
|
|
200
|
-
export FAKE_ERROR_CLASS=overloaded
|
|
201
|
-
local json
|
|
202
|
-
json=$( cd "$REPO" && claude -p --output-format json "TEST" < /dev/null )
|
|
203
|
-
run ordered_check_decision 0 "$json" "$REPO"
|
|
204
|
-
[ "$status" -eq 0 ]
|
|
205
|
-
[[ "$output" != *"DECISION=PARSE_SUMMARY"* ]]
|
|
206
|
-
[[ "$output" == *"DECISION=HALT"* ]]
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
@test "P214: non-zero exit takes precedence over is_error check (HALT routing)" {
|
|
210
|
-
# Non-zero exit halts regardless of is_error value — the exit-code rule
|
|
211
|
-
# is check (1) in the ordered sequence.
|
|
212
|
-
export FAKE_ERROR_CLASS=overloaded
|
|
213
|
-
local json
|
|
214
|
-
json=$( cd "$REPO" && claude -p --output-format json "TEST" < /dev/null )
|
|
215
|
-
run ordered_check_decision 1 "$json" "$REPO"
|
|
216
|
-
[ "$status" -eq 0 ]
|
|
217
|
-
[[ "$output" == *"DECISION=HALT"* ]]
|
|
218
|
-
[[ "$output" == *"reason=non-zero-exit"* ]]
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
@test "P214: is_error:true + staged work -> defers to existing P261 SALVAGE branch (no double-handling)" {
|
|
222
|
-
# When staged work exists, the transient-API-error HALT branch must NOT
|
|
223
|
-
# fire — it MUST defer to the P261 SALVAGE branch. This guards against
|
|
224
|
-
# the new branch swallowing salvage-eligible work.
|
|
225
|
-
export FAKE_ERROR_CLASS=overloaded
|
|
226
|
-
printf 'salvageable work\n' > "$REPO/salvage-me.txt"
|
|
227
|
-
git -C "$REPO" add salvage-me.txt
|
|
228
|
-
local json
|
|
229
|
-
json=$( cd "$REPO" && claude -p --output-format json "TEST" < /dev/null )
|
|
230
|
-
run ordered_check_decision 0 "$json" "$REPO"
|
|
231
|
-
[ "$status" -eq 0 ]
|
|
232
|
-
[[ "$output" == *"DECISION=DEFER_TO_SALVAGE_BRANCH"* ]]
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
# ---------------------------------------------------------------------------
|
|
236
|
-
# Doc-lint contract assertions (Permitted Exception per ADR-037; structural
|
|
237
|
-
# slice marked at top of file per ADR-052 Surface 2). These guard the SKILL.md
|
|
238
|
-
# / ADR-032 prose against drift away from the behavioural contract above.
|
|
239
|
-
# ---------------------------------------------------------------------------
|
|
240
|
-
|
|
241
|
-
@test "P214: SKILL.md Step 5 documents the ORDERED check sequence (exit-code, is_error, ITERATION_SUMMARY)" {
|
|
242
|
-
# The ordered-check rule must be explicit in the prose so an implementer
|
|
243
|
-
# reading Step 5 routes is_error:true to HALT before attempting to parse
|
|
244
|
-
# a missing ITERATION_SUMMARY block.
|
|
245
|
-
run grep -niE "(check|read|parse).{0,40}is_error.{0,80}before.{0,80}(ITERATION_SUMMARY|parse|\.result)|ordered check|check.order" "$SKILL_FILE"
|
|
246
|
-
[ "$status" -eq 0 ]
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
@test "P214: SKILL.md Step 5 names the transient-API-error classes (overloaded / rate-limit / auth-expired)" {
|
|
250
|
-
# The HALT advisory must enumerate the known transient classes so the
|
|
251
|
-
# final summary carries an actionable message rather than a generic
|
|
252
|
-
# "loop halted" line.
|
|
253
|
-
run grep -niE "529|Overloaded|overload" "$SKILL_FILE"
|
|
254
|
-
[ "$status" -eq 0 ]
|
|
255
|
-
run grep -niE "429|rate.?limit" "$SKILL_FILE"
|
|
256
|
-
[ "$status" -eq 0 ]
|
|
257
|
-
run grep -niE "401|auth.?expired|auth.*expir" "$SKILL_FILE"
|
|
258
|
-
[ "$status" -eq 0 ]
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
@test "P214: SKILL.md Step 5 cites P214 as the driver of the transient-API-error HALT branch" {
|
|
262
|
-
run grep -nE "P214" "$SKILL_FILE"
|
|
263
|
-
[ "$status" -eq 0 ]
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
@test "P214: SKILL.md HALT branch distinguishes the transient-API-error class from the P261 stream-timeout SALVAGE class" {
|
|
267
|
-
# The two is_error:true branches (SALVAGE vs HALT) must be cross-referenced
|
|
268
|
-
# so adopters reading either branch see the other.
|
|
269
|
-
run grep -niE "P261.{0,200}(transient|HALT|overload|class)|transient.{0,200}P261|salvage.{0,200}(transient|class)" "$SKILL_FILE"
|
|
270
|
-
[ "$status" -eq 0 ]
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
@test "P214: ADR-032 P261 section names the is_error:true class taxonomy (SALVAGE = stream-timeout; HALT = transient-API-error)" {
|
|
274
|
-
# ADR-032's P261 amendment should be extended with the broader class
|
|
275
|
-
# taxonomy so the SKILL prose and the ADR contract stay in sync.
|
|
276
|
-
run grep -niE "P214|transient.?(API.?)?error|class taxonomy|(overload|rate.?limit|auth.?expired).{0,80}HALT|HALT.{0,80}(overload|rate.?limit|auth.?expired)" "$ADR_FILE"
|
|
277
|
-
[ "$status" -eq 0 ]
|
|
278
|
-
}
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bats
|
|
2
|
-
# P206 — work-problems Step 5 iteration-prompt-body must EXPLICITLY require
|
|
3
|
-
# AFK iter subprocesses to author a `.changeset/*.md` alongside any fix
|
|
4
|
-
# commit that ships shippable code. Hook P141 (itil-changeset-discipline.sh)
|
|
5
|
-
# enforces this at git-commit time but depends on the plugin marketplace
|
|
6
|
-
# cache being current. The prompt-time constraint composes defence-in-depth
|
|
7
|
-
# with the hook so iter subprocesses self-author the changeset rather than
|
|
8
|
-
# discovering the gap at commit time (or worse — slipping through when the
|
|
9
|
-
# hook is missing from the install).
|
|
10
|
-
#
|
|
11
|
-
# Reported as inbound from downstream consumer bbstats (their P195) on
|
|
12
|
-
# 2026-05-15; covered by ADR-076 Origin field tier.
|
|
13
|
-
#
|
|
14
|
-
# tdd-review: structural-permitted (justification: SKILL.md is the named
|
|
15
|
-
# contract document under ADR-052; behavioural alternative would require a
|
|
16
|
-
# synthetic `claude -p` iter dispatch harness that completes a fix commit
|
|
17
|
-
# and asserts `.changeset/*.md` co-presence — that harness sits outside the
|
|
18
|
-
# skill layer and depends on the Anthropic CLI binary. Same Permitted
|
|
19
|
-
# Exception precedent as `work-problems-step-5-delegation.bats:99-105` and
|
|
20
|
-
# the P083 / P086 / P089 ScheduleWakeup / retro / stdin-redirect fixtures
|
|
21
|
-
# in the same directory).
|
|
22
|
-
#
|
|
23
|
-
# @problem P206
|
|
24
|
-
# @problem P141
|
|
25
|
-
# @jtbd JTBD-006
|
|
26
|
-
# @jtbd JTBD-007
|
|
27
|
-
# @jtbd JTBD-001
|
|
28
|
-
#
|
|
29
|
-
# Cross-reference:
|
|
30
|
-
# P206 — this ticket (work-problems iter workers don't add changesets)
|
|
31
|
-
# P141 — sibling changeset-discipline hook (hook-level enforcement;
|
|
32
|
-
# prompt-time constraint composes defence-in-depth)
|
|
33
|
-
# bbstats#195 — inbound report from downstream consumer
|
|
34
|
-
# ADR-014 (governance skills commit their own work)
|
|
35
|
-
# ADR-018 (inter-iteration release cadence — changesets are the load-
|
|
36
|
-
# bearing input to ADR-020's auto-release path)
|
|
37
|
-
# ADR-052 (behavioural tests default; structural-permitted with comment)
|
|
38
|
-
# ADR-076 (inbound-reported problems rank ahead via sort tier — Origin
|
|
39
|
-
# field stamping)
|
|
40
|
-
# JTBD-006 (Progress the Backlog While I'm Away) — load-bearing
|
|
41
|
-
# JTBD-007 (Keep Plugins Current Across Projects) — closure depends on
|
|
42
|
-
# release actually shipping
|
|
43
|
-
|
|
44
|
-
setup() {
|
|
45
|
-
SKILL_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
|
|
46
|
-
SKILL_FILE="${SKILL_DIR}/SKILL.md"
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
@test "SKILL.md Step 5 iteration-prompt-body names changeset as required when fix changes shippable code (P206)" {
|
|
50
|
-
# The iteration-prompt-body must EXPLICITLY require iter subprocesses to
|
|
51
|
-
# author a `.changeset/*.md` alongside any fix commit that ships shippable
|
|
52
|
-
# code. Without the explicit constraint, iter subprocesses can complete
|
|
53
|
-
# fix commits that the orchestrator's Step 6.5 release-cadence drain
|
|
54
|
-
# then has nothing to release — fixes accumulate without an npm publish.
|
|
55
|
-
# The constraint must name `changeset` AND a "shippable code" qualifier
|
|
56
|
-
# so doc-only and test-only commits are correctly exempted.
|
|
57
|
-
run grep -niE "changeset.{0,200}(shippable|publishable|packages/<plugin>)" "$SKILL_FILE"
|
|
58
|
-
[ "$status" -eq 0 ]
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
@test "SKILL.md Step 5 iteration-prompt-body exempts doc-only and test-only changes from the changeset requirement (P206)" {
|
|
62
|
-
# Doc-only changes (e.g. JTBD edits, ADR edits, retro additions) and
|
|
63
|
-
# test-only changes (under `test/`) ship no behaviour — requiring a
|
|
64
|
-
# changeset for them would author noise CHANGELOG bullets per release.
|
|
65
|
-
# The constraint must name the exemption explicitly so iter subprocesses
|
|
66
|
-
# do not over-apply the rule.
|
|
67
|
-
run grep -niE "(doc.?only|docs.?only|test.?only).{0,80}(omit|may omit|no changeset|not required)|changeset.{0,80}(omit|exempt)" "$SKILL_FILE"
|
|
68
|
-
[ "$status" -eq 0 ]
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
@test "SKILL.md Step 5 iteration-prompt-body cites P141 as the defence-in-depth hook (P206)" {
|
|
72
|
-
# The prompt-time constraint composes with hook P141 (changeset-discipline).
|
|
73
|
-
# Naming P141 inline in the prompt-body makes the defence-in-depth
|
|
74
|
-
# composition self-documenting — a future contributor reading the prompt
|
|
75
|
-
# understands the hook is the second layer, not the only layer.
|
|
76
|
-
run grep -nE "P141" "$SKILL_FILE"
|
|
77
|
-
[ "$status" -eq 0 ]
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
@test "SKILL.md Related section cites P206 (this fix)" {
|
|
81
|
-
# ADR-037 + ADR-052 self-documenting contract: the contract document
|
|
82
|
-
# carries a Related section listing the problem tickets it satisfies.
|
|
83
|
-
# P206 closure depends on this citation landing.
|
|
84
|
-
run grep -nE "P206" "$SKILL_FILE"
|
|
85
|
-
[ "$status" -eq 0 ]
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
@test "SKILL.md Step 5 iteration-prompt-body cites bbstats#195 as the inbound source (P206 + ADR-076 Origin)" {
|
|
89
|
-
# ADR-076 reported-first tier requires the Origin field to be visible at
|
|
90
|
-
# the contract surface so future contributors understand the constraint
|
|
91
|
-
# was driven by external evidence, not internal speculation. The bbstats
|
|
92
|
-
# back-link is the audit anchor.
|
|
93
|
-
run grep -niE "bbstats.{0,20}195|bbstats/.{0,30}195|bbstats#195" "$SKILL_FILE"
|
|
94
|
-
[ "$status" -eq 0 ]
|
|
95
|
-
}
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bats
|
|
2
|
-
# P211 — work-problems Step 5 iteration-prompt-body must EXPLICITLY re-ground
|
|
3
|
-
# each iter's dispatch prompt against the CURRENT ticket only. The orchestrator
|
|
4
|
-
# MUST NOT inline the ticket's `## Fix Strategy` text verbatim, and MUST NOT
|
|
5
|
-
# leak prior-iter content (prior ticket ID, prior Fix Strategy text, prior
|
|
6
|
-
# outcome reason, prior commit SHA, prior retro findings) across iterations.
|
|
7
|
-
#
|
|
8
|
-
# Reported as inbound from downstream consumer bbstats (their P194) on
|
|
9
|
-
# 2026-05-15; covered by ADR-076 Origin field tier.
|
|
10
|
-
#
|
|
11
|
-
# Behavioural mechanism for the bug: AFK iter subprocesses inherit a stale
|
|
12
|
-
# design-rationale frame and may attempt fixes anchored on the wrong ticket's
|
|
13
|
-
# intent. Workaround the ticket names: user-in-the-loop verification after
|
|
14
|
-
# each iter, reading the subprocess's commit and checking whether it cites
|
|
15
|
-
# the correct ticket's design rationale — a manual-policing burden the AFK
|
|
16
|
-
# loop is meant to eliminate. JTBD-006 (Progress the Backlog While I'm Away)
|
|
17
|
-
# is load-bearing: the audit trail and trust in the AFK loop degrade if iters
|
|
18
|
-
# work the wrong ticket's design rationale.
|
|
19
|
-
#
|
|
20
|
-
# tdd-review: structural-permitted (justification: SKILL.md is the named
|
|
21
|
-
# contract document under ADR-052; behavioural alternative would require a
|
|
22
|
-
# synthetic `claude -p` iter dispatch harness that simulates multiple
|
|
23
|
-
# sequential iters and asserts no cross-iter prompt-body content leakage —
|
|
24
|
-
# that harness sits outside the skill layer and depends on the Anthropic CLI
|
|
25
|
-
# binary. Same Permitted Exception precedent as
|
|
26
|
-
# `work-problems-step-5-iter-changeset-required.bats:14-21`,
|
|
27
|
-
# `work-problems-step-5-delegation.bats:99-105`, and the P083 / P086 / P089
|
|
28
|
-
# ScheduleWakeup / retro / stdin-redirect fixtures in the same directory.
|
|
29
|
-
# P012 is the harness-gap ticket).
|
|
30
|
-
#
|
|
31
|
-
# @problem P211
|
|
32
|
-
# @problem P012
|
|
33
|
-
# @jtbd JTBD-006
|
|
34
|
-
# @jtbd JTBD-001
|
|
35
|
-
#
|
|
36
|
-
# Cross-reference:
|
|
37
|
-
# P211 — this ticket (orchestrator carries prior-ticket Fix Strategy into
|
|
38
|
-
# next iter's dispatch context — pollutes the new iter's framing)
|
|
39
|
-
# bbstats#194 — inbound report from downstream consumer
|
|
40
|
-
# ADR-014 (single-commit grain — fix lands as one coherent commit)
|
|
41
|
-
# ADR-032 (governance skill invocation patterns — AFK iteration-isolation
|
|
42
|
-
# wrapper; re-grounding is a clarification of that isolation intent)
|
|
43
|
-
# ADR-052 (behavioural tests default; structural-permitted with comment)
|
|
44
|
-
# ADR-076 (inbound-reported problems rank ahead via sort tier — Origin
|
|
45
|
-
# field stamping)
|
|
46
|
-
# JTBD-006 (Progress the Backlog While I'm Away) — load-bearing
|
|
47
|
-
|
|
48
|
-
setup() {
|
|
49
|
-
SKILL_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
|
|
50
|
-
SKILL_FILE="${SKILL_DIR}/SKILL.md"
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
@test "SKILL.md cites P211 (re-grounding driver) in Related section" {
|
|
54
|
-
# Self-documenting contract — a future contributor weakening the
|
|
55
|
-
# re-grounding constraint reads P211 and understands why it exists.
|
|
56
|
-
run grep -nE 'P211' "$SKILL_FILE"
|
|
57
|
-
[ "$status" -eq 0 ]
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
@test "SKILL.md Step 5 iteration prompt body names re-grounding per iter explicitly" {
|
|
61
|
-
# The "self-contained" opener at line 510 is the existing weaker form; the
|
|
62
|
-
# stricter "re-ground per iter" phrasing names the construction invariant
|
|
63
|
-
# the orchestrator MUST satisfy on each iter dispatch. P211's bug shape is
|
|
64
|
-
# exactly the case where "self-contained" was read as a subprocess-side
|
|
65
|
-
# property only, with the orchestrator-side construction leaking prior-iter
|
|
66
|
-
# content into the new iter's prompt body.
|
|
67
|
-
run grep -niE "re.?ground.{0,40}per iter|re.?grounded.{0,40}per iter|per.?iter.{0,40}re.?ground" "$SKILL_FILE"
|
|
68
|
-
[ "$status" -eq 0 ]
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
@test "SKILL.md Step 5 iter prompt body forbids inlining Fix Strategy verbatim" {
|
|
72
|
-
# The bug shape: orchestrator reads target ticket's `## Fix Strategy` and
|
|
73
|
-
# cites it verbatim into the iteration subprocess's prompt body. The
|
|
74
|
-
# SKILL.md MUST explicitly forbid this so future contributors understand
|
|
75
|
-
# the subprocess reads Fix Strategy from disk via manage-problem inside
|
|
76
|
-
# its own context.
|
|
77
|
-
run grep -niE "(not|never|MUST NOT|does not).{0,40}inline.{0,40}Fix Strategy|Fix Strategy.{0,40}(not|never|MUST NOT|does not).{0,40}inline|do not.{0,40}cite.{0,40}Fix Strategy.{0,40}verbatim|Fix Strategy.{0,40}verbatim.{0,40}(not|never|forbid)" "$SKILL_FILE"
|
|
78
|
-
[ "$status" -eq 0 ]
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
@test "SKILL.md Step 5 iter prompt body explicitly forbids prior-iter content leakage" {
|
|
82
|
-
# The cross-iter leakage class names: prior ticket ID, prior Fix Strategy
|
|
83
|
-
# text, prior outcome reason, prior commit SHA, prior retro findings. The
|
|
84
|
-
# SKILL.md MUST name the no-leakage invariant explicitly so the orchestrator
|
|
85
|
-
# main turn's prompt construction is constrained on every iter.
|
|
86
|
-
run grep -niE "(no prior|not.{0,20}prior|prior.?iter.{0,40}(leak|carry|inherit)|leak.{0,40}prior|carry.{0,40}prior.{0,40}iter)" "$SKILL_FILE"
|
|
87
|
-
[ "$status" -eq 0 ]
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
@test "SKILL.md Step 5 names template-driven reset-per-iter construction" {
|
|
91
|
-
# The construction shape: template-driven, reset per iter, no global
|
|
92
|
-
# accumulator across iters. This is the structural invariant the
|
|
93
|
-
# orchestrator main turn must satisfy when building each iter's prompt.
|
|
94
|
-
run grep -niE "template.?driven|reset per iter|reset.{0,20}per.{0,20}iter|no.{0,20}(global )?accumulator" "$SKILL_FILE"
|
|
95
|
-
[ "$status" -eq 0 ]
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
@test "SKILL.md Step 5 iteration prompt body cites P211 inline" {
|
|
99
|
-
# The re-grounding clause must cite P211 inline so the contract document
|
|
100
|
-
# is self-documenting — a future contributor removing the clause reads the
|
|
101
|
-
# P211 reference and understands why it exists before deleting it. Same
|
|
102
|
-
# pattern as the P083 / P086 / P146 / P232 inline citations in the same
|
|
103
|
-
# block.
|
|
104
|
-
run grep -nE "re.?ground.{0,200}P211|P211.{0,200}re.?ground|P211.{0,200}Fix Strategy|Fix Strategy.{0,200}P211" "$SKILL_FILE"
|
|
105
|
-
[ "$status" -eq 0 ]
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
@test "SKILL.md re-grounding clause sits inside Step 5 iteration prompt body section" {
|
|
109
|
-
# Structural locality: the re-grounding clause must live INSIDE Step 5's
|
|
110
|
-
# Iteration prompt body section (after the "self-contained" opener at
|
|
111
|
-
# line 510), not free-floating elsewhere in SKILL.md. Locality matters
|
|
112
|
-
# because the rule is read alongside the rest of the prompt-body contract,
|
|
113
|
-
# and a future contributor refactoring Step 5 must encounter it inline.
|
|
114
|
-
# Assertion shape: the line containing "re-ground" sits after the line
|
|
115
|
-
# containing "Iteration prompt body" and before the line containing
|
|
116
|
-
# "Return-summary contract".
|
|
117
|
-
iter_line=$(grep -nE '^\*\*Iteration prompt body' "$SKILL_FILE" | head -1 | cut -d: -f1)
|
|
118
|
-
# Tightened regex: require the literal hyphenated form "re-ground" /
|
|
119
|
-
# "re-grounded" / "re-grounding" so partial-substring matches like
|
|
120
|
-
# "foreground" (line 33) don't satisfy the assertion.
|
|
121
|
-
reground_line=$(grep -niE "re-ground(ed|ing)?" "$SKILL_FILE" | head -1 | cut -d: -f1)
|
|
122
|
-
return_summary_line=$(grep -nE '^\*\*Return-summary contract' "$SKILL_FILE" | head -1 | cut -d: -f1)
|
|
123
|
-
[ -n "$iter_line" ]
|
|
124
|
-
[ -n "$reground_line" ]
|
|
125
|
-
[ -n "$return_summary_line" ]
|
|
126
|
-
[ "$reground_line" -gt "$iter_line" ]
|
|
127
|
-
[ "$reground_line" -lt "$return_summary_line" ]
|
|
128
|
-
}
|