@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,120 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bats
|
|
2
|
-
|
|
3
|
-
# P342: Iter retros queue their own observations as outstanding-questions
|
|
4
|
-
# for user-direction triage instead of auto-ticketing — same trust-
|
|
5
|
-
# boundary as /wr-retrospective:run-retro Step 4a (verification close-on-
|
|
6
|
-
# evidence).
|
|
7
|
-
#
|
|
8
|
-
# The fix shape amends the work-problems Step 5 iter-prompt body:
|
|
9
|
-
# - Relax the "no capture-* siblings mid-loop" rule for RETRO-surfaced
|
|
10
|
-
# observations specifically.
|
|
11
|
-
# - Direct retro to auto-ticket recurring class-of-behaviour
|
|
12
|
-
# observations via /wr-itil:capture-problem (mechanical-stage carve-
|
|
13
|
-
# out per run-retro Step 4a precedent).
|
|
14
|
-
# - Route ONLY direction-setting observations (genuine user-judgment-
|
|
15
|
-
# bound questions) to outstanding_questions.
|
|
16
|
-
# - Document the classification:
|
|
17
|
-
# recurring class-of-behaviour / SKILL-contract drift / hook
|
|
18
|
-
# misbehaviour / framework-gap → auto-ticket.
|
|
19
|
-
# Direction-setting (design choice, deviation-approval, framework
|
|
20
|
-
# boundary) → outstanding_questions.
|
|
21
|
-
# Ambiguous → default to auto-ticket.
|
|
22
|
-
#
|
|
23
|
-
# Doc-lint contract assertions per ADR-037 Permitted Exception.
|
|
24
|
-
#
|
|
25
|
-
# @problem P342
|
|
26
|
-
# @adr ADR-044 (Decision-Delegation Contract — mechanical-stage carve-out per Step 4a precedent)
|
|
27
|
-
# @adr ADR-013 Rule 5 (policy-authorised silent proceed)
|
|
28
|
-
# @adr ADR-032 (governance skill invocation patterns — foreground-spawns-background fanout pattern for capture-*)
|
|
29
|
-
# @jtbd JTBD-006 (Progress the Backlog While I'm Away — durable WSJF-ranked backlog accumulation)
|
|
30
|
-
# @jtbd JTBD-201 (audit-trail — auto-ticketed observations become durable artefacts)
|
|
31
|
-
|
|
32
|
-
setup() {
|
|
33
|
-
REPO_ROOT="$(cd "$(dirname "$BATS_TEST_FILENAME")/../../../../.." && pwd)"
|
|
34
|
-
SKILL_MD="$REPO_ROOT/packages/itil/skills/work-problems/SKILL.md"
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
@test "work-problems P342: SKILL.md exists" {
|
|
38
|
-
[ -f "$SKILL_MD" ]
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
# ── Step 5 iter-prompt: capture-* carve-out for retro observations ──────────
|
|
42
|
-
|
|
43
|
-
@test "work-problems P342: iter-prompt body carves out capture-* for retro-surfaced observations" {
|
|
44
|
-
# The fix relaxes the "No capture-* siblings mid-loop" rule for RETRO
|
|
45
|
-
# observations specifically. Existing P078-class spam rule remains for
|
|
46
|
-
# non-retro mid-iter capture; the carve-out is bounded to retro.
|
|
47
|
-
run grep -nE 'retro.*capture-\*|capture-\*.*retro|retro-surfaced.*capture|capture-problem.*retro' "$SKILL_MD"
|
|
48
|
-
[ "$status" -eq 0 ]
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
@test "work-problems P342: iter-prompt body directs retro to auto-ticket via /wr-itil:capture-problem" {
|
|
52
|
-
# Recurring class-of-behaviour observations MUST route to
|
|
53
|
-
# /wr-itil:capture-problem (mechanical-stage carve-out per run-retro
|
|
54
|
-
# Step 4a precedent). The skill is named explicitly so adopters know
|
|
55
|
-
# which capture sibling to invoke.
|
|
56
|
-
run grep -nE '/wr-itil:capture-problem' "$SKILL_MD"
|
|
57
|
-
[ "$status" -eq 0 ]
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
@test "work-problems P342: iter-prompt cites Step 4a precedent for mechanical-stage carve-out" {
|
|
61
|
-
# The carve-out's authority is the run-retro Step 4a verification
|
|
62
|
-
# close-on-evidence precedent. Cite it so future authors don't unwind
|
|
63
|
-
# the carve-out by re-applying the broad "no capture-* mid-loop" rule
|
|
64
|
-
# uniformly.
|
|
65
|
-
run grep -nE 'Step 4a precedent|run-retro Step 4a|Step 4a.*mechanical' "$SKILL_MD"
|
|
66
|
-
[ "$status" -eq 0 ]
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
# ── Classification taxonomy ────────────────────────────────────────────────
|
|
70
|
-
|
|
71
|
-
@test "work-problems P342: iter-prompt classifies recurring class-of-behaviour as auto-ticket" {
|
|
72
|
-
# Recurring class-of-behaviour / SKILL-contract drift / hook
|
|
73
|
-
# misbehaviour / framework-gap → auto-ticket. The taxonomy MUST be
|
|
74
|
-
# documented so future authors don't drift on classification.
|
|
75
|
-
run grep -nE 'recurring class-of-behaviour|class-of-behaviour observation' "$SKILL_MD"
|
|
76
|
-
[ "$status" -eq 0 ]
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
@test "work-problems P342: iter-prompt classifies direction-setting as outstanding_questions" {
|
|
80
|
-
# Direction-setting (design choice, deviation-approval, framework
|
|
81
|
-
# boundary) → outstanding_questions. The route must be named so the
|
|
82
|
-
# framework boundary is preserved.
|
|
83
|
-
run grep -nE 'Direction-setting observation|direction-setting.*outstanding_questions' "$SKILL_MD"
|
|
84
|
-
[ "$status" -eq 0 ]
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
@test "work-problems P342: iter-prompt classifies ambiguous observations as default-to-auto-ticket" {
|
|
88
|
-
# Ambiguous → default to auto-ticket. This is the trust-boundary
|
|
89
|
-
# asymmetry that prevents observations from silently piling in the
|
|
90
|
-
# queue file (per P342 Description).
|
|
91
|
-
run grep -nE 'Ambiguous.*auto-ticket|default to auto-ticket|ambiguous.*default.*ticket' "$SKILL_MD"
|
|
92
|
-
[ "$status" -eq 0 ]
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
# ── Trust-boundary mirror in run-retro Step 4b ─────────────────────────────
|
|
96
|
-
|
|
97
|
-
@test "work-problems P342: iter-prompt cross-references run-retro Step 4b carve-out symmetry" {
|
|
98
|
-
# The run-retro Step 4b stage classification mirrors this carve-out so
|
|
99
|
-
# the same trust-boundary applies whether retro fires in iter context
|
|
100
|
-
# OR standalone in main turn. Cross-reference the sibling locus so the
|
|
101
|
-
# symmetry is discoverable.
|
|
102
|
-
run grep -nE 'run-retro.*Step 4b|Step 4b.*mirror|symmetry.*Step 4b|Step 4b.*carve-out' "$SKILL_MD"
|
|
103
|
-
[ "$status" -eq 0 ]
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
# ── Cross-reference to P342 ────────────────────────────────────────────────
|
|
107
|
-
|
|
108
|
-
@test "work-problems P342: Related section cites P342 as the originating ticket" {
|
|
109
|
-
run grep -nE '\*\*P342\*\*|P342\b' "$SKILL_MD"
|
|
110
|
-
[ "$status" -eq 0 ]
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
# ── Anti-pattern preservation: P130 mid-loop ask discipline unaffected ─────
|
|
114
|
-
|
|
115
|
-
@test "work-problems P342: iter-prompt preserves P130 NEVER call AskUserQuestion mid-loop discipline" {
|
|
116
|
-
# The P342 carve-out is for capture-* siblings on the retro path only;
|
|
117
|
-
# the iter-prompt's mid-loop AskUserQuestion ban is unchanged.
|
|
118
|
-
run grep -nE 'NEVER call .?AskUserQuestion.? mid-loop|MUST NOT call .?AskUserQuestion.? between iter' "$SKILL_MD"
|
|
119
|
-
[ "$status" -eq 0 ]
|
|
120
|
-
}
|
|
@@ -1,248 +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 revert-and-proceed 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 0 PRE-FLIGHT subprocess failure handling
|
|
9
|
-
# (P358). Step 0b / 0c / 0d dispatch a /wr-itil:review-problems (or
|
|
10
|
-
# check-upstream-responses) pre-flight subprocess "same shape as Step 5". But a
|
|
11
|
-
# pre-flight is a NON-load-bearing cache-refresh dependency, NOT an iter (the
|
|
12
|
-
# loop body). When a pre-flight subprocess exits non-zero OR returns
|
|
13
|
-
# `is_error: true` (e.g. `API Error: The socket connection was closed
|
|
14
|
-
# unexpectedly`), the orchestrator's contract is NON-BLOCKING:
|
|
15
|
-
# (1) revert any dirty (unstaged) partial cache/audit/README write the
|
|
16
|
-
# pre-flight left (`git checkout -- docs/problems/ docs/audits/`);
|
|
17
|
-
# (1b) if a dead pre-flight left STAGED residue, `git reset` then revert
|
|
18
|
-
# (ADR-009 no-trust-window-extension — a dead is_error:true subprocess
|
|
19
|
-
# must not seed the parent's commit);
|
|
20
|
-
# (2) log a one-line annotation;
|
|
21
|
-
# (3) proceed to Step 1 with the existing README.
|
|
22
|
-
# This is ORTHOGONAL to the Step 5 iter SALVAGE-vs-HALT axis (P261 / P214):
|
|
23
|
-
# that axis classifies an *iter's* is_error:true; this fixture classifies the
|
|
24
|
-
# *pre-flight role* — which NEVER salvages and NEVER halts the loop.
|
|
25
|
-
#
|
|
26
|
-
# The fake `claude` shim below re-creates the production shape: it dirties an
|
|
27
|
-
# unstaged cache file in the repo, then emits an is_error:true socket-closed
|
|
28
|
-
# JSON envelope (no commit). The harness re-implements the orchestrator's
|
|
29
|
-
# pre-flight failure contract (faithful to SKILL.md § "Step 0 pre-flight
|
|
30
|
-
# subprocess failure handling (P358)") and asserts the revert-and-proceed
|
|
31
|
-
# outcome across the input shapes. Adopters who copy the SKILL.md pre-flight
|
|
32
|
-
# block into their orchestrator should observe the same outcomes.
|
|
33
|
-
#
|
|
34
|
-
# @problem P358
|
|
35
|
-
# @rfc RFC-024
|
|
36
|
-
# @jtbd JTBD-006
|
|
37
|
-
#
|
|
38
|
-
# Cross-reference:
|
|
39
|
-
# P358 (claude -p subprocess dispatch socket-closed; pre-flight is_error
|
|
40
|
-
# handling gap) — driver ticket
|
|
41
|
-
# RFC-024 (work-problems pre-flight subprocess failure handling) — fix vehicle
|
|
42
|
-
# ADR-032 (governance skill invocation patterns — § "Pre-flight subprocess
|
|
43
|
-
# failure handling — non-blocking revert-and-proceed (P358 amendment)") —
|
|
44
|
-
# the iter-vs-pre-flight failure-semantics distinction this fixture pins
|
|
45
|
-
# ADR-009 (gate-marker / no-trust-window-extension — staged residue git reset)
|
|
46
|
-
# ADR-019 (preflight clean-tree reconciliation surface)
|
|
47
|
-
# P261 / P214 (the iter is_error:true SALVAGE/HALT axis this is orthogonal to)
|
|
48
|
-
# ADR-037 / ADR-052 (skill testing strategy — behavioural default; doc-lint
|
|
49
|
-
# contract assertion is the Permitted Exception, marked above)
|
|
50
|
-
|
|
51
|
-
setup() {
|
|
52
|
-
TEST_TMP="$(mktemp -d)"
|
|
53
|
-
FAKE_BIN="${TEST_TMP}/bin"
|
|
54
|
-
mkdir -p "$FAKE_BIN"
|
|
55
|
-
|
|
56
|
-
# Fake `claude` binary simulating a pre-flight subprocess of the socket-closed
|
|
57
|
-
# class: it leaves a dirty (UNSTAGED by default) partial cache write in the
|
|
58
|
-
# CWD git repo, then emits an is_error:true JSON envelope carrying the
|
|
59
|
-
# socket-closed error string in `.result`. No commit. This matches the
|
|
60
|
-
# 2026-06-10 P358 shape: a /wr-itil:review-problems pre-flight that partially
|
|
61
|
-
# refreshed docs/problems/.upstream-cache.json then died with
|
|
62
|
-
# `API Error: The socket connection was closed unexpectedly`.
|
|
63
|
-
cat > "$FAKE_BIN/claude" <<'FAKE_EOF'
|
|
64
|
-
#!/usr/bin/env bash
|
|
65
|
-
# Test fake for work-problems Step 0 pre-flight failure-handling fixture.
|
|
66
|
-
# Dirties a partial cache write, then emits is_error:true socket-closed JSON.
|
|
67
|
-
mkdir -p docs/problems
|
|
68
|
-
printf 'partial-refresh-mid-die\n' >> docs/problems/.upstream-cache.json
|
|
69
|
-
if [ "${FAKE_STAGE_RESIDUE:-0}" = "1" ]; then
|
|
70
|
-
git add docs/problems/.upstream-cache.json 2>/dev/null || true
|
|
71
|
-
fi
|
|
72
|
-
if [ "${FAKE_EXIT:-0}" != "0" ]; then
|
|
73
|
-
printf '%s\n' '{"is_error":true,"result":"subprocess crashed"}'
|
|
74
|
-
exit "${FAKE_EXIT}"
|
|
75
|
-
fi
|
|
76
|
-
printf '%s\n' '{"is_error":true,"result":"API Error: The socket connection was closed unexpectedly. For more information, pass `verbose: true`","total_cost_usd":0.0,"duration_ms":727000}'
|
|
77
|
-
FAKE_EOF
|
|
78
|
-
chmod +x "$FAKE_BIN/claude"
|
|
79
|
-
export PATH="$FAKE_BIN:$PATH"
|
|
80
|
-
|
|
81
|
-
# A throwaway git repo so dirty-detection + the revert are real. Seed a
|
|
82
|
-
# committed clean cache so the partial write is observably a dirty delta.
|
|
83
|
-
REPO="${TEST_TMP}/repo"
|
|
84
|
-
mkdir -p "$REPO/docs/problems"
|
|
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
|
-
printf 'clean-cache\n' > "$REPO/docs/problems/.upstream-cache.json"
|
|
89
|
-
git -C "$REPO" add docs/problems/.upstream-cache.json
|
|
90
|
-
git -C "$REPO" commit -q -m "root: clean cache"
|
|
91
|
-
|
|
92
|
-
SKILL_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
|
|
93
|
-
SKILL_FILE="${SKILL_DIR}/SKILL.md"
|
|
94
|
-
ADR_FILE="$(cd "${SKILL_DIR}/../../../.." && pwd)/docs/decisions/032-governance-skill-invocation-patterns.proposed.md"
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
teardown() {
|
|
98
|
-
if [ -n "${TEST_TMP:-}" ] && [ -d "$TEST_TMP" ]; then
|
|
99
|
-
rm -rf "$TEST_TMP"
|
|
100
|
-
fi
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
# Faithful re-implementation of SKILL.md § "Step 0 pre-flight subprocess failure
|
|
104
|
-
# handling (P358)". Consumes the pre-flight JSON envelope + the pre-flight exit
|
|
105
|
-
# code + the repo working-tree state, applies the non-blocking revert-and-proceed
|
|
106
|
-
# contract, and returns the orchestrator's decision. KEY PROPERTY: a pre-flight
|
|
107
|
-
# NEVER halts the loop and NEVER salvages — it reverts and proceeds.
|
|
108
|
-
preflight_failure_outcome() {
|
|
109
|
-
local json="$1"
|
|
110
|
-
local exit_code="$2"
|
|
111
|
-
local repo="$3"
|
|
112
|
-
|
|
113
|
-
local is_error
|
|
114
|
-
is_error=$(printf '%s' "$json" | python3 -c 'import json,sys; print(str(json.load(sys.stdin).get("is_error")).lower())' 2>/dev/null || echo unknown)
|
|
115
|
-
|
|
116
|
-
# Pre-flight succeeded (exit 0 AND is_error:false) → cache refreshed; proceed.
|
|
117
|
-
if [ "$exit_code" = "0" ] && [ "$is_error" = "false" ]; then
|
|
118
|
-
printf 'DECISION=PROCEED reason=preflight-ok\n'
|
|
119
|
-
return 0
|
|
120
|
-
fi
|
|
121
|
-
|
|
122
|
-
# Pre-flight FAILED (non-zero exit OR is_error:true) → NON-BLOCKING contract.
|
|
123
|
-
# Step 1b: if the dead pre-flight left STAGED residue, unstage it first
|
|
124
|
-
# (ADR-009 — a dead is_error:true subprocess must not seed the parent index).
|
|
125
|
-
if [ -n "$(git -C "$repo" diff --cached --name-only)" ]; then
|
|
126
|
-
git -C "$repo" reset -q
|
|
127
|
-
fi
|
|
128
|
-
# Step 1: revert the whole contractually-touchable path set (not just cache).
|
|
129
|
-
# Per-path tolerant — a COMBINED `git checkout -- A B` errors and reverts
|
|
130
|
-
# NOTHING when B is absent (e.g. docs/audits/ on a fresh adopter repo), so
|
|
131
|
-
# revert each path independently.
|
|
132
|
-
git -C "$repo" checkout -- docs/problems/ 2>/dev/null || true
|
|
133
|
-
git -C "$repo" checkout -- docs/audits/ 2>/dev/null || true
|
|
134
|
-
# Step 3: proceed to Step 1 (never halt).
|
|
135
|
-
printf 'DECISION=PROCEED reason=preflight-failed-reverted\n'
|
|
136
|
-
return 0
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
# ---------------------------------------------------------------------------
|
|
140
|
-
# Behavioural cases (the load-bearing core per ADR-052).
|
|
141
|
-
# ---------------------------------------------------------------------------
|
|
142
|
-
|
|
143
|
-
@test "P358: pre-flight is_error:true (socket-closed) + unstaged partial write -> revert + PROCEED (never halt)" {
|
|
144
|
-
export FAKE_STAGE_RESIDUE=0 FAKE_EXIT=0
|
|
145
|
-
local json
|
|
146
|
-
json=$( cd "$REPO" && claude -p --output-format json "PREFLIGHT" < /dev/null )
|
|
147
|
-
# The fake left a dirty partial cache write.
|
|
148
|
-
run git -C "$REPO" status --porcelain docs/problems/.upstream-cache.json
|
|
149
|
-
[ -n "$output" ]
|
|
150
|
-
run preflight_failure_outcome "$json" 0 "$REPO"
|
|
151
|
-
[ "$status" -eq 0 ]
|
|
152
|
-
[[ "$output" == *"DECISION=PROCEED"* ]]
|
|
153
|
-
[[ "$output" == *"preflight-failed-reverted"* ]]
|
|
154
|
-
# The dirty partial write was reverted — tree is clean again.
|
|
155
|
-
run git -C "$REPO" status --porcelain
|
|
156
|
-
[ -z "$output" ]
|
|
157
|
-
# The committed clean cache content survived (revert restored it).
|
|
158
|
-
run cat "$REPO/docs/problems/.upstream-cache.json"
|
|
159
|
-
[[ "$output" == "clean-cache" ]]
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
@test "P358: pre-flight non-zero exit -> revert + PROCEED (non-blocking; not a loop halt)" {
|
|
163
|
-
export FAKE_STAGE_RESIDUE=0 FAKE_EXIT=1
|
|
164
|
-
local json
|
|
165
|
-
json=$( cd "$REPO" && claude -p --output-format json "PREFLIGHT" < /dev/null || true )
|
|
166
|
-
run preflight_failure_outcome "$json" 1 "$REPO"
|
|
167
|
-
[ "$status" -eq 0 ]
|
|
168
|
-
[[ "$output" == *"DECISION=PROCEED"* ]]
|
|
169
|
-
# Crucially NOT a HALT — a pre-flight failure does not stop the loop.
|
|
170
|
-
[[ "$output" != *"HALT"* ]]
|
|
171
|
-
run git -C "$REPO" status --porcelain
|
|
172
|
-
[ -z "$output" ]
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
@test "P358: pre-flight left STAGED residue -> git reset then revert (ADR-009 no-seed-parent-index)" {
|
|
176
|
-
export FAKE_STAGE_RESIDUE=1 FAKE_EXIT=0
|
|
177
|
-
local json
|
|
178
|
-
json=$( cd "$REPO" && claude -p --output-format json "PREFLIGHT" < /dev/null )
|
|
179
|
-
# The fake STAGED the partial write.
|
|
180
|
-
run git -C "$REPO" diff --cached --name-only
|
|
181
|
-
[[ "$output" == *".upstream-cache.json"* ]]
|
|
182
|
-
run preflight_failure_outcome "$json" 0 "$REPO"
|
|
183
|
-
[ "$status" -eq 0 ]
|
|
184
|
-
[[ "$output" == *"DECISION=PROCEED"* ]]
|
|
185
|
-
# Staged residue was unstaged AND reverted — index + tree both clean.
|
|
186
|
-
run git -C "$REPO" diff --cached --name-only
|
|
187
|
-
[ -z "$output" ]
|
|
188
|
-
run git -C "$REPO" status --porcelain
|
|
189
|
-
[ -z "$output" ]
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
@test "P358: pre-flight success (exit 0 + is_error:false) -> PROCEED without revert" {
|
|
193
|
-
# Hand-build a clean success envelope (the fake always fails by design).
|
|
194
|
-
local json='{"is_error":false,"result":"refreshed"}'
|
|
195
|
-
run preflight_failure_outcome "$json" 0 "$REPO"
|
|
196
|
-
[ "$status" -eq 0 ]
|
|
197
|
-
[[ "$output" == *"DECISION=PROCEED"* ]]
|
|
198
|
-
[[ "$output" == *"preflight-ok"* ]]
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
# ---------------------------------------------------------------------------
|
|
202
|
-
# Doc-lint contract assertions (Permitted Exception per ADR-037; structural
|
|
203
|
-
# slice marked at top of file per ADR-052 Surface 2). These guard the SKILL.md
|
|
204
|
-
# / ADR-032 prose against drift away from the behavioural contract above.
|
|
205
|
-
# ---------------------------------------------------------------------------
|
|
206
|
-
|
|
207
|
-
@test "P358: SKILL.md documents the Step 0 pre-flight failure-handling subsection" {
|
|
208
|
-
run grep -niE "pre-flight subprocess failure handling.{0,40}P358|Step 0 pre-flight subprocess failure" "$SKILL_FILE"
|
|
209
|
-
[ "$status" -eq 0 ]
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
@test "P358: SKILL.md pre-flight contract names the non-blocking revert-and-proceed rule" {
|
|
213
|
-
run grep -niE "non-?blocking" "$SKILL_FILE"
|
|
214
|
-
[ "$status" -eq 0 ]
|
|
215
|
-
run grep -niE "revert.{0,40}(proceed|partial)|proceed to Step 1 with the existing" "$SKILL_FILE"
|
|
216
|
-
[ "$status" -eq 0 ]
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
@test "P358: SKILL.md distinguishes pre-flight (cache-refresh dependency) from iter (loop body)" {
|
|
220
|
-
run grep -niE "non-load-bearing cache-refresh dependency" "$SKILL_FILE"
|
|
221
|
-
[ "$status" -eq 0 ]
|
|
222
|
-
run grep -niE "iter IS the loop body|the iter is the loop body" "$SKILL_FILE"
|
|
223
|
-
[ "$status" -eq 0 ]
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
@test "P358: SKILL.md pre-flight forward-pointer fires in the 0b/0c/0d dispatch paragraphs" {
|
|
227
|
-
# At least three "do NOT halt the loop (a failed pre-flight ...)" pointers.
|
|
228
|
-
run bash -c "grep -ciE 'do NOT halt the loop .a failed pre-flight' '$SKILL_FILE'"
|
|
229
|
-
[ "$status" -eq 0 ]
|
|
230
|
-
[ "$output" -ge 3 ]
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
@test "P358: SKILL.md pre-flight contract cites P358" {
|
|
234
|
-
run grep -nE "P358" "$SKILL_FILE"
|
|
235
|
-
[ "$status" -eq 0 ]
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
@test "P358: ADR-032 carries the pre-flight failure-handling P358 amendment" {
|
|
239
|
-
run grep -niE "Pre-flight subprocess failure handling.{0,60}P358 amendment" "$ADR_FILE"
|
|
240
|
-
[ "$status" -eq 0 ]
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
@test "P358: ADR-032 amendment names the iter-vs-pre-flight failure-semantics axis as orthogonal to SALVAGE/HALT" {
|
|
244
|
-
run grep -niE "orthogonal" "$ADR_FILE"
|
|
245
|
-
[ "$status" -eq 0 ]
|
|
246
|
-
run grep -niE "No SALVAGE for a pre-flight|SALVAGE branch does NOT apply to a pre-flight" "$ADR_FILE"
|
|
247
|
-
[ "$status" -eq 0 ]
|
|
248
|
-
}
|
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bats
|
|
2
|
-
# Contract-assertion bats for work-problems Step 0 session-continuity
|
|
3
|
-
# detection (the extension per P109).
|
|
4
|
-
#
|
|
5
|
-
# Per ADR-037 SKILL.md is a contract document; these assertions check the
|
|
6
|
-
# contract strings the skill prose authoritatively pins for the Step 0
|
|
7
|
-
# session-continuity detection pass. Follows the split pattern established
|
|
8
|
-
# by work-problems-preflight.bats (fetch/divergence assertions) — this file
|
|
9
|
-
# covers the second invariant family: prior-session partial-work signals +
|
|
10
|
-
# interactive/AFK routing.
|
|
11
|
-
#
|
|
12
|
-
# Cross-reference:
|
|
13
|
-
# @problem P109 (work-problems preflight does not detect prior-session partial-work state)
|
|
14
|
-
# ADR-019 (AFK orchestrator preflight — extension scope)
|
|
15
|
-
# ADR-013 (structured user interaction — Rule 1 interactive, Rule 6 non-interactive fail-safe)
|
|
16
|
-
# ADR-032 (governance skill invocation patterns — .afk-run-state/iter-*.json contract)
|
|
17
|
-
# ADR-037 (skill testing strategy — contract-assertion framing)
|
|
18
|
-
# @jtbd JTBD-006 (Progress the Backlog While I'm Away — session-continuity detection belongs in Step 0)
|
|
19
|
-
|
|
20
|
-
setup() {
|
|
21
|
-
SKILL_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
|
|
22
|
-
SKILL_FILE="${SKILL_DIR}/SKILL.md"
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
@test "SKILL.md exists" {
|
|
26
|
-
[ -f "$SKILL_FILE" ]
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
@test "SKILL.md Step 0 cites P109 (session-continuity driver)" {
|
|
30
|
-
# Contract criterion: the extension is traceable to its driver ticket.
|
|
31
|
-
run grep -n "P109" "$SKILL_FILE"
|
|
32
|
-
[ "$status" -eq 0 ]
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
@test "SKILL.md Step 0 names the session-continuity detection pass" {
|
|
36
|
-
# Contract criterion: the new detection pass is named as a discrete
|
|
37
|
-
# concept in the Step 0 prose (not buried under the divergence check).
|
|
38
|
-
run grep -niE "session.continuity" "$SKILL_FILE"
|
|
39
|
-
[ "$status" -eq 0 ]
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
@test "SKILL.md Step 0 enumerates untracked docs/decisions/*.proposed.md signal" {
|
|
43
|
-
# Contract criterion: drafted-but-unlanded ADRs are one of the signals
|
|
44
|
-
# the session-continuity detection pass MUST enumerate.
|
|
45
|
-
run grep -nE "docs/decisions/\*\.proposed\.md|docs/decisions/.*\.proposed\.md" "$SKILL_FILE"
|
|
46
|
-
[ "$status" -eq 0 ]
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
@test "SKILL.md Step 0 enumerates untracked docs/problems/*.md signal" {
|
|
50
|
-
# Contract criterion: drafted-but-unlanded problem tickets are enumerated
|
|
51
|
-
# as one of the session-continuity signals. The preflight section already
|
|
52
|
-
# references docs/problems/ for the scan surface; the test checks that
|
|
53
|
-
# the Preflight section names untracked problem files as a detection
|
|
54
|
-
# signal (not merely the backlog-scan surface).
|
|
55
|
-
run grep -niE "untracked.*docs/problems|docs/problems/.*untracked" "$SKILL_FILE"
|
|
56
|
-
[ "$status" -eq 0 ]
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
@test "SKILL.md Step 0 enumerates .afk-run-state/iter-*.json error signal" {
|
|
60
|
-
# Contract criterion: the .afk-run-state/iter-*.json subprocess artefacts
|
|
61
|
-
# (per ADR-032) with is_error: true or api_error_status >= 400 are named
|
|
62
|
-
# as a signal.
|
|
63
|
-
run grep -nE "\.afk-run-state/iter-\*\.json|\.afk-run-state/iter-.*\.json" "$SKILL_FILE"
|
|
64
|
-
[ "$status" -eq 0 ]
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
@test "SKILL.md Step 0 names the is_error / api_error_status fields" {
|
|
68
|
-
# Contract criterion: the specific JSON fields the detection pass reads
|
|
69
|
-
# are named verbatim so the contract is unambiguous.
|
|
70
|
-
run grep -niE "is_error.*true|api_error_status" "$SKILL_FILE"
|
|
71
|
-
[ "$status" -eq 0 ]
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
@test "SKILL.md Step 0 enumerates stale .claude/worktrees signal" {
|
|
75
|
-
# Contract criterion: stale subagent worktrees are a detection signal.
|
|
76
|
-
# Detection only (not cleanup/mutation — per P109 scope boundary).
|
|
77
|
-
run grep -nE "\.claude/worktrees" "$SKILL_FILE"
|
|
78
|
-
[ "$status" -eq 0 ]
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
@test "SKILL.md Step 0 enumerates git worktree list signal for claude/* branches" {
|
|
82
|
-
# Contract criterion: git worktree list is the detection mechanism for
|
|
83
|
-
# claude/* branches adjacent to the .claude/worktrees/ dir check.
|
|
84
|
-
run grep -niE "git worktree list" "$SKILL_FILE"
|
|
85
|
-
[ "$status" -eq 0 ]
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
@test "SKILL.md Step 0 enumerates uncommitted SKILL.md / source / ADR edits signal" {
|
|
89
|
-
# Contract criterion: mid-authoring source edits are a detection signal.
|
|
90
|
-
run grep -niE "uncommitted.*(SKILL\.md|source|ADR)|(SKILL\.md|source|ADR).*uncommitted" "$SKILL_FILE"
|
|
91
|
-
[ "$status" -eq 0 ]
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
@test "SKILL.md Step 0 routes interactive via AskUserQuestion" {
|
|
95
|
-
# Contract criterion per ADR-013 Rule 1: the interactive branch uses
|
|
96
|
-
# AskUserQuestion.
|
|
97
|
-
run grep -nE "AskUserQuestion" "$SKILL_FILE"
|
|
98
|
-
[ "$status" -eq 0 ]
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
@test "SKILL.md Step 0 interactive branch names the 4 option categories" {
|
|
102
|
-
# Contract criterion: the AskUserQuestion 4-option shape is pinned so
|
|
103
|
-
# adopters know the branch set. Resume / discard / leave-and-lower-priority / halt.
|
|
104
|
-
run grep -niE "resume" "$SKILL_FILE"
|
|
105
|
-
[ "$status" -eq 0 ]
|
|
106
|
-
run grep -niE "discard" "$SKILL_FILE"
|
|
107
|
-
[ "$status" -eq 0 ]
|
|
108
|
-
run grep -niE "leave.*lower.priority|leave.and.lower.priority" "$SKILL_FILE"
|
|
109
|
-
[ "$status" -eq 0 ]
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
@test "SKILL.md Step 0 routes AFK via halt-with-report per ADR-013 Rule 6" {
|
|
113
|
-
# Contract criterion per ADR-013 Rule 6: the non-interactive / AFK branch
|
|
114
|
-
# halts with a report rather than silently choosing.
|
|
115
|
-
run grep -niE "halt.with.report|halt with report|Rule 6 fail.safe" "$SKILL_FILE"
|
|
116
|
-
[ "$status" -eq 0 ]
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
@test "SKILL.md Step 0 cites ADR-013 Rule 6 for AFK fail-safe" {
|
|
120
|
-
# Contract criterion: ADR-013 Rule 6 is named as the authority for the
|
|
121
|
-
# non-interactive halt branch.
|
|
122
|
-
run grep -nE "ADR-013.*Rule 6|Rule 6.*ADR-013" "$SKILL_FILE"
|
|
123
|
-
[ "$status" -eq 0 ]
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
@test "SKILL.md Step 0 emits a structured Prior-Session State report" {
|
|
127
|
-
# Contract criterion: the AFK halt branch surfaces a structured report,
|
|
128
|
-
# not a free-text prose blurb — so the user can act on it on return.
|
|
129
|
-
run grep -niE "Prior.Session State" "$SKILL_FILE"
|
|
130
|
-
[ "$status" -eq 0 ]
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
@test "SKILL.md Non-Interactive Decision Making table covers session-continuity" {
|
|
134
|
-
# Contract criterion: the decision-matrix section surfaces the new branch
|
|
135
|
-
# so adopters of the skill can find the AFK default without reading
|
|
136
|
-
# Step 0 prose in full.
|
|
137
|
-
run grep -niE "Prior.session partial.work|session.continuity.*dirty|Prior-Session State.*AFK" "$SKILL_FILE"
|
|
138
|
-
[ "$status" -eq 0 ]
|
|
139
|
-
}
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bats
|
|
2
|
-
# Doc-lint guard: work-problems SKILL.md must include the preflight
|
|
3
|
-
# (fetch-origin + divergence handling) per ADR-019.
|
|
4
|
-
#
|
|
5
|
-
# Structural assertion — Permitted Exception to the source-grep ban (ADR-005 / P011).
|
|
6
|
-
# These tests assert that the skill specification document contains the
|
|
7
|
-
# preflight step so the AFK orchestrator does not iterate against a stale
|
|
8
|
-
# local backlog when origin/<base> has advanced.
|
|
9
|
-
#
|
|
10
|
-
# Cross-reference:
|
|
11
|
-
# P040 (work-problems does not fetch origin before starting)
|
|
12
|
-
# ADR-019 (AFK orchestrator preflight)
|
|
13
|
-
# @jtbd JTBD-006 (Progress the Backlog While I'm Away)
|
|
14
|
-
|
|
15
|
-
setup() {
|
|
16
|
-
SKILL_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
|
|
17
|
-
SKILL_FILE="${SKILL_DIR}/SKILL.md"
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
@test "SKILL.md cites ADR-019 (preflight)" {
|
|
21
|
-
# ADR-019 confirmation criterion: skill must reference the ADR.
|
|
22
|
-
run grep -n "ADR-019" "$SKILL_FILE"
|
|
23
|
-
[ "$status" -eq 0 ]
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
@test "SKILL.md preflight runs git fetch origin" {
|
|
27
|
-
# ADR-019 mechanism: must run `git fetch origin` before opening the
|
|
28
|
-
# work loop.
|
|
29
|
-
run grep -n "git fetch origin" "$SKILL_FILE"
|
|
30
|
-
[ "$status" -eq 0 ]
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
@test "SKILL.md preflight uses git pull --ff-only on trivial divergence" {
|
|
34
|
-
# ADR-019 mechanism: trivial fast-forward is policy-authorised; non-ff is
|
|
35
|
-
# not. The skill must cite --ff-only to prevent merge attempts.
|
|
36
|
-
run grep -n "ff-only" "$SKILL_FILE"
|
|
37
|
-
[ "$status" -eq 0 ]
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
@test "SKILL.md preflight stops the loop on non-fast-forward divergence" {
|
|
41
|
-
# Confirmation: divergence handling must include a stop-with-report path,
|
|
42
|
-
# not a silent retry or merge.
|
|
43
|
-
run grep -niE "non-fast-forward|non-ff" "$SKILL_FILE"
|
|
44
|
-
[ "$status" -eq 0 ]
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
@test "SKILL.md preflight has a discrete step before backlog scan" {
|
|
48
|
-
# The preflight should appear as a discrete step (e.g. Step 0 — Preflight)
|
|
49
|
-
# so it is not buried in prose.
|
|
50
|
-
run grep -niE "step 0|preflight" "$SKILL_FILE"
|
|
51
|
-
[ "$status" -eq 0 ]
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
@test "SKILL.md Non-Interactive Decision Making table covers origin divergence" {
|
|
55
|
-
# ADR-019 confirmation: the non-interactive defaults table must include a
|
|
56
|
-
# row for the divergence decision.
|
|
57
|
-
run grep -niE "Origin diverged|origin.*divergence|fast-forward" "$SKILL_FILE"
|
|
58
|
-
[ "$status" -eq 0 ]
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
@test "SKILL.md explicitly forbids non-interactive merge/rebase remediation" {
|
|
62
|
-
# ADR-019 forbids non-interactive rebase/merge attempts. The skill must
|
|
63
|
-
# negate these (e.g. "Do NOT attempt to rebase or merge" or "are NOT
|
|
64
|
-
# policy-authorised") rather than silently allow them. We assert the
|
|
65
|
-
# negation appears, not that the words are absent — discussing forbidden
|
|
66
|
-
# operations in the negative is exactly what the ADR requires.
|
|
67
|
-
run grep -niE "Do NOT attempt to rebase or merge|NOT policy-authorised" "$SKILL_FILE"
|
|
68
|
-
[ "$status" -eq 0 ]
|
|
69
|
-
}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bats
|
|
2
|
-
# Doc-lint guard: work-problems SKILL.md must include the inter-iteration
|
|
3
|
-
# release-cadence check per ADR-018.
|
|
4
|
-
#
|
|
5
|
-
# Structural assertion — Permitted Exception to the source-grep ban (ADR-005 / P011).
|
|
6
|
-
# These tests assert that the skill specification document contains the
|
|
7
|
-
# release-cadence step so the AFK orchestrator does not silently accumulate
|
|
8
|
-
# unreleased changesets across iterations.
|
|
9
|
-
#
|
|
10
|
-
# Cross-reference:
|
|
11
|
-
# P041 (work-problems does not enforce release cadence)
|
|
12
|
-
# ADR-018 (inter-iteration release cadence for AFK loops)
|
|
13
|
-
# @jtbd JTBD-006 (Progress the Backlog While I'm Away)
|
|
14
|
-
|
|
15
|
-
setup() {
|
|
16
|
-
SKILL_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
|
|
17
|
-
SKILL_FILE="${SKILL_DIR}/SKILL.md"
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
@test "SKILL.md exists" {
|
|
21
|
-
[ -f "$SKILL_FILE" ]
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
@test "SKILL.md cites ADR-018 (release cadence)" {
|
|
25
|
-
# ADR-018 confirmation criterion: skill must reference the ADR.
|
|
26
|
-
run grep -n "ADR-018" "$SKILL_FILE"
|
|
27
|
-
[ "$status" -eq 0 ]
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
@test "SKILL.md delegates to wr-risk-scorer:assess-release (preserves pure-scorer contract from ADR-015)" {
|
|
31
|
-
# ADR-018 mechanism: must delegate to the assess-release skill rather than
|
|
32
|
-
# re-implementing risk scoring inline.
|
|
33
|
-
run grep -n "assess-release" "$SKILL_FILE"
|
|
34
|
-
[ "$status" -eq 0 ]
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
@test "SKILL.md references release:watch as the drain mechanism" {
|
|
38
|
-
# ADR-018 mechanism: drain action runs npm run release:watch (after
|
|
39
|
-
# push:watch) when the queue hits appetite.
|
|
40
|
-
run grep -n "release:watch" "$SKILL_FILE"
|
|
41
|
-
[ "$status" -eq 0 ]
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
@test "SKILL.md references push:watch as part of the drain mechanism" {
|
|
45
|
-
# ADR-018 mechanism: drain action runs push:watch before release:watch.
|
|
46
|
-
run grep -n "push:watch" "$SKILL_FILE"
|
|
47
|
-
[ "$status" -eq 0 ]
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
@test "SKILL.md has a release-cadence step between iterations" {
|
|
51
|
-
# The inter-iteration check should appear as a discrete step or subsection
|
|
52
|
-
# so it is not buried in prose.
|
|
53
|
-
run grep -niE "release.cadence|cadence check|release queue" "$SKILL_FILE"
|
|
54
|
-
[ "$status" -eq 0 ]
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
@test "SKILL.md Non-Interactive Decision Making table covers pipeline risk at appetite" {
|
|
58
|
-
# ADR-018 confirmation criterion: the non-interactive defaults table must
|
|
59
|
-
# include a row for the release-drain decision, otherwise an AFK reader
|
|
60
|
-
# cannot find the rule.
|
|
61
|
-
run grep -niE "Pipeline risk at appetite|release queue.*appetite|drain.*release" "$SKILL_FILE"
|
|
62
|
-
[ "$status" -eq 0 ]
|
|
63
|
-
}
|