@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,317 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bats
|
|
2
|
-
# Behavioural fixtures for /wr-itil:capture-story (P170 Phase 2 Slice 7).
|
|
3
|
-
#
|
|
4
|
-
# Per ADR-052 (Behavioural-tests-default for skill testing), these tests
|
|
5
|
-
# exercise the load-bearing primitives the skill dispatches and assert
|
|
6
|
-
# observable state — NOT the prose contents of SKILL.md.
|
|
7
|
-
#
|
|
8
|
-
# Behavioural surfaces under test:
|
|
9
|
-
# 1. Next-ID computation — capture-story uses the inline
|
|
10
|
-
# max(local, origin) + 1 formula scanning docs/stories/*/STORY-*.md
|
|
11
|
-
# + git ls-tree -r origin/main docs/stories/ per ADR-019 inline
|
|
12
|
-
# collision-guard approved at Slice 3 design review (option a).
|
|
13
|
-
# 2. ID collision-on-origin renumber — when an origin RFC IS not yet
|
|
14
|
-
# pulled locally, the formula must compute the higher of the two
|
|
15
|
-
# and increment from there (no silent collision).
|
|
16
|
-
# 3. Reverse-trace helper "Stories" section-name support — the three
|
|
17
|
-
# Slice 2a/2b helpers (update-problem / update-jtbd / update-rfc
|
|
18
|
-
# -references-section.sh) must accept "Stories" as a section name.
|
|
19
|
-
# 4. Frontmatter shape — a captured story file conforms to ADR-060
|
|
20
|
-
# lines 220-228 (status: draft / story-id / problems / jtbd / etc.).
|
|
21
|
-
# 5. NO update-story-references-section.sh "Stories" path —
|
|
22
|
-
# story-maps are HTML; the story-tier reverse-trace helper does NOT
|
|
23
|
-
# accept "Stories" (per architect amend finding 2 on Slice 7).
|
|
24
|
-
#
|
|
25
|
-
# @problem P170
|
|
26
|
-
# @jtbd JTBD-008 (Decompose a Fix Into Coordinated Changes — capture-time
|
|
27
|
-
# decomposition surface)
|
|
28
|
-
# @jtbd JTBD-001 (extended scope — change-set-level governance)
|
|
29
|
-
# @adr ADR-060 (Problem-RFC-Story framework — story tier)
|
|
30
|
-
# @adr ADR-052 (Behavioural-tests-default)
|
|
31
|
-
# @adr ADR-019 (ID collision-on-origin renumber)
|
|
32
|
-
# @adr ADR-014 (single-commit grain)
|
|
33
|
-
|
|
34
|
-
setup() {
|
|
35
|
-
REPO_ROOT="$(cd "$(dirname "$BATS_TEST_FILENAME")/../../../../.." && pwd)"
|
|
36
|
-
SKILL_FILE="${REPO_ROOT}/packages/itil/skills/capture-story/SKILL.md"
|
|
37
|
-
HELPER_PROBLEM="${REPO_ROOT}/packages/itil/scripts/update-problem-references-section.sh"
|
|
38
|
-
HELPER_JTBD="${REPO_ROOT}/packages/itil/scripts/update-jtbd-references-section.sh"
|
|
39
|
-
HELPER_RFC="${REPO_ROOT}/packages/itil/scripts/update-rfc-references-section.sh"
|
|
40
|
-
HELPER_STORY="${REPO_ROOT}/packages/itil/scripts/update-story-references-section.sh"
|
|
41
|
-
|
|
42
|
-
TMPROOT=$(mktemp -d)
|
|
43
|
-
ORIG_DIR="$PWD"
|
|
44
|
-
cd "$TMPROOT"
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
teardown() {
|
|
48
|
-
cd "$ORIG_DIR"
|
|
49
|
-
rm -rf "$TMPROOT"
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
# ---------------------------------------------------------------------------
|
|
53
|
-
# Surface 0: SKILL.md exists with correct name (minimum discoverability)
|
|
54
|
-
# ---------------------------------------------------------------------------
|
|
55
|
-
|
|
56
|
-
@test "capture-story: SKILL.md exists" {
|
|
57
|
-
[ -f "$SKILL_FILE" ]
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
@test "capture-story: SKILL.md frontmatter declares wr-itil:capture-story name" {
|
|
61
|
-
# Discoverable on / autocomplete depends on the canonical name.
|
|
62
|
-
run grep -E '^name: wr-itil:capture-story$' "$SKILL_FILE"
|
|
63
|
-
[ "$status" -eq 0 ]
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
# ---------------------------------------------------------------------------
|
|
67
|
-
# Surface 1: Next-ID computation — inline formula matches capture-rfc precedent
|
|
68
|
-
# (verified against a fixture stories directory).
|
|
69
|
-
# ---------------------------------------------------------------------------
|
|
70
|
-
|
|
71
|
-
@test "capture-story: next-ID formula computes 001 for empty stories directory" {
|
|
72
|
-
mkdir -p docs/stories/draft
|
|
73
|
-
local_max=$(ls docs/stories/*/STORY-*.md 2>/dev/null | sed 's|.*/STORY-||;s|-.*||' | grep -oE '^[0-9]+' | sort -n | tail -1)
|
|
74
|
-
origin_max="" # no git fixture; treat as empty
|
|
75
|
-
next=$(printf '%03d' $(( 10#$(echo -e "${local_max:-0}\n${origin_max:-0}" | sort -n | tail -1) + 1 )))
|
|
76
|
-
[ "$next" = "001" ]
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
@test "capture-story: next-ID formula computes 003 when STORY-002 exists locally" {
|
|
80
|
-
mkdir -p docs/stories/draft docs/stories/in-progress
|
|
81
|
-
touch docs/stories/draft/STORY-002-foo.md
|
|
82
|
-
touch docs/stories/in-progress/STORY-001-bar.md
|
|
83
|
-
local_max=$(ls docs/stories/*/STORY-*.md 2>/dev/null | sed 's|.*/STORY-||;s|-.*||' | grep -oE '^[0-9]+' | sort -n | tail -1)
|
|
84
|
-
next=$(printf '%03d' $(( 10#${local_max:-0} + 1 )))
|
|
85
|
-
[ "$next" = "003" ]
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
@test "capture-story: next-ID formula picks max(local, origin) when origin is higher (collision-on-origin renumber)" {
|
|
89
|
-
# Simulates the renumber: local has STORY-002, origin has STORY-005.
|
|
90
|
-
# Formula must pick 005 + 1 = 006, not 002 + 1 = 003 (silent collision).
|
|
91
|
-
local_max=2
|
|
92
|
-
origin_max=5
|
|
93
|
-
next=$(printf '%03d' $(( 10#$(echo -e "${local_max:-0}\n${origin_max:-0}" | sort -n | tail -1) + 1 )))
|
|
94
|
-
[ "$next" = "006" ]
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
@test "capture-story: next-ID formula picks max(local, origin) when local is higher" {
|
|
98
|
-
# Reverse case: local STORY-007, origin STORY-003. Local wins → 008.
|
|
99
|
-
local_max=7
|
|
100
|
-
origin_max=3
|
|
101
|
-
next=$(printf '%03d' $(( 10#$(echo -e "${local_max:-0}\n${origin_max:-0}" | sort -n | tail -1) + 1 )))
|
|
102
|
-
[ "$next" = "008" ]
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
# ---------------------------------------------------------------------------
|
|
106
|
-
# Surface 2: Reverse-trace helpers accept "Stories" section name
|
|
107
|
-
# (Slice 2a/2b shipped these — verify they're still wired correctly).
|
|
108
|
-
# ---------------------------------------------------------------------------
|
|
109
|
-
|
|
110
|
-
@test "capture-story: update-problem-references-section.sh accepts 'Stories' section name without rejecting" {
|
|
111
|
-
# Set up minimal fixture: a problem file with a Story Maps placeholder
|
|
112
|
-
# section. The helper should accept "Stories" as a valid lookup key
|
|
113
|
-
# (architect finding on Slice 7: the absence of Stories support here
|
|
114
|
-
# would block the inline reverse-trace refresh in capture-story Step 6).
|
|
115
|
-
mkdir -p docs/problems/known-error docs/stories/draft
|
|
116
|
-
cat > docs/problems/known-error/170-test-problem.md <<EOF
|
|
117
|
-
# P170: Test problem
|
|
118
|
-
|
|
119
|
-
## Story Maps
|
|
120
|
-
|
|
121
|
-
(empty)
|
|
122
|
-
|
|
123
|
-
## Stories
|
|
124
|
-
|
|
125
|
-
(empty)
|
|
126
|
-
EOF
|
|
127
|
-
run bash "$HELPER_PROBLEM" docs/problems/known-error/170-test-problem.md Stories
|
|
128
|
-
# Acceptable outcomes: success (0) or no-op-with-stderr; rejection (e.g.
|
|
129
|
-
# "unknown section-name") would fail this assertion.
|
|
130
|
-
[[ "$output" != *"unknown section-name"* ]]
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
@test "capture-story: update-jtbd-references-section.sh accepts 'Stories' section name" {
|
|
134
|
-
mkdir -p docs/jtbd/solo-developer docs/stories/draft
|
|
135
|
-
cat > docs/jtbd/solo-developer/JTBD-008-test.proposed.md <<EOF
|
|
136
|
-
# JTBD-008: Test
|
|
137
|
-
|
|
138
|
-
## Stories
|
|
139
|
-
|
|
140
|
-
(empty)
|
|
141
|
-
EOF
|
|
142
|
-
run bash "$HELPER_JTBD" docs/jtbd/solo-developer/JTBD-008-test.proposed.md Stories
|
|
143
|
-
[[ "$output" != *"unknown section-name"* ]]
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
@test "capture-story: update-rfc-references-section.sh accepts 'Stories' section name" {
|
|
147
|
-
mkdir -p docs/rfcs docs/stories/draft
|
|
148
|
-
cat > docs/rfcs/RFC-002-test.verifying.md <<EOF
|
|
149
|
-
# RFC-002: Test
|
|
150
|
-
|
|
151
|
-
## Stories
|
|
152
|
-
|
|
153
|
-
(empty)
|
|
154
|
-
EOF
|
|
155
|
-
run bash "$HELPER_RFC" docs/rfcs/RFC-002-test.verifying.md Stories
|
|
156
|
-
[[ "$output" != *"unknown section-name"* ]]
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
# ---------------------------------------------------------------------------
|
|
160
|
-
# Surface 3: NO update-story-references-section.sh "Stories" path
|
|
161
|
-
# (architect amend finding 2 on Slice 7 — story-maps are HTML, no markdown
|
|
162
|
-
# reverse-trace section auto-maintained on the HTML map; capture-story does
|
|
163
|
-
# NOT stage story-map files.)
|
|
164
|
-
# ---------------------------------------------------------------------------
|
|
165
|
-
|
|
166
|
-
@test "capture-story: update-story-references-section.sh does NOT accept 'Stories' section name (architect finding 2 — story-maps are HTML, manually authored)" {
|
|
167
|
-
mkdir -p docs/stories/draft
|
|
168
|
-
cat > docs/stories/draft/STORY-001-test.md <<EOF
|
|
169
|
-
# STORY-001: Test
|
|
170
|
-
EOF
|
|
171
|
-
run bash "$HELPER_STORY" docs/stories/draft/STORY-001-test.md Stories
|
|
172
|
-
# The helper's lookup table supports RFCs + Story Maps but NOT Stories
|
|
173
|
-
# (per architect finding 2). The helper MUST exit non-zero AND name
|
|
174
|
-
# the supported sections in its error stream.
|
|
175
|
-
[ "$status" -ne 0 ]
|
|
176
|
-
[[ "$output" == *"unknown section-name"* ]] || [[ "$output" == *"Supported"* ]]
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
# ---------------------------------------------------------------------------
|
|
180
|
-
# Surface 4: Frontmatter shape — verify ADR-060 lines 220-228 fields
|
|
181
|
-
# round-trip through a minimal capture sequence.
|
|
182
|
-
# ---------------------------------------------------------------------------
|
|
183
|
-
|
|
184
|
-
@test "capture-story: captured frontmatter contains required fields per ADR-060 lines 220-228" {
|
|
185
|
-
# Construct the frontmatter the way the skill prescribes (Step 5).
|
|
186
|
-
mkdir -p docs/stories/draft
|
|
187
|
-
next_id="001"
|
|
188
|
-
slug="test-capture"
|
|
189
|
-
description="Test capture"
|
|
190
|
-
reported=$(date -u +%Y-%m-%d)
|
|
191
|
-
cat > "docs/stories/draft/STORY-${next_id}-${slug}.md" <<EOF
|
|
192
|
-
---
|
|
193
|
-
status: draft
|
|
194
|
-
story-id: ${slug}
|
|
195
|
-
reported: ${reported}
|
|
196
|
-
decision-makers: [Test]
|
|
197
|
-
problems: [P170]
|
|
198
|
-
jtbd: [JTBD-008]
|
|
199
|
-
rfcs: []
|
|
200
|
-
story-maps: [STORY-MAP-001]
|
|
201
|
-
estimated-effort: M
|
|
202
|
-
---
|
|
203
|
-
|
|
204
|
-
# STORY-${next_id}: ${description}
|
|
205
|
-
EOF
|
|
206
|
-
# Assert each required frontmatter field appears (grep is sufficient —
|
|
207
|
-
# ADR-052 prefers behavioural assertion on the observable file state).
|
|
208
|
-
story_file="docs/stories/draft/STORY-${next_id}-${slug}.md"
|
|
209
|
-
for field in status story-id reported decision-makers problems jtbd rfcs story-maps estimated-effort; do
|
|
210
|
-
run grep -E "^${field}:" "$story_file"
|
|
211
|
-
[ "$status" -eq 0 ]
|
|
212
|
-
done
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
@test "capture-story: I8-at-capture invariant — a valid captured story has a NON-EMPTY story-maps: (ADR-095)" {
|
|
216
|
-
mkdir -p docs/stories/draft
|
|
217
|
-
cat > docs/stories/draft/STORY-001-mapped.md <<EOF
|
|
218
|
-
---
|
|
219
|
-
status: draft
|
|
220
|
-
story-maps: [STORY-MAP-002]
|
|
221
|
-
---
|
|
222
|
-
EOF
|
|
223
|
-
run grep -E '^story-maps: \[STORY-MAP-[0-9]' docs/stories/draft/STORY-001-mapped.md
|
|
224
|
-
[ "$status" -eq 0 ]
|
|
225
|
-
run grep -E '^story-maps: \[\]' docs/stories/draft/STORY-001-mapped.md
|
|
226
|
-
[ "$status" -ne 0 ]
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
@test "capture-story: SKILL prescribes refuse-and-route on a missing story-map trace (I8/ADR-095)" {
|
|
230
|
-
run grep -E 'I8 hard-block AT CAPTURE|refuse-and-route|missing-story-map-trace' "$SKILL_FILE"
|
|
231
|
-
[ "$status" -eq 0 ]
|
|
232
|
-
run grep -E 'story-map traces are optional at capture' "$SKILL_FILE"
|
|
233
|
-
[ "$status" -ne 0 ]
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
@test "capture-story: captured story file lands at docs/stories/draft/ per ADR-060 lines 145-147" {
|
|
237
|
-
# Story-maps use HTML and lifecycle subdirs (draft/accepted/in-progress/
|
|
238
|
-
# completed/archived); stories use markdown and lifecycle subdirs
|
|
239
|
-
# (draft/accepted/in-progress/done/archived). Captured story lands at
|
|
240
|
-
# draft/ per the skill's Step 5 prescription.
|
|
241
|
-
mkdir -p docs/stories/draft
|
|
242
|
-
touch docs/stories/draft/STORY-001-test.md
|
|
243
|
-
[ -f docs/stories/draft/STORY-001-test.md ]
|
|
244
|
-
# Negative assertion: NOT in any other subdir at capture time.
|
|
245
|
-
[ ! -f docs/stories/accepted/STORY-001-test.md ]
|
|
246
|
-
[ ! -f docs/stories/in-progress/STORY-001-test.md ]
|
|
247
|
-
[ ! -f docs/stories/done/STORY-001-test.md ]
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
# --- P474 / STORY-054: the lifecycle mirror must stay gone ---------------------
|
|
251
|
-
# A `**Status**:` body line duplicating the frontmatter `status:` used to sit in
|
|
252
|
-
# this template. The oversight fingerprint excludes the frontmatter key but
|
|
253
|
-
# hashed the body copy, so advancing a story un-ratified it and the no-implement
|
|
254
|
-
# gate then denied its own implementing commit. This was the FOURTH such
|
|
255
|
-
# lifecycle mirror in a family of three, so the removal needs a lock: without
|
|
256
|
-
# one, the next template edit reintroduces it and nothing fails.
|
|
257
|
-
|
|
258
|
-
@test "P474: the capture-story template emits no **Status** body mirror" {
|
|
259
|
-
# Behavioural on the artefact the skill prescribes, not on prose ABOUT it:
|
|
260
|
-
# extract the template's own story scaffold and assert the shape it produces.
|
|
261
|
-
# The SKILL may still MENTION the forbidden line in its do-not-reintroduce
|
|
262
|
-
# note, so match only a line-start emission inside a fenced block.
|
|
263
|
-
run bash -c "awk '/^# STORY-<NNN>/,/^## Dependencies/' '$SKILL_FILE' | grep -cE '^\*\*Status\*\*:'"
|
|
264
|
-
[ "$output" = "0" ]
|
|
265
|
-
# Anti-vacuity: if a heading rename ever empties the awk range, the grep -c
|
|
266
|
-
# above returns 0 and passes while the mirror is present. Assert the range
|
|
267
|
-
# actually contains the sibling field that DID survive.
|
|
268
|
-
run bash -c "awk '/^# STORY-<NNN>/,/^## Dependencies/' '$SKILL_FILE' | grep -cE '^\*\*Reported\*\*:'"
|
|
269
|
-
[ "$output" -ge 1 ]
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
@test "P474: the documented story body shape emits no **Status** body mirror" {
|
|
273
|
-
# The second carrier. docs/stories/README.md is the ADOPTER-facing one —
|
|
274
|
-
# reconcile-stories.sh reads the adopter's own copy — so a stale shape here
|
|
275
|
-
# has them hand-author the mirror straight back in.
|
|
276
|
-
local readme="${REPO_ROOT}/docs/stories/README.md"
|
|
277
|
-
[ -f "$readme" ]
|
|
278
|
-
run bash -c "awk '/^# STORY-<NNN>/,/^## /' '$readme' | grep -cE '^\*\*Status\*\*:'"
|
|
279
|
-
[ "$output" = "0" ]
|
|
280
|
-
# Same anti-vacuity guard as the template carrier above.
|
|
281
|
-
run bash -c "awk '/^# STORY-<NNN>/,/^## /' '$readme' | grep -cE '^\*\*Reported\*\*:'"
|
|
282
|
-
[ "$output" -ge 1 ]
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
@test "P474: a template-shaped story keeps its ratification across an accept transition" {
|
|
286
|
-
# The invariant the prose serves. Seeds a story in the shape the template now
|
|
287
|
-
# produces, ratifies it, advances status + ticks a criterion, and asserts the
|
|
288
|
-
# fingerprint still matches — the exact sequence that used to drift.
|
|
289
|
-
# shellcheck source=/dev/null
|
|
290
|
-
source "${REPO_ROOT}/packages/itil/lib/story-oversight.sh"
|
|
291
|
-
mkdir -p docs/stories/draft
|
|
292
|
-
local f=docs/stories/draft/STORY-902-shape.md
|
|
293
|
-
printf -- '---\nstatus: draft\nstory-id: shape\nhuman-oversight: confirmed\noversight-hash: P\n---\n\n# STORY-902: a story\n\n**Reported**: 2026-07-30\n\n## User value\n\nvalue.\n\n## Acceptance criteria\n\n- [ ] a criterion\n' > "$f"
|
|
294
|
-
local h; h="$(oversight_content_hash "$f")"
|
|
295
|
-
sed -i.bak "s/oversight-hash: P/oversight-hash: $h/" "$f" && rm -f "$f.bak"
|
|
296
|
-
run is_story_map_ratified "$f"
|
|
297
|
-
[ "$status" -eq 0 ]
|
|
298
|
-
|
|
299
|
-
sed -i.bak 's/^status: draft/status: accepted/; s/- \[ \] a criterion/- [x] a criterion/' "$f" && rm -f "$f.bak"
|
|
300
|
-
run is_story_map_ratified "$f"
|
|
301
|
-
[ "$status" -eq 0 ]
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
@test "P474: reintroducing the mirror DOES drift a ratified story (the lock has teeth)" {
|
|
305
|
-
# Proves the invariant test above is not vacuous: put the mirror back and the
|
|
306
|
-
# accept transition drifts again, which is the defect.
|
|
307
|
-
# shellcheck source=/dev/null
|
|
308
|
-
source "${REPO_ROOT}/packages/itil/lib/story-oversight.sh"
|
|
309
|
-
mkdir -p docs/stories/draft
|
|
310
|
-
local f=docs/stories/draft/STORY-903-regress.md
|
|
311
|
-
printf -- '---\nstatus: draft\nstory-id: regress\nhuman-oversight: confirmed\noversight-hash: P\n---\n\n# STORY-903: a story\n\n**Status**: draft\n**Reported**: 2026-07-30\n\n## User value\n\nvalue.\n' > "$f"
|
|
312
|
-
local h; h="$(oversight_content_hash "$f")"
|
|
313
|
-
sed -i.bak "s/oversight-hash: P/oversight-hash: $h/" "$f" && rm -f "$f.bak"
|
|
314
|
-
sed -i.bak 's/^status: draft/status: accepted/; s/^\*\*Status\*\*: draft/**Status**: accepted/' "$f" && rm -f "$f.bak"
|
|
315
|
-
run is_story_map_ratified "$f"
|
|
316
|
-
[ "$status" -ne 0 ]
|
|
317
|
-
}
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bats
|
|
2
|
-
# Behavioural fixtures for /wr-itil:capture-story-map (P170 Phase 2 Slice 3 — ADR-060).
|
|
3
|
-
#
|
|
4
|
-
# Mirrors capture-story-behavioural.bats with story-map-tier adjustments
|
|
5
|
-
# (HTML encoding, I3 + I4 invariants instead of I6 + I9, no optional
|
|
6
|
-
# --rfc / --story-map flags).
|
|
7
|
-
|
|
8
|
-
setup() {
|
|
9
|
-
REPO_ROOT="$(cd "$(dirname "$BATS_TEST_FILENAME")/../../../../.." && pwd)"
|
|
10
|
-
SKILL_FILE="${REPO_ROOT}/packages/itil/skills/capture-story-map/SKILL.md"
|
|
11
|
-
HELPER_PROBLEM="${REPO_ROOT}/packages/itil/scripts/update-problem-references-section.sh"
|
|
12
|
-
HELPER_JTBD="${REPO_ROOT}/packages/itil/scripts/update-jtbd-references-section.sh"
|
|
13
|
-
|
|
14
|
-
TMPROOT=$(mktemp -d)
|
|
15
|
-
ORIG_DIR="$PWD"
|
|
16
|
-
cd "$TMPROOT"
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
teardown() {
|
|
20
|
-
cd "$ORIG_DIR"
|
|
21
|
-
rm -rf "$TMPROOT"
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
@test "capture-story-map: SKILL.md exists" {
|
|
25
|
-
[ -f "$SKILL_FILE" ]
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
@test "capture-story-map: SKILL.md frontmatter declares wr-itil:capture-story-map name" {
|
|
29
|
-
run grep -E '^name: wr-itil:capture-story-map$' "$SKILL_FILE"
|
|
30
|
-
[ "$status" -eq 0 ]
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
@test "capture-story-map: SKILL.md names I3 trace-to-problem invariant" {
|
|
34
|
-
run grep -E 'I3 hard-block|I3.*trace-to-problem' "$SKILL_FILE"
|
|
35
|
-
[ "$status" -eq 0 ]
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
@test "capture-story-map: SKILL.md names I4 trace-to-JTBD invariant" {
|
|
39
|
-
run grep -E 'I4 hard-block|I4.*trace-to-JTBD' "$SKILL_FILE"
|
|
40
|
-
[ "$status" -eq 0 ]
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
@test "capture-story-map: next-ID formula computes 001 for empty story-maps directory" {
|
|
44
|
-
mkdir -p docs/story-maps/draft
|
|
45
|
-
local_max=$(ls docs/story-maps/*/STORY-MAP-*.html 2>/dev/null | sed 's|.*/STORY-MAP-||;s|-.*||' | grep -oE '^[0-9]+' | sort -n | tail -1)
|
|
46
|
-
next=$(printf '%03d' $(( 10#${local_max:-0} + 1 )))
|
|
47
|
-
[ "$next" = "001" ]
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
@test "capture-story-map: next-ID formula computes 003 when STORY-MAP-002 exists locally" {
|
|
51
|
-
mkdir -p docs/story-maps/draft docs/story-maps/in-progress
|
|
52
|
-
touch docs/story-maps/draft/STORY-MAP-002-foo.html
|
|
53
|
-
touch docs/story-maps/in-progress/STORY-MAP-001-bar.html
|
|
54
|
-
local_max=$(ls docs/story-maps/*/STORY-MAP-*.html 2>/dev/null | sed 's|.*/STORY-MAP-||;s|-.*||' | grep -oE '^[0-9]+' | sort -n | tail -1)
|
|
55
|
-
next=$(printf '%03d' $(( 10#${local_max:-0} + 1 )))
|
|
56
|
-
[ "$next" = "003" ]
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
@test "capture-story-map: update-problem-references-section.sh accepts 'Story Maps' section name" {
|
|
60
|
-
mkdir -p docs/problems/known-error docs/story-maps/draft
|
|
61
|
-
cat > docs/problems/known-error/170-test.md <<'EOF'
|
|
62
|
-
# P170: Test
|
|
63
|
-
|
|
64
|
-
## Story Maps
|
|
65
|
-
|
|
66
|
-
(empty)
|
|
67
|
-
EOF
|
|
68
|
-
run bash "$HELPER_PROBLEM" docs/problems/known-error/170-test.md "Story Maps"
|
|
69
|
-
[[ "$output" != *"unknown section-name"* ]]
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
@test "capture-story-map: update-jtbd-references-section.sh accepts 'Story Maps' section name" {
|
|
73
|
-
mkdir -p docs/jtbd/solo-developer docs/story-maps/draft
|
|
74
|
-
cat > docs/jtbd/solo-developer/JTBD-008-test.proposed.md <<'EOF'
|
|
75
|
-
# JTBD-008: Test
|
|
76
|
-
|
|
77
|
-
## Story Maps
|
|
78
|
-
|
|
79
|
-
(empty)
|
|
80
|
-
EOF
|
|
81
|
-
run bash "$HELPER_JTBD" docs/jtbd/solo-developer/JTBD-008-test.proposed.md "Story Maps"
|
|
82
|
-
[[ "$output" != *"unknown section-name"* ]]
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
@test "capture-story-map: SKILL.md prescribes HTML encoding per ADR-060 amendment 2026-05-12" {
|
|
86
|
-
run grep -E 'HTML5|<!DOCTYPE html>|encoding amendment 2026-05-12' "$SKILL_FILE"
|
|
87
|
-
[ "$status" -eq 0 ]
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
@test "capture-story-map: SKILL.md prescribes draft/ landing subdir" {
|
|
91
|
-
run grep -E 'docs/story-maps/draft/STORY-MAP' "$SKILL_FILE"
|
|
92
|
-
[ "$status" -eq 0 ]
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
@test "capture-story-map: SKILL.md prohibits inline style on data-bearing elements per STYLE-GUIDE.md" {
|
|
96
|
-
run grep -iE 'NO inline.*style.*data-bearing|prohibited inline.*style' "$SKILL_FILE"
|
|
97
|
-
[ "$status" -eq 0 ]
|
|
98
|
-
}
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bats
|
|
2
|
-
# Contract assertions for /wr-itil:close-incident (P071 split slice 6c).
|
|
3
|
-
#
|
|
4
|
-
# This skill hosts the "close a restored incident" user intent previously
|
|
5
|
-
# hidden behind /wr-itil:manage-incident <I> close. It checks the Linked
|
|
6
|
-
# Problem's file suffix and, if the problem is in an acceptable terminal
|
|
7
|
-
# state (.known-error.md / .verifying.md / .closed.md) OR the incident
|
|
8
|
-
# documents a No Problem justification, renames the incident file from
|
|
9
|
-
# .restored.md to .closed.md and updates the Status field.
|
|
10
|
-
#
|
|
11
|
-
# Structural assertion — Permitted Exception to the source-grep ban
|
|
12
|
-
# (ADR-005 / P011 / ADR-037 contract-assertion pattern).
|
|
13
|
-
#
|
|
14
|
-
# @problem P071
|
|
15
|
-
# @jtbd JTBD-001 (enforce governance without slowing down — discoverable surface)
|
|
16
|
-
# @jtbd JTBD-101 (extend the suite with clear patterns — one skill per distinct user intent)
|
|
17
|
-
# @jtbd JTBD-201 (restore service fast with an audit trail — close gate preserves the problem-handoff link)
|
|
18
|
-
#
|
|
19
|
-
# Cross-reference:
|
|
20
|
-
# P071: docs/problems/071-argument-based-skill-subcommands-are-not-discoverable.open.md
|
|
21
|
-
# ADR-010 amended (Skill Granularity section) — split naming + forwarder contract
|
|
22
|
-
# ADR-011 — manage-incident skill-wrapping precedent (close gate on linked problem)
|
|
23
|
-
# ADR-022 — problem lifecycle verification-pending status (.verifying.md accepted alongside .known-error.md / .closed.md)
|
|
24
|
-
# ADR-037 — contract-assertion bats pattern
|
|
25
|
-
|
|
26
|
-
setup() {
|
|
27
|
-
SKILL_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
|
|
28
|
-
SKILL_FILE="${SKILL_DIR}/SKILL.md"
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
@test "SKILL.md exists and has frontmatter" {
|
|
32
|
-
[ -f "$SKILL_FILE" ]
|
|
33
|
-
run head -1 "$SKILL_FILE"
|
|
34
|
-
[ "$status" -eq 0 ]
|
|
35
|
-
[ "$output" = "---" ]
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
@test "SKILL.md frontmatter name is wr-itil:close-incident (P071 + ADR-010 amended)" {
|
|
39
|
-
# Split naming convention per ADR-010 amendment: <verb>-<object> pair.
|
|
40
|
-
# The new skill's name must match the phased-landing plan pinned in P071.
|
|
41
|
-
run grep -n "^name: wr-itil:close-incident$" "$SKILL_FILE"
|
|
42
|
-
[ "$status" -eq 0 ]
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
@test "SKILL.md frontmatter description names the close intent (P071)" {
|
|
46
|
-
# Description must name "close" and "incident" so Claude Code autocomplete
|
|
47
|
-
# surfaces the user intent rather than a generic name.
|
|
48
|
-
run grep -inE "^description:.*clos.*incident|^description:.*incident.*clos" "$SKILL_FILE"
|
|
49
|
-
[ "$status" -eq 0 ]
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
@test "SKILL.md frontmatter allowed-tools grants file-mutation surface (P071 — close requires rename + edit)" {
|
|
53
|
-
# close-incident renames .restored.md → .closed.md and updates the
|
|
54
|
-
# Status field. Unlike restore-incident, the linked-problem gate is a
|
|
55
|
-
# hard check (not a prompt), so no AskUserQuestion is required. No
|
|
56
|
-
# cross-skill invocation either, so no Skill tool is required.
|
|
57
|
-
run grep -nE "^allowed-tools:" "$SKILL_FILE"
|
|
58
|
-
[ "$status" -eq 0 ]
|
|
59
|
-
run grep -nE "^allowed-tools:.*Write" "$SKILL_FILE"
|
|
60
|
-
[ "$status" -eq 0 ]
|
|
61
|
-
run grep -nE "^allowed-tools:.*Edit" "$SKILL_FILE"
|
|
62
|
-
[ "$status" -eq 0 ]
|
|
63
|
-
run grep -nE "^allowed-tools:.*Bash" "$SKILL_FILE"
|
|
64
|
-
[ "$status" -eq 0 ]
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
@test "SKILL.md documents the .restored.md → .closed.md rename (P071 + ADR-011)" {
|
|
68
|
-
# The close transition renames the incident file from .restored.md
|
|
69
|
-
# to .closed.md. The SKILL.md must name both suffixes explicitly so
|
|
70
|
-
# the file-suffix contract is legible.
|
|
71
|
-
run grep -inE "\.restored\.md" "$SKILL_FILE"
|
|
72
|
-
[ "$status" -eq 0 ]
|
|
73
|
-
run grep -inE "\.closed\.md" "$SKILL_FILE"
|
|
74
|
-
[ "$status" -eq 0 ]
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
@test "SKILL.md documents the Linked-Problem gate with .known-error.md allowance (P071 + ADR-011)" {
|
|
78
|
-
# Per ADR-011, the close gate accepts a linked problem in
|
|
79
|
-
# .known-error.md state. Older form of the gate — must still be
|
|
80
|
-
# named explicitly post-ADR-022.
|
|
81
|
-
run grep -inE "known-error" "$SKILL_FILE"
|
|
82
|
-
[ "$status" -eq 0 ]
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
@test "SKILL.md documents the Linked-Problem gate .verifying.md allowance (P071 + ADR-022)" {
|
|
86
|
-
# Per ADR-022, .verifying.md (fix released, root cause confirmed,
|
|
87
|
-
# awaiting verification) also satisfies the incident-close gate.
|
|
88
|
-
# The SKILL.md must name this allowance explicitly so the ADR-022
|
|
89
|
-
# extension is preserved post-split.
|
|
90
|
-
run grep -inE "\.verifying\.md|verifying" "$SKILL_FILE"
|
|
91
|
-
[ "$status" -eq 0 ]
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
@test "SKILL.md documents the No Problem justification path (P071 + ADR-011)" {
|
|
95
|
-
# Per ADR-011, the incident may carry a ## No Problem section with a
|
|
96
|
-
# justification (e.g. "one-off cosmic-bit-flip"). In that case the
|
|
97
|
-
# linked-problem gate is bypassed. The SKILL.md must document the
|
|
98
|
-
# No Problem acceptance so the audit trail invariant is preserved.
|
|
99
|
-
run grep -inE "No Problem|no problem" "$SKILL_FILE"
|
|
100
|
-
[ "$status" -eq 0 ]
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
@test "SKILL.md documents the .open.md block condition (P071 + ADR-011)" {
|
|
104
|
-
# Per ADR-011, a linked problem in .open.md state blocks the close.
|
|
105
|
-
# The user must transition the problem to Known Error (or the
|
|
106
|
-
# verification pipeline must complete) before the incident can close.
|
|
107
|
-
# The SKILL.md must name this blocking condition explicitly.
|
|
108
|
-
run grep -inE "\.open\.md|Open" "$SKILL_FILE"
|
|
109
|
-
[ "$status" -eq 0 ]
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
@test "SKILL.md cites P071 and ADR-010 amended (P071 + ADR-025)" {
|
|
113
|
-
# ADR-025 inheritance per ADR-037: contract-assertion bats should reflect
|
|
114
|
-
# traceability cites on the skill spec document.
|
|
115
|
-
run grep -inE "P071|ADR-010" "$SKILL_FILE"
|
|
116
|
-
[ "$status" -eq 0 ]
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
@test "SKILL.md cites ADR-011 + ADR-022 for the close gate (P071 + ADR-011 + ADR-022)" {
|
|
120
|
-
# close-incident inherits the Linked-Problem gate from ADR-011 and the
|
|
121
|
-
# .verifying.md extension from ADR-022. Both must be cited so the
|
|
122
|
-
# precedent chain is legible.
|
|
123
|
-
run grep -inE "ADR-011" "$SKILL_FILE"
|
|
124
|
-
[ "$status" -eq 0 ]
|
|
125
|
-
run grep -inE "ADR-022" "$SKILL_FILE"
|
|
126
|
-
[ "$status" -eq 0 ]
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
@test "SKILL.md does not carry a deprecated-arguments frontmatter flag (clean-split skill)" {
|
|
130
|
-
# close-incident is a clean-split skill with no argument-subcommands
|
|
131
|
-
# itself (its argument is a data parameter — incident ID only).
|
|
132
|
-
# ADR-010 amendment's `deprecated-arguments: true` flag is only valid
|
|
133
|
-
# on host skills with forwarder routes. close-incident is a
|
|
134
|
-
# forwarder TARGET, not a host. It must NOT carry the flag.
|
|
135
|
-
run grep -E "^deprecated-arguments:" "$SKILL_FILE"
|
|
136
|
-
[ "$status" -ne 0 ]
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
@test "SKILL.md does not use word-argument subcommand branching (P071 regression guard)" {
|
|
140
|
-
# The whole point of P071: Claude Code autocomplete does not surface
|
|
141
|
-
# word-argument subcommands. A clean-split skill must not reintroduce
|
|
142
|
-
# word-arg subcommand routing. The data parameter <I> is a string,
|
|
143
|
-
# not a verb keyword.
|
|
144
|
-
run grep -inE "If arguments start with \"(list|mitigate|restore|close|link)\"|If arguments contain \"(list|mitigate|restore|close|link)\"" "$SKILL_FILE"
|
|
145
|
-
[ "$status" -ne 0 ]
|
|
146
|
-
}
|