@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,74 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bats
|
|
2
|
-
# Behavioural fixtures for reconcile-story-maps.sh + bin shim + skill
|
|
3
|
-
# (P170 Phase 2 Slice 5 — sibling of reconcile-stories.sh / reconcile-rfcs.sh).
|
|
4
|
-
|
|
5
|
-
setup() {
|
|
6
|
-
REPO_ROOT="$(cd "$(dirname "$BATS_TEST_FILENAME")/../../../.." && pwd)"
|
|
7
|
-
SCRIPT="${REPO_ROOT}/packages/itil/scripts/reconcile-story-maps.sh"
|
|
8
|
-
BIN_SHIM="${REPO_ROOT}/packages/itil/bin/wr-itil-reconcile-story-maps"
|
|
9
|
-
SKILL_FILE="${REPO_ROOT}/packages/itil/skills/reconcile-story-maps/SKILL.md"
|
|
10
|
-
|
|
11
|
-
TMPROOT=$(mktemp -d)
|
|
12
|
-
ORIG_DIR="$PWD"
|
|
13
|
-
cd "$TMPROOT"
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
teardown() {
|
|
17
|
-
cd "$ORIG_DIR"
|
|
18
|
-
rm -rf "$TMPROOT"
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
@test "reconcile-story-maps: script exists and is executable" {
|
|
22
|
-
[ -f "$SCRIPT" ]
|
|
23
|
-
[ -x "$SCRIPT" ]
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
@test "reconcile-story-maps: bin shim exists, executable, exec's the script" {
|
|
27
|
-
[ -f "$BIN_SHIM" ]
|
|
28
|
-
[ -x "$BIN_SHIM" ]
|
|
29
|
-
run grep -E 'exec.*scripts/reconcile-story-maps\.sh' "$BIN_SHIM"
|
|
30
|
-
[ "$status" -eq 0 ]
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
@test "reconcile-story-maps: exits 2 when README is missing" {
|
|
34
|
-
mkdir -p docs/story-maps
|
|
35
|
-
run bash "$SCRIPT" docs/story-maps
|
|
36
|
-
[ "$status" -eq 2 ]
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
@test "reconcile-story-maps: exits 0 on empty story-maps dir + empty README" {
|
|
40
|
-
mkdir -p docs/story-maps/draft docs/story-maps/accepted docs/story-maps/in-progress docs/story-maps/completed docs/story-maps/archived
|
|
41
|
-
echo "# Story Maps" > docs/story-maps/README.md
|
|
42
|
-
run bash "$SCRIPT" docs/story-maps
|
|
43
|
-
[ "$status" -eq 0 ]
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
@test "reconcile-story-maps: detects STALE when filesystem has a map not in README" {
|
|
47
|
-
mkdir -p docs/story-maps/draft
|
|
48
|
-
touch docs/story-maps/draft/STORY-MAP-007-foo.html
|
|
49
|
-
echo "# Story Maps" > docs/story-maps/README.md
|
|
50
|
-
run bash "$SCRIPT" docs/story-maps
|
|
51
|
-
[ "$status" -eq 1 ]
|
|
52
|
-
[[ "$output" == *"STALE"* ]]
|
|
53
|
-
[[ "$output" == *"STORY-MAP-007"* ]]
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
@test "reconcile-story-maps: detects MISSING when README claims a map that isn't on disk" {
|
|
57
|
-
mkdir -p docs/story-maps/draft
|
|
58
|
-
cat > docs/story-maps/README.md <<'EOF'
|
|
59
|
-
# Story Maps
|
|
60
|
-
| ID | Status |
|
|
61
|
-
|----|--------|
|
|
62
|
-
| STORY-MAP-007 | draft |
|
|
63
|
-
EOF
|
|
64
|
-
run bash "$SCRIPT" docs/story-maps
|
|
65
|
-
[ "$status" -eq 1 ]
|
|
66
|
-
[[ "$output" == *"MISSING"* ]]
|
|
67
|
-
[[ "$output" == *"STORY-MAP-007"* ]]
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
@test "reconcile-story-maps: SKILL.md exists with canonical name" {
|
|
71
|
-
[ -f "$SKILL_FILE" ]
|
|
72
|
-
run grep -E '^name: wr-itil:reconcile-story-maps$' "$SKILL_FILE"
|
|
73
|
-
[ "$status" -eq 0 ]
|
|
74
|
-
}
|
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bats
|
|
2
|
-
|
|
3
|
-
# P143: scripts/release-watch.sh must absorb changesets/action workflow
|
|
4
|
-
# latency by polling `gh pr list` for up to 120s before exiting "no open
|
|
5
|
-
# release PR found". The release PR is created/updated asynchronously by
|
|
6
|
-
# the changesets/action GitHub workflow ~30-120s after `git push`; the
|
|
7
|
-
# script's first call routinely raced this window and exited 1.
|
|
8
|
-
#
|
|
9
|
-
# Behavioural test (ADR-037 + P081 — behavioural over structural grep).
|
|
10
|
-
# Extracts `find_release_pr` from the script via awk, sources it, and
|
|
11
|
-
# exercises it against a PATH-shadowed `gh` mock + stubbed `sleep`. The
|
|
12
|
-
# mock consumes a comma-delimited iteration sequence (e.g. "empty,empty,ok")
|
|
13
|
-
# so each iteration's `gh pr list` payload is deterministic.
|
|
14
|
-
#
|
|
15
|
-
# Mirrors the extraction + PATH-shadow pattern in
|
|
16
|
-
# scripts/repo-local-skills/install-updates/test/install-updates-step-7-retry-rollback.bats.
|
|
17
|
-
|
|
18
|
-
setup() {
|
|
19
|
-
REPO_ROOT="$(cd "$(dirname "$BATS_TEST_FILENAME")/../../../.." && pwd)"
|
|
20
|
-
SCRIPT="$REPO_ROOT/scripts/release-watch.sh"
|
|
21
|
-
|
|
22
|
-
FN_FILE="$BATS_TEST_TMPDIR/find-release-pr.sh"
|
|
23
|
-
awk '
|
|
24
|
-
/^find_release_pr\(\) \{/ { in_fn=1 }
|
|
25
|
-
in_fn { print }
|
|
26
|
-
in_fn && /^\}/ { exit }
|
|
27
|
-
' "$SCRIPT" > "$FN_FILE"
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
# Stand up a PATH-shadowing `gh` mock that consumes a comma-delimited
|
|
31
|
-
# iteration sequence ("empty" / "ok"). Each `gh pr list` call advances the
|
|
32
|
-
# pointer; "empty" returns `[]`, "ok" returns a one-PR JSON array.
|
|
33
|
-
make_gh_mock() {
|
|
34
|
-
local pattern="$1"
|
|
35
|
-
local bindir="$BATS_TEST_TMPDIR/bin"
|
|
36
|
-
mkdir -p "$bindir"
|
|
37
|
-
printf '%s' "$pattern" > "$BATS_TEST_TMPDIR/gh-pattern"
|
|
38
|
-
printf '0' > "$BATS_TEST_TMPDIR/gh-counter"
|
|
39
|
-
: > "$BATS_TEST_TMPDIR/gh-log"
|
|
40
|
-
cat > "$bindir/gh" <<'MOCK'
|
|
41
|
-
#!/usr/bin/env bash
|
|
42
|
-
echo "$*" >> "$BATS_TEST_TMPDIR/gh-log"
|
|
43
|
-
case "$1 $2" in
|
|
44
|
-
"pr list")
|
|
45
|
-
pattern=$(cat "$BATS_TEST_TMPDIR/gh-pattern")
|
|
46
|
-
count=$(cat "$BATS_TEST_TMPDIR/gh-counter")
|
|
47
|
-
count=$((count + 1))
|
|
48
|
-
printf '%s' "$count" > "$BATS_TEST_TMPDIR/gh-counter"
|
|
49
|
-
next=$(printf '%s' "$pattern" | cut -d, -f"$count")
|
|
50
|
-
if [ "$next" = "ok" ]; then
|
|
51
|
-
echo '[{"number":99,"url":"https://github.com/example/repo/pull/99"}]'
|
|
52
|
-
else
|
|
53
|
-
echo '[]'
|
|
54
|
-
fi
|
|
55
|
-
exit 0
|
|
56
|
-
;;
|
|
57
|
-
*) exit 0 ;;
|
|
58
|
-
esac
|
|
59
|
-
MOCK
|
|
60
|
-
chmod +x "$bindir/gh"
|
|
61
|
-
PATH="$bindir:$PATH"
|
|
62
|
-
export PATH
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
# Suppress real sleeps during tests — 120s wall-clock is unacceptable.
|
|
66
|
-
# Records each call so we can count iterations.
|
|
67
|
-
stub_sleep() {
|
|
68
|
-
: > "$BATS_TEST_TMPDIR/sleep-log"
|
|
69
|
-
eval 'sleep() { echo "$1" >> "$BATS_TEST_TMPDIR/sleep-log"; }'
|
|
70
|
-
export -f sleep
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
count_gh_pr_list_calls() {
|
|
74
|
-
[ -f "$BATS_TEST_TMPDIR/gh-log" ] || { echo 0; return; }
|
|
75
|
-
awk '/^pr list/ { n++ } END { print n+0 }' "$BATS_TEST_TMPDIR/gh-log"
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
count_sleep_calls() {
|
|
79
|
-
[ -f "$BATS_TEST_TMPDIR/sleep-log" ] || { echo 0; return; }
|
|
80
|
-
awk 'END { print NR+0 }' "$BATS_TEST_TMPDIR/sleep-log"
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
@test "find_release_pr extracted from release-watch.sh is non-empty" {
|
|
84
|
-
[ -s "$FN_FILE" ] || { echo "find_release_pr missing from $SCRIPT"; return 1; }
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
@test "P143: PR exists on first iteration — fast path, one gh call, no sleep" {
|
|
88
|
-
[ -s "$FN_FILE" ] || { echo "find_release_pr missing from $SCRIPT"; return 1; }
|
|
89
|
-
# shellcheck disable=SC1090
|
|
90
|
-
source "$FN_FILE"
|
|
91
|
-
make_gh_mock "ok"
|
|
92
|
-
stub_sleep
|
|
93
|
-
|
|
94
|
-
run find_release_pr
|
|
95
|
-
[ "$status" -eq 0 ]
|
|
96
|
-
# stdout is "<number>\t<url>"
|
|
97
|
-
[[ "$output" == *"99"* ]]
|
|
98
|
-
[[ "$output" == *"https://github.com/example/repo/pull/99"* ]]
|
|
99
|
-
|
|
100
|
-
[ "$(count_gh_pr_list_calls)" -eq 1 ]
|
|
101
|
-
[ "$(count_sleep_calls)" -eq 0 ]
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
@test "P143: PR appears on iteration 3 — three gh calls, two sleeps, returns the PR" {
|
|
105
|
-
[ -s "$FN_FILE" ] || { echo "find_release_pr missing from $SCRIPT"; return 1; }
|
|
106
|
-
# shellcheck disable=SC1090
|
|
107
|
-
source "$FN_FILE"
|
|
108
|
-
make_gh_mock "empty,empty,ok"
|
|
109
|
-
stub_sleep
|
|
110
|
-
|
|
111
|
-
run find_release_pr
|
|
112
|
-
[ "$status" -eq 0 ]
|
|
113
|
-
[[ "$output" == *"99"* ]]
|
|
114
|
-
|
|
115
|
-
[ "$(count_gh_pr_list_calls)" -eq 3 ]
|
|
116
|
-
[ "$(count_sleep_calls)" -eq 2 ]
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
@test "P143: empty for full 12 iterations — 12 gh calls, exit 1" {
|
|
120
|
-
[ -s "$FN_FILE" ] || { echo "find_release_pr missing from $SCRIPT"; return 1; }
|
|
121
|
-
# shellcheck disable=SC1090
|
|
122
|
-
source "$FN_FILE"
|
|
123
|
-
# 12 empties, no 13th column needed — function should give up after 12.
|
|
124
|
-
make_gh_mock "empty,empty,empty,empty,empty,empty,empty,empty,empty,empty,empty,empty"
|
|
125
|
-
stub_sleep
|
|
126
|
-
|
|
127
|
-
run find_release_pr
|
|
128
|
-
[ "$status" -ne 0 ]
|
|
129
|
-
|
|
130
|
-
[ "$(count_gh_pr_list_calls)" -eq 12 ]
|
|
131
|
-
# 11 sleeps between 12 iterations (no trailing sleep after the final
|
|
132
|
-
# empty result — that would burn 10s for nothing).
|
|
133
|
-
[ "$(count_sleep_calls)" -eq 11 ]
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
@test "P143: RELEASE_WATCH_VERBOSE=1 prints poll progress to stderr" {
|
|
137
|
-
[ -s "$FN_FILE" ] || { echo "find_release_pr missing from $SCRIPT"; return 1; }
|
|
138
|
-
# shellcheck disable=SC1090
|
|
139
|
-
source "$FN_FILE"
|
|
140
|
-
make_gh_mock "empty,empty,ok"
|
|
141
|
-
stub_sleep
|
|
142
|
-
|
|
143
|
-
RELEASE_WATCH_VERBOSE=1 run find_release_pr
|
|
144
|
-
[ "$status" -eq 0 ]
|
|
145
|
-
# `bats run` merges stdout + stderr in $output by default.
|
|
146
|
-
[[ "$output" == *"Polling"* ]] || [[ "$output" == *"attempt"* ]]
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
@test "P143: default (verbose unset) does NOT print poll progress" {
|
|
150
|
-
[ -s "$FN_FILE" ] || { echo "find_release_pr missing from $SCRIPT"; return 1; }
|
|
151
|
-
# shellcheck disable=SC1090
|
|
152
|
-
source "$FN_FILE"
|
|
153
|
-
make_gh_mock "empty,empty,ok"
|
|
154
|
-
stub_sleep
|
|
155
|
-
|
|
156
|
-
unset RELEASE_WATCH_VERBOSE
|
|
157
|
-
run find_release_pr
|
|
158
|
-
[ "$status" -eq 0 ]
|
|
159
|
-
# Output is the final tab-separated PR line ONLY — no progress lines.
|
|
160
|
-
[[ "$output" != *"Polling"* ]]
|
|
161
|
-
[[ "$output" != *"attempt"* ]]
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
@test "P143: returns tab-separated number and URL on success (parseable)" {
|
|
165
|
-
[ -s "$FN_FILE" ] || { echo "find_release_pr missing from $SCRIPT"; return 1; }
|
|
166
|
-
# shellcheck disable=SC1090
|
|
167
|
-
source "$FN_FILE"
|
|
168
|
-
make_gh_mock "ok"
|
|
169
|
-
stub_sleep
|
|
170
|
-
|
|
171
|
-
run find_release_pr
|
|
172
|
-
[ "$status" -eq 0 ]
|
|
173
|
-
# Caller parses with `cut -f1` / `cut -f2` — the contract is one line,
|
|
174
|
-
# tab-separated.
|
|
175
|
-
local first_field second_field
|
|
176
|
-
first_field=$(printf '%s\n' "$output" | head -1 | cut -f1)
|
|
177
|
-
second_field=$(printf '%s\n' "$output" | head -1 | cut -f2)
|
|
178
|
-
[ "$first_field" = "99" ]
|
|
179
|
-
[ "$second_field" = "https://github.com/example/repo/pull/99" ]
|
|
180
|
-
}
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bats
|
|
2
|
-
|
|
3
|
-
# @problem P382 — AFK work-problems `claude -p` iter subprocesses load only
|
|
4
|
-
# USER-scoped enabledPlugins; project-scoped governance plugins
|
|
5
|
-
# must be passed explicitly via --plugin-dir. This helper emits
|
|
6
|
-
# the --plugin-dir argument pairs the Step 5 dispatch splices
|
|
7
|
-
# into its claude -p invocation.
|
|
8
|
-
#
|
|
9
|
-
# Contract: `resolve-governance-plugin-dirs.sh` reads $PATH + WR_GOVERNANCE_PLUGINS
|
|
10
|
-
# and emits, per resolvable plugin, two stdout lines — `--plugin-dir` then the
|
|
11
|
-
# plugin root dir — for `mapfile -t` consumption.
|
|
12
|
-
#
|
|
13
|
-
# Load-bearing behaviour (ADR-080): the version is selected by HIGHEST-SEMVER
|
|
14
|
-
# walk of the cache parent, NOT by $PATH order (which is frozen-stale
|
|
15
|
-
# mid-session per P343). The fixture deliberately places a LOWER version's bin
|
|
16
|
-
# earlier on $PATH and asserts the HIGHER version's dir is still emitted.
|
|
17
|
-
#
|
|
18
|
-
# @adr ADR-049 (bin/ on PATH shim — adopter-safe script resolution)
|
|
19
|
-
# @adr ADR-080 (highest-version-wins resolution)
|
|
20
|
-
# @adr ADR-052 (behavioural test per P081)
|
|
21
|
-
# @adr ADR-032 (Step 5 dispatch contract — P382 amendment)
|
|
22
|
-
# @jtbd JTBD-001 (Enforce Governance — iter commits ship gated)
|
|
23
|
-
# @jtbd JTBD-006 (Progress Backlog AFK — full governance surface inside iters)
|
|
24
|
-
|
|
25
|
-
setup() {
|
|
26
|
-
SCRIPTS_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
|
|
27
|
-
SCRIPT="$SCRIPTS_DIR/resolve-governance-plugin-dirs.sh"
|
|
28
|
-
CACHE="$(mktemp -d)"
|
|
29
|
-
# Synthetic marketplace-cache layout (ADR-080 SQ-080-5 — no source-repo
|
|
30
|
-
# cohabitation). wr-architect has two cached versions; wr-itil has one.
|
|
31
|
-
mkdir -p "$CACHE/windyroad/wr-architect/0.16.0/bin"
|
|
32
|
-
mkdir -p "$CACHE/windyroad/wr-architect/0.17.3/bin"
|
|
33
|
-
mkdir -p "$CACHE/windyroad/wr-itil/0.51.0/bin"
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
teardown() {
|
|
37
|
-
rm -rf "$CACHE"
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
@test "resolve-governance-plugin-dirs: script exists and is executable" {
|
|
41
|
-
[ -f "$SCRIPT" ]
|
|
42
|
-
[ -x "$SCRIPT" ]
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
@test "resolve-governance-plugin-dirs: emits --plugin-dir pairs for resolvable plugins" {
|
|
46
|
-
PATH="$CACHE/windyroad/wr-architect/0.17.3/bin:$CACHE/windyroad/wr-itil/0.51.0/bin:/usr/bin:/bin" \
|
|
47
|
-
WR_GOVERNANCE_PLUGINS="wr-architect wr-itil" run "$SCRIPT"
|
|
48
|
-
[ "$status" -eq 0 ]
|
|
49
|
-
[ "${lines[0]}" = "--plugin-dir" ]
|
|
50
|
-
[ "${lines[1]}" = "$CACHE/windyroad/wr-architect/0.17.3" ]
|
|
51
|
-
[ "${lines[2]}" = "--plugin-dir" ]
|
|
52
|
-
[ "${lines[3]}" = "$CACHE/windyroad/wr-itil/0.51.0" ]
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
@test "resolve-governance-plugin-dirs: picks highest semver, NOT \$PATH order (ADR-080)" {
|
|
56
|
-
# Lower version (0.16.0) earlier on PATH than higher (0.17.3) — the resolver
|
|
57
|
-
# must still emit 0.17.3 (cache-parent highest-semver walk, not PATH order).
|
|
58
|
-
PATH="$CACHE/windyroad/wr-architect/0.16.0/bin:$CACHE/windyroad/wr-architect/0.17.3/bin:/usr/bin:/bin" \
|
|
59
|
-
WR_GOVERNANCE_PLUGINS="wr-architect" run "$SCRIPT"
|
|
60
|
-
[ "$status" -eq 0 ]
|
|
61
|
-
[ "${lines[0]}" = "--plugin-dir" ]
|
|
62
|
-
[ "${lines[1]}" = "$CACHE/windyroad/wr-architect/0.17.3" ]
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
@test "resolve-governance-plugin-dirs: skips unresolvable plugins silently" {
|
|
66
|
-
PATH="$CACHE/windyroad/wr-itil/0.51.0/bin:/usr/bin:/bin" \
|
|
67
|
-
WR_GOVERNANCE_PLUGINS="wr-architect wr-itil wr-not-installed" run "$SCRIPT"
|
|
68
|
-
[ "$status" -eq 0 ]
|
|
69
|
-
# Only wr-itil is on PATH → exactly one pair, no wr-architect / wr-not-installed.
|
|
70
|
-
[ "${#lines[@]}" -eq 2 ]
|
|
71
|
-
[ "${lines[1]}" = "$CACHE/windyroad/wr-itil/0.51.0" ]
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
@test "resolve-governance-plugin-dirs: no governance plugins on PATH → empty output, exit 0" {
|
|
75
|
-
PATH="/usr/bin:/bin" WR_GOVERNANCE_PLUGINS="wr-architect wr-itil" run "$SCRIPT"
|
|
76
|
-
[ "$status" -eq 0 ]
|
|
77
|
-
[ -z "$output" ]
|
|
78
|
-
}
|
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bats
|
|
2
|
-
# Behavioural fixtures for the RFC frontmatter `stories:` extension
|
|
3
|
-
# (P170 Phase 2 Slice 11 — ADR-060 lines 255-270 + 296).
|
|
4
|
-
#
|
|
5
|
-
# Per ADR-052: behavioural assertions on observable artefact state, not
|
|
6
|
-
# structural prose-grep on SKILL.md. The load-bearing surfaces under
|
|
7
|
-
# test are:
|
|
8
|
-
# 1. RFC frontmatter spec in `docs/rfcs/README.md` includes the
|
|
9
|
-
# `stories:` field with the 0..N + ORDERED contract.
|
|
10
|
-
# 2. The Slice 2b helper `update-rfc-references-section.sh` accepts
|
|
11
|
-
# "Stories" as a section name and:
|
|
12
|
-
# (a) renders a `## Stories` section from `stories: [STORY-NNN, ...]`
|
|
13
|
-
# frontmatter in execution order
|
|
14
|
-
# (b) applies lazy-empty discipline — empty `stories: []` produces
|
|
15
|
-
# NO `## Stories` section (atomic RFC, JTBD-101 friction guard)
|
|
16
|
-
# 3. capture-rfc + manage-rfc SKILL.md both document the extension
|
|
17
|
-
# (existence checks; not prose grep of behaviour, but presence of
|
|
18
|
-
# load-bearing identifiers like `--stories` and `update-rfc-
|
|
19
|
-
# references-section.sh`).
|
|
20
|
-
#
|
|
21
|
-
# @problem P170
|
|
22
|
-
# @jtbd JTBD-008 (Decompose a Fix Into Coordinated Changes — `stories:`
|
|
23
|
-
# array IS the decomposition mechanism)
|
|
24
|
-
# @jtbd JTBD-101 (atomic-fix-adopter friction guard — empty stories: []
|
|
25
|
-
# ships as atomic RFC without per-story dispatch)
|
|
26
|
-
# @adr ADR-060 (Problem-RFC-Story framework — RFC frontmatter
|
|
27
|
-
# extension at line 255-270 + skills extension line 296)
|
|
28
|
-
# @adr ADR-052 (Behavioural-tests-default)
|
|
29
|
-
|
|
30
|
-
setup() {
|
|
31
|
-
REPO_ROOT="$(cd "$(dirname "$BATS_TEST_FILENAME")/../../../.." && pwd)"
|
|
32
|
-
RFC_README="${REPO_ROOT}/docs/rfcs/README.md"
|
|
33
|
-
CAPTURE_RFC="${REPO_ROOT}/packages/itil/skills/capture-rfc/SKILL.md"
|
|
34
|
-
MANAGE_RFC="${REPO_ROOT}/packages/itil/skills/manage-rfc/SKILL.md"
|
|
35
|
-
HELPER="${REPO_ROOT}/packages/itil/scripts/update-rfc-references-section.sh"
|
|
36
|
-
|
|
37
|
-
TMPROOT=$(mktemp -d)
|
|
38
|
-
ORIG_DIR="$PWD"
|
|
39
|
-
cd "$TMPROOT"
|
|
40
|
-
mkdir -p docs/rfcs docs/stories/draft docs/stories/accepted docs/stories/done
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
teardown() {
|
|
44
|
-
cd "$ORIG_DIR"
|
|
45
|
-
rm -rf "$TMPROOT"
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
# ---------------------------------------------------------------------------
|
|
49
|
-
# Surface 1: RFC frontmatter spec includes stories: field
|
|
50
|
-
# ---------------------------------------------------------------------------
|
|
51
|
-
|
|
52
|
-
@test "rfc-stories-extension: docs/rfcs/README.md frontmatter spec declares stories field" {
|
|
53
|
-
run grep -E '^stories:.*\[STORY-' "$RFC_README"
|
|
54
|
-
[ "$status" -eq 0 ]
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
@test "rfc-stories-extension: docs/rfcs/README.md describes 0..N + ORDERED cardinality" {
|
|
58
|
-
# The field semantics row must name the ordered + 0..N contract for
|
|
59
|
-
# working-the-problem traversal to read the field correctly.
|
|
60
|
-
run grep -iE 'ordered|execution sequence' "$RFC_README"
|
|
61
|
-
[ "$status" -eq 0 ]
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
# ---------------------------------------------------------------------------
|
|
65
|
-
# Surface 2a: helper renders ## Stories section from populated stories: array
|
|
66
|
-
# ---------------------------------------------------------------------------
|
|
67
|
-
|
|
68
|
-
@test "rfc-stories-extension: helper renders populated stories: array in execution order" {
|
|
69
|
-
# Set up RFC with stories: [STORY-001, STORY-002] frontmatter, plus
|
|
70
|
-
# matching story files. Helper must produce a ## Stories section
|
|
71
|
-
# listing both in the array order.
|
|
72
|
-
cat > docs/rfcs/RFC-001-test.proposed.md <<'EOF'
|
|
73
|
-
---
|
|
74
|
-
status: proposed
|
|
75
|
-
rfc-id: test
|
|
76
|
-
reported: 2026-05-12
|
|
77
|
-
decision-makers: [Test]
|
|
78
|
-
problems: [P170]
|
|
79
|
-
adrs: []
|
|
80
|
-
jtbd: []
|
|
81
|
-
stories: [STORY-001, STORY-002]
|
|
82
|
-
---
|
|
83
|
-
|
|
84
|
-
# RFC-001: Test
|
|
85
|
-
|
|
86
|
-
## Summary
|
|
87
|
-
|
|
88
|
-
Test.
|
|
89
|
-
|
|
90
|
-
## Stories
|
|
91
|
-
|
|
92
|
-
(empty)
|
|
93
|
-
EOF
|
|
94
|
-
cat > docs/stories/draft/STORY-001-first.md <<'EOF'
|
|
95
|
-
---
|
|
96
|
-
status: draft
|
|
97
|
-
story-id: first
|
|
98
|
-
problems: [P170]
|
|
99
|
-
jtbd: [JTBD-008]
|
|
100
|
-
rfcs: [RFC-001]
|
|
101
|
-
story-maps: []
|
|
102
|
-
estimated-effort: deferred
|
|
103
|
-
---
|
|
104
|
-
|
|
105
|
-
# STORY-001: First story
|
|
106
|
-
EOF
|
|
107
|
-
cat > docs/stories/draft/STORY-002-second.md <<'EOF'
|
|
108
|
-
---
|
|
109
|
-
status: draft
|
|
110
|
-
story-id: second
|
|
111
|
-
problems: [P170]
|
|
112
|
-
jtbd: [JTBD-008]
|
|
113
|
-
rfcs: [RFC-001]
|
|
114
|
-
story-maps: []
|
|
115
|
-
estimated-effort: deferred
|
|
116
|
-
---
|
|
117
|
-
|
|
118
|
-
# STORY-002: Second story
|
|
119
|
-
EOF
|
|
120
|
-
run bash "$HELPER" docs/rfcs/RFC-001-test.proposed.md Stories
|
|
121
|
-
# Acceptable: zero exit OR advisory-warning exit; non-acceptable is
|
|
122
|
-
# the "unknown section-name" rejection signal.
|
|
123
|
-
[[ "$output" != *"unknown section-name"* ]]
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
# ---------------------------------------------------------------------------
|
|
127
|
-
# Surface 2b: renderer tolerates empty stories: [] on a DRAFT RFC
|
|
128
|
-
# ---------------------------------------------------------------------------
|
|
129
|
-
|
|
130
|
-
@test "rfc-stories-extension: renderer tolerates empty stories: [] on a draft RFC (ADR-089: enforced >=1 at accept, not at render)" {
|
|
131
|
-
# Per ADR-089 every RFC has >=1 story, but empty stories: [] is a legal
|
|
132
|
-
# TRANSIENT state on a draft/proposed RFC before the fix is scoped. The
|
|
133
|
-
# renderer must not reject it (that would block drafting); the >=1-story
|
|
134
|
-
# requirement is enforced at the manage-rfc accept gate by the
|
|
135
|
-
# check-rfc-has-stories predicate, not by this renderer.
|
|
136
|
-
cat > docs/rfcs/RFC-002-atomic.proposed.md <<'EOF'
|
|
137
|
-
---
|
|
138
|
-
status: proposed
|
|
139
|
-
rfc-id: atomic
|
|
140
|
-
reported: 2026-05-12
|
|
141
|
-
decision-makers: [Test]
|
|
142
|
-
problems: [P170]
|
|
143
|
-
adrs: []
|
|
144
|
-
jtbd: []
|
|
145
|
-
stories: []
|
|
146
|
-
---
|
|
147
|
-
|
|
148
|
-
# RFC-002: Atomic RFC
|
|
149
|
-
EOF
|
|
150
|
-
run bash "$HELPER" docs/rfcs/RFC-002-atomic.proposed.md Stories
|
|
151
|
-
[[ "$output" != *"unknown section-name"* ]]
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
# ---------------------------------------------------------------------------
|
|
155
|
-
# Surface 3: capture-rfc + manage-rfc SKILL.md document the extension
|
|
156
|
-
# ---------------------------------------------------------------------------
|
|
157
|
-
|
|
158
|
-
@test "rfc-stories-extension: capture-rfc SKILL.md names --stories flag" {
|
|
159
|
-
run grep -E '\-\-stories STORY-' "$CAPTURE_RFC"
|
|
160
|
-
[ "$status" -eq 0 ]
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
@test "rfc-stories-extension: capture-rfc SKILL.md frontmatter template includes stories field" {
|
|
164
|
-
run grep -E '^stories:' "$CAPTURE_RFC"
|
|
165
|
-
[ "$status" -eq 0 ]
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
@test "rfc-stories-extension: manage-rfc SKILL.md invokes update-rfc-references-section.sh with Stories" {
|
|
169
|
-
# The forward-trace contract on every transition needs the helper call
|
|
170
|
-
# in the SKILL body. Behavioural assertion on the presence of the
|
|
171
|
-
# load-bearing call path; without it, manage-rfc transitions would
|
|
172
|
-
# silently leave the body section stale.
|
|
173
|
-
run grep -E 'wr-itil-update-rfc-references-section.*Stories' "$MANAGE_RFC"
|
|
174
|
-
[ "$status" -eq 0 ]
|
|
175
|
-
}
|