@windyroad/retrospective 0.27.1 → 0.27.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 +5 -2
- package/hooks/test/retrospective-deferral-census.bats +0 -112
- package/hooks/test/retrospective-readme-jtbd-currency.bats +0 -312
- package/scripts/test/check-ask-hygiene.bats +0 -262
- package/scripts/test/check-autocreate-rfc-scope.bats +0 -250
- package/scripts/test/check-briefing-budgets.bats +0 -349
- package/scripts/test/check-internal-id-leaks.bats +0 -286
- package/scripts/test/check-plugin-maturity-drift.bats +0 -269
- package/scripts/test/check-readme-jtbd-currency.bats +0 -165
- package/scripts/test/check-skill-md-budgets.bats +0 -336
- package/scripts/test/check-tarball-shipped-shims.bats +0 -284
- package/scripts/test/check-tickets-deferred-cause.bats +0 -330
- package/scripts/test/list-plugin-attribution.bats +0 -149
- package/scripts/test/measure-context-budget.bats +0 -298
- package/skills/analyze-context/test/analyze-context-skill-contract.bats +0 -142
- package/skills/migrate-briefing/test/migrate-briefing-contract.bats +0 -105
- package/skills/migrate-briefing/test/migrate-briefing-fixture.bats +0 -242
- package/skills/run-retro/test/run-retro-anti-pattern-clause.bats +0 -87
- package/skills/run-retro/test/run-retro-codification-candidates.bats +0 -168
- package/skills/run-retro/test/run-retro-context-usage-step-2c.bats +0 -156
- package/skills/run-retro/test/run-retro-pipeline-instability-scan.bats +0 -122
- package/skills/run-retro/test/run-retro-signal-vs-noise.bats +0 -137
- package/skills/run-retro/test/run-retro-skill-candidates.bats +0 -116
- package/skills/run-retro/test/run-retro-stage-1-fallback-gating.bats +0 -65
- package/skills/run-retro/test/run-retro-step-2d-r6-auto-flag.bats +0 -82
- package/skills/run-retro/test/run-retro-step-3-tier-3-branch-b-evidence-based.bats +0 -189
- package/skills/run-retro/test/run-retro-step-4a-cross-plugin-dispatch.bats +0 -114
- package/skills/run-retro/test/run-retro-step-4a-prior-session-evidence-drain.bats +0 -168
- package/skills/run-retro/test/run-retro-step-4a-recovery-path.bats +0 -84
- package/skills/run-retro/test/run-retro-step-4b-retro-auto-ticket-carveout.bats +0 -115
- package/skills/run-retro/test/run-retro-ticket-first-flow.bats +0 -161
- package/skills/run-retro/test/run-retro-verification-close-housekeeping.bats +0 -132
|
@@ -1,262 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bats
|
|
2
|
-
#
|
|
3
|
-
# packages/retrospective/scripts/test/check-ask-hygiene.bats
|
|
4
|
-
#
|
|
5
|
-
# Behavioural tests for `check-ask-hygiene.sh` — the ask-hygiene trail
|
|
6
|
-
# advisory script (P135 Phase 5 / ADR-044). Mirrors the test pattern of
|
|
7
|
-
# `check-briefing-budgets.bats`.
|
|
8
|
-
#
|
|
9
|
-
# Tests are behavioural per ADR-005 / ADR-037 — they exercise the
|
|
10
|
-
# script end-to-end against fixture trail directories and assert on
|
|
11
|
-
# stdout / stderr / exit shape. No structural greps of the script
|
|
12
|
-
# source itself per ADR-044's deviation-default to behavioural-by-
|
|
13
|
-
# default for skill / script testing.
|
|
14
|
-
#
|
|
15
|
-
# @problem P135 (Phase 5 measurement)
|
|
16
|
-
# @adr ADR-044 (Decision-Delegation Contract — lazy-count metric)
|
|
17
|
-
# @adr ADR-040 (Tier 3 advisory-not-fail-closed)
|
|
18
|
-
# @adr ADR-005 / ADR-037 (Plugin testing strategy — behavioural tests)
|
|
19
|
-
# @jtbd JTBD-001 / JTBD-006 / JTBD-201
|
|
20
|
-
|
|
21
|
-
SCRIPT="${BATS_TEST_DIRNAME}/../check-ask-hygiene.sh"
|
|
22
|
-
|
|
23
|
-
setup() {
|
|
24
|
-
TEST_DIR="$(mktemp -d)"
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
teardown() {
|
|
28
|
-
rm -rf "$TEST_DIR"
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
# ── Pre-checks ──────────────────────────────────────────────────────────────
|
|
32
|
-
|
|
33
|
-
@test "script file exists and is executable" {
|
|
34
|
-
[ -f "$SCRIPT" ]
|
|
35
|
-
[ -x "$SCRIPT" ]
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
@test "missing retros dir exits 2 with error message on stderr" {
|
|
39
|
-
run bash "$SCRIPT" "$TEST_DIR/does-not-exist"
|
|
40
|
-
[ "$status" -eq 2 ]
|
|
41
|
-
[[ "$output" == *"retros dir not found"* ]]
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
@test "empty retros dir exits 0 with empty stdout" {
|
|
45
|
-
run bash "$SCRIPT" "$TEST_DIR"
|
|
46
|
-
[ "$status" -eq 0 ]
|
|
47
|
-
[ -z "$output" ]
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
@test "default retros-dir argument is docs/retros (when omitted)" {
|
|
51
|
-
# Behavioural: script must accept no-arg invocation when invoked from a project root.
|
|
52
|
-
# We exercise from a fresh tmp dir with no docs/retros to assert the missing-dir
|
|
53
|
-
# behaviour fires when the default path is used.
|
|
54
|
-
cd "$TEST_DIR"
|
|
55
|
-
run bash "$SCRIPT"
|
|
56
|
-
[ "$status" -eq 2 ]
|
|
57
|
-
[[ "$output" == *"docs/retros"* ]]
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
# ── Single-entry behaviour ──────────────────────────────────────────────────
|
|
61
|
-
|
|
62
|
-
@test "single trail entry emits one RETRO line and no TREND" {
|
|
63
|
-
cat > "$TEST_DIR/2026-04-27-ask-hygiene.md" <<'TRAIL'
|
|
64
|
-
**Lazy count: 5**
|
|
65
|
-
**Direction count: 2**
|
|
66
|
-
TRAIL
|
|
67
|
-
run bash "$SCRIPT" "$TEST_DIR"
|
|
68
|
-
[ "$status" -eq 0 ]
|
|
69
|
-
[[ "$output" == *"RETRO 2026-04-27 lazy=5 direction=2"* ]]
|
|
70
|
-
[[ "$output" != *"TREND"* ]]
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
@test "trail entry without lazy-count line is skipped silently" {
|
|
74
|
-
cat > "$TEST_DIR/2026-04-27-ask-hygiene.md" <<'TRAIL'
|
|
75
|
-
# Some retro file with no lazy count
|
|
76
|
-
**Direction count: 3**
|
|
77
|
-
TRAIL
|
|
78
|
-
run bash "$SCRIPT" "$TEST_DIR"
|
|
79
|
-
[ "$status" -eq 0 ]
|
|
80
|
-
[ -z "$output" ]
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
@test "ADR-074 substance-confirm ask counts as direction, never inflates lazy" {
|
|
84
|
-
# A retro where the only AskUserQuestion was a substance-confirm-before-build
|
|
85
|
-
# ask: run-retro Step 2d tags it `direction` (cat-1, ADR-074), so the trail
|
|
86
|
-
# records direction=1 lazy=0. The script must report it under direction and
|
|
87
|
-
# leave lazy at 0 — the exclusion holds by construction (category-agnostic tally).
|
|
88
|
-
cat > "$TEST_DIR/2026-05-27-ask-hygiene.md" <<'TRAIL'
|
|
89
|
-
**Lazy count: 0**
|
|
90
|
-
**Direction count: 1**
|
|
91
|
-
TRAIL
|
|
92
|
-
run bash "$SCRIPT" "$TEST_DIR"
|
|
93
|
-
[ "$status" -eq 0 ]
|
|
94
|
-
[[ "$output" == *"RETRO 2026-05-27 lazy=0 direction=1"* ]]
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
# ── Multi-entry behaviour ───────────────────────────────────────────────────
|
|
98
|
-
|
|
99
|
-
@test "multiple trail entries emit RETRO lines sorted oldest-first by date" {
|
|
100
|
-
cat > "$TEST_DIR/2026-04-27-ask-hygiene.md" <<'TRAIL'
|
|
101
|
-
**Lazy count: 1**
|
|
102
|
-
TRAIL
|
|
103
|
-
cat > "$TEST_DIR/2026-04-25-ask-hygiene.md" <<'TRAIL'
|
|
104
|
-
**Lazy count: 5**
|
|
105
|
-
TRAIL
|
|
106
|
-
cat > "$TEST_DIR/2026-04-26-ask-hygiene.md" <<'TRAIL'
|
|
107
|
-
**Lazy count: 3**
|
|
108
|
-
TRAIL
|
|
109
|
-
run bash "$SCRIPT" "$TEST_DIR"
|
|
110
|
-
[ "$status" -eq 0 ]
|
|
111
|
-
# Assert order: 04-25 (oldest) → 04-26 → 04-27 (newest)
|
|
112
|
-
line1="${lines[0]}"
|
|
113
|
-
line2="${lines[1]}"
|
|
114
|
-
line3="${lines[2]}"
|
|
115
|
-
[[ "$line1" == *"2026-04-25"* ]]
|
|
116
|
-
[[ "$line2" == *"2026-04-26"* ]]
|
|
117
|
-
[[ "$line3" == *"2026-04-27"* ]]
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
@test "two-or-more entries emit TREND line with first/last/delta" {
|
|
121
|
-
cat > "$TEST_DIR/2026-04-25-ask-hygiene.md" <<'TRAIL'
|
|
122
|
-
**Lazy count: 5**
|
|
123
|
-
TRAIL
|
|
124
|
-
cat > "$TEST_DIR/2026-04-27-ask-hygiene.md" <<'TRAIL'
|
|
125
|
-
**Lazy count: 1**
|
|
126
|
-
TRAIL
|
|
127
|
-
run bash "$SCRIPT" "$TEST_DIR"
|
|
128
|
-
[ "$status" -eq 0 ]
|
|
129
|
-
[[ "$output" == *"TREND lazy_first=5 lazy_last=1 delta=-4"* ]]
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
@test "TREND line shows positive delta when lazy count grew" {
|
|
133
|
-
cat > "$TEST_DIR/2026-04-25-ask-hygiene.md" <<'TRAIL'
|
|
134
|
-
**Lazy count: 1**
|
|
135
|
-
TRAIL
|
|
136
|
-
cat > "$TEST_DIR/2026-04-27-ask-hygiene.md" <<'TRAIL'
|
|
137
|
-
**Lazy count: 4**
|
|
138
|
-
TRAIL
|
|
139
|
-
run bash "$SCRIPT" "$TEST_DIR"
|
|
140
|
-
[ "$status" -eq 0 ]
|
|
141
|
-
[[ "$output" == *"TREND lazy_first=1 lazy_last=4 delta=+3"* ]]
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
@test "TREND line shows zero delta when lazy count unchanged" {
|
|
145
|
-
cat > "$TEST_DIR/2026-04-25-ask-hygiene.md" <<'TRAIL'
|
|
146
|
-
**Lazy count: 2**
|
|
147
|
-
TRAIL
|
|
148
|
-
cat > "$TEST_DIR/2026-04-27-ask-hygiene.md" <<'TRAIL'
|
|
149
|
-
**Lazy count: 2**
|
|
150
|
-
TRAIL
|
|
151
|
-
run bash "$SCRIPT" "$TEST_DIR"
|
|
152
|
-
[ "$status" -eq 0 ]
|
|
153
|
-
[[ "$output" == *"TREND lazy_first=2 lazy_last=2 delta=+0"* ]]
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
# ── Window override ──────────────────────────────────────────────────────────
|
|
157
|
-
|
|
158
|
-
@test "ASK_HYGIENE_WINDOW=2 keeps only the most-recent 2 entries" {
|
|
159
|
-
for d in 25 26 27; do
|
|
160
|
-
cat > "$TEST_DIR/2026-04-$d-ask-hygiene.md" <<TRAIL
|
|
161
|
-
**Lazy count: $d**
|
|
162
|
-
TRAIL
|
|
163
|
-
done
|
|
164
|
-
ASK_HYGIENE_WINDOW=2 run bash "$SCRIPT" "$TEST_DIR"
|
|
165
|
-
[ "$status" -eq 0 ]
|
|
166
|
-
# Assert: 04-25 not present; 04-26 first; 04-27 last
|
|
167
|
-
[[ "$output" != *"2026-04-25"* ]]
|
|
168
|
-
[[ "$output" == *"RETRO 2026-04-26"* ]]
|
|
169
|
-
[[ "$output" == *"RETRO 2026-04-27"* ]]
|
|
170
|
-
# TREND should reflect the windowed pair, not the full 3
|
|
171
|
-
[[ "$output" == *"TREND lazy_first=26 lazy_last=27 delta=+1"* ]]
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
@test "default window 10 keeps all entries when fewer than 10 exist" {
|
|
175
|
-
cat > "$TEST_DIR/2026-04-25-ask-hygiene.md" <<'TRAIL'
|
|
176
|
-
**Lazy count: 5**
|
|
177
|
-
TRAIL
|
|
178
|
-
cat > "$TEST_DIR/2026-04-27-ask-hygiene.md" <<'TRAIL'
|
|
179
|
-
**Lazy count: 1**
|
|
180
|
-
TRAIL
|
|
181
|
-
run bash "$SCRIPT" "$TEST_DIR"
|
|
182
|
-
[ "$status" -eq 0 ]
|
|
183
|
-
[[ "$output" == *"2026-04-25"* ]]
|
|
184
|
-
[[ "$output" == *"2026-04-27"* ]]
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
# ── Category-coverage shape ──────────────────────────────────────────────────
|
|
188
|
-
|
|
189
|
-
@test "RETRO line includes all 6 category counts (lazy + 5 non-lazy)" {
|
|
190
|
-
cat > "$TEST_DIR/2026-04-27-ask-hygiene.md" <<'TRAIL'
|
|
191
|
-
**Lazy count: 0**
|
|
192
|
-
**Direction count: 3**
|
|
193
|
-
**Override count: 1**
|
|
194
|
-
**Silent-framework count: 1**
|
|
195
|
-
**Taste count: 0**
|
|
196
|
-
**Correction-followup count: 0**
|
|
197
|
-
TRAIL
|
|
198
|
-
run bash "$SCRIPT" "$TEST_DIR"
|
|
199
|
-
[ "$status" -eq 0 ]
|
|
200
|
-
[[ "$output" == *"lazy=0"* ]]
|
|
201
|
-
[[ "$output" == *"direction=3"* ]]
|
|
202
|
-
[[ "$output" == *"override=1"* ]]
|
|
203
|
-
[[ "$output" == *"silent=1"* ]]
|
|
204
|
-
[[ "$output" == *"taste=0"* ]]
|
|
205
|
-
[[ "$output" == *"correction=0"* ]]
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
@test "missing non-lazy categories default to 0" {
|
|
209
|
-
cat > "$TEST_DIR/2026-04-27-ask-hygiene.md" <<'TRAIL'
|
|
210
|
-
**Lazy count: 4**
|
|
211
|
-
TRAIL
|
|
212
|
-
run bash "$SCRIPT" "$TEST_DIR"
|
|
213
|
-
[ "$status" -eq 0 ]
|
|
214
|
-
[[ "$output" == *"lazy=4"* ]]
|
|
215
|
-
[[ "$output" == *"direction=0"* ]]
|
|
216
|
-
[[ "$output" == *"override=0"* ]]
|
|
217
|
-
[[ "$output" == *"silent=0"* ]]
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
# ── Format tolerance ──────────────────────────────────────────────────────────
|
|
221
|
-
|
|
222
|
-
@test "lazy-count line works without bold markdown asterisks" {
|
|
223
|
-
cat > "$TEST_DIR/2026-04-27-ask-hygiene.md" <<'TRAIL'
|
|
224
|
-
Lazy count: 7
|
|
225
|
-
TRAIL
|
|
226
|
-
run bash "$SCRIPT" "$TEST_DIR"
|
|
227
|
-
[ "$status" -eq 0 ]
|
|
228
|
-
[[ "$output" == *"lazy=7"* ]]
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
@test "lazy-count line is case-insensitive on the LAZY label" {
|
|
232
|
-
cat > "$TEST_DIR/2026-04-27-ask-hygiene.md" <<'TRAIL'
|
|
233
|
-
**lazy count: 8**
|
|
234
|
-
TRAIL
|
|
235
|
-
run bash "$SCRIPT" "$TEST_DIR"
|
|
236
|
-
[ "$status" -eq 0 ]
|
|
237
|
-
[[ "$output" == *"lazy=8"* ]]
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
# ── Cross-shell portability (P124 / P133 lessons) ───────────────────────────
|
|
241
|
-
|
|
242
|
-
@test "script glob iteration uses portable for-loop existence check (no shopt nullglob)" {
|
|
243
|
-
# Behavioural: invoking an empty retros dir must NOT emit a literal
|
|
244
|
-
# `*-ask-hygiene.md` because the glob unexpanded to a literal pattern.
|
|
245
|
-
# The script's portable iteration handles this without zsh `shopt -s nullglob`.
|
|
246
|
-
run bash "$SCRIPT" "$TEST_DIR"
|
|
247
|
-
[ "$status" -eq 0 ]
|
|
248
|
-
[[ "$output" != *"*-ask-hygiene.md"* ]]
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
# ── Read-only contract ──────────────────────────────────────────────────────
|
|
252
|
-
|
|
253
|
-
@test "script is read-only — fixture tree unchanged after run" {
|
|
254
|
-
cat > "$TEST_DIR/2026-04-27-ask-hygiene.md" <<'TRAIL'
|
|
255
|
-
**Lazy count: 3**
|
|
256
|
-
TRAIL
|
|
257
|
-
pre_hash=$(find "$TEST_DIR" -type f -exec cksum {} \; 2>/dev/null | sort | cksum | awk '{print $1}')
|
|
258
|
-
run bash "$SCRIPT" "$TEST_DIR"
|
|
259
|
-
[ "$status" -eq 0 ]
|
|
260
|
-
post_hash=$(find "$TEST_DIR" -type f -exec cksum {} \; 2>/dev/null | sort | cksum | awk '{print $1}')
|
|
261
|
-
[ "$pre_hash" = "$post_hash" ]
|
|
262
|
-
}
|
|
@@ -1,250 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bats
|
|
2
|
-
#
|
|
3
|
-
# packages/retrospective/scripts/test/check-autocreate-rfc-scope.bats
|
|
4
|
-
#
|
|
5
|
-
# Behavioural tests for `check-autocreate-rfc-scope.sh` — the ADR-073
|
|
6
|
-
# auto-create-RFC reassessment advisory (RFC-005 B9). The detector scans
|
|
7
|
-
# docs/rfcs/*.proposed.md for skeleton (capture-rfc placeholder-scope) RFCs
|
|
8
|
-
# whose `problems:` trace a fix-shipped problem — the "auto-created RFC
|
|
9
|
-
# under-scoped" signal ADR-073's Reassessment Criteria names. run-retro
|
|
10
|
-
# Step 2b surfaces the candidates so a human can assess whether auto-created
|
|
11
|
-
# RFCs are systematically under-scoped.
|
|
12
|
-
#
|
|
13
|
-
# Tests are behavioural per ADR-005 / ADR-052 / P081 — they exercise the
|
|
14
|
-
# script end-to-end against fixture docs/rfcs + docs/problems trees and
|
|
15
|
-
# assert on stdout / exit-code shape. No structural greps of the script
|
|
16
|
-
# source. Mirrors the sibling `check-readme-jtbd-currency.bats`.
|
|
17
|
-
#
|
|
18
|
-
# @problem P314 (rework the fix-time RFC-trace gate — RFC-005 B9 wires the
|
|
19
|
-
# ADR-073 reassessment criterion into run-retro Step 2b)
|
|
20
|
-
# @problem P081 (Structural-content tests are wasteful — behavioural preferred)
|
|
21
|
-
# @adr ADR-073 (fix-time gate auto-creates a missing RFC; Reassessment
|
|
22
|
-
# Criteria: revisit if auto-created RFCs systematically under-scoped)
|
|
23
|
-
# @adr ADR-013 Rule 6 (non-interactive fail-safe — advisory script never blocks)
|
|
24
|
-
# @adr ADR-040 (declarative-first / advisory-then-escalate precedent)
|
|
25
|
-
# @adr ADR-005 / ADR-052 (behavioural tests via bats)
|
|
26
|
-
|
|
27
|
-
SCRIPT="${BATS_TEST_DIRNAME}/../check-autocreate-rfc-scope.sh"
|
|
28
|
-
|
|
29
|
-
# The capture-rfc skeleton placeholder string (em-dash is U+2014, matching
|
|
30
|
-
# capture-rfc/SKILL.md and the live RFC-026 skeleton).
|
|
31
|
-
PLACEHOLDER='(deferred — populate at /wr-itil:manage-rfc accepted transition)'
|
|
32
|
-
|
|
33
|
-
setup() {
|
|
34
|
-
TEST_DIR="$(mktemp -d)"
|
|
35
|
-
RFCS_DIR="$TEST_DIR/rfcs"
|
|
36
|
-
PROBLEMS_DIR="$TEST_DIR/problems"
|
|
37
|
-
mkdir -p "$RFCS_DIR" "$PROBLEMS_DIR"
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
teardown() {
|
|
41
|
-
rm -rf "$TEST_DIR"
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
# Write a proposed RFC. $1 = filename, $2 = problems-csv (e.g. "P361"),
|
|
45
|
-
# $3 = scope-body (use $PLACEHOLDER for a skeleton).
|
|
46
|
-
make_rfc() {
|
|
47
|
-
local fname="$1" probs="$2" scope="$3"
|
|
48
|
-
cat > "$RFCS_DIR/$fname" <<EOF
|
|
49
|
-
---
|
|
50
|
-
status: proposed
|
|
51
|
-
human-oversight: unconfirmed
|
|
52
|
-
problems: [$probs]
|
|
53
|
-
---
|
|
54
|
-
|
|
55
|
-
# $fname
|
|
56
|
-
|
|
57
|
-
## Scope
|
|
58
|
-
|
|
59
|
-
$scope
|
|
60
|
-
|
|
61
|
-
## Tasks
|
|
62
|
-
|
|
63
|
-
- [ ] $PLACEHOLDER
|
|
64
|
-
EOF
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
# Write a problem ticket under a lifecycle subdir. $1 = subdir, $2 = num,
|
|
68
|
-
# $3 = body.
|
|
69
|
-
make_problem() {
|
|
70
|
-
local sub="$1" num="$2" body="$3"
|
|
71
|
-
mkdir -p "$PROBLEMS_DIR/$sub"
|
|
72
|
-
cat > "$PROBLEMS_DIR/$sub/$num-stub.md" <<EOF
|
|
73
|
-
# P$num stub ticket
|
|
74
|
-
|
|
75
|
-
$body
|
|
76
|
-
EOF
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
# ── Pre-checks ──────────────────────────────────────────────────────────────
|
|
80
|
-
|
|
81
|
-
@test "script file exists and is executable" {
|
|
82
|
-
[ -f "$SCRIPT" ]
|
|
83
|
-
[ -x "$SCRIPT" ]
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
@test "missing rfcs dir exits 2 with error message on stderr" {
|
|
87
|
-
run bash "$SCRIPT" "$TEST_DIR/does-not-exist" "$PROBLEMS_DIR"
|
|
88
|
-
[ "$status" -eq 2 ]
|
|
89
|
-
[[ "$output" == *"rfcs dir not found"* ]]
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
@test "empty rfcs dir exits 0 with a zeroed TOTAL summary" {
|
|
93
|
-
run bash "$SCRIPT" "$RFCS_DIR" "$PROBLEMS_DIR"
|
|
94
|
-
[ "$status" -eq 0 ]
|
|
95
|
-
[[ "$output" == *"TOTAL proposed_skeletons=0 under_scoped=0"* ]]
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
# ── Regression anchor: the P361/RFC-026 gate-on-next-touch shape ─────────────
|
|
99
|
-
# A known-error-located problem whose fix is recorded as a populated
|
|
100
|
-
# `## Fix Strategy` (NO `## Fix Released` heading), traced by a
|
|
101
|
-
# placeholder-scope RFC. The original (pre-review) predicate missed this.
|
|
102
|
-
|
|
103
|
-
@test "known-error problem with populated Fix Strategy (no Fix Released) is under-scoped" {
|
|
104
|
-
make_problem "known-error" "361" "## Fix Strategy
|
|
105
|
-
|
|
106
|
-
Implemented in \`packages/itil/scripts/derive-release-vehicle.sh\`. Full 15-test suite green; de-facto-released exit-0 branch added."
|
|
107
|
-
make_rfc "RFC-026-stub.proposed.md" "P361" "$PLACEHOLDER"
|
|
108
|
-
|
|
109
|
-
run bash "$SCRIPT" "$RFCS_DIR" "$PROBLEMS_DIR"
|
|
110
|
-
[ "$status" -eq 0 ]
|
|
111
|
-
[[ "$output" == *"AUTOCREATE-RFC under-scoped rfc=RFC-026"* ]]
|
|
112
|
-
[[ "$output" == *"problems=P361"* ]]
|
|
113
|
-
[[ "$output" == *"shipped=P361:fix-strategy"* ]]
|
|
114
|
-
[[ "$output" == *"TOTAL proposed_skeletons=1 under_scoped=1"* ]]
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
# ── verifying/ lifecycle-directory basis (the P215/RFC-021 shape) ───────────
|
|
118
|
-
|
|
119
|
-
@test "skeleton RFC tracing a verifying/ problem is under-scoped (directory basis)" {
|
|
120
|
-
make_problem "verifying" "215" "## Fix Strategy
|
|
121
|
-
|
|
122
|
-
Recovery directive added to the architect gate."
|
|
123
|
-
make_rfc "RFC-021-stub.proposed.md" "P215" "$PLACEHOLDER"
|
|
124
|
-
|
|
125
|
-
run bash "$SCRIPT" "$RFCS_DIR" "$PROBLEMS_DIR"
|
|
126
|
-
[ "$status" -eq 0 ]
|
|
127
|
-
[[ "$output" == *"AUTOCREATE-RFC under-scoped rfc=RFC-021"* ]]
|
|
128
|
-
[[ "$output" == *"shipped=P215:verifying"* ]]
|
|
129
|
-
[[ "$output" == *"TOTAL proposed_skeletons=1 under_scoped=1"* ]]
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
# ── Fix Released heading basis ──────────────────────────────────────────────
|
|
133
|
-
|
|
134
|
-
@test "skeleton RFC tracing a problem with a Fix Released heading is under-scoped" {
|
|
135
|
-
make_problem "known-error" "500" "## Fix Released
|
|
136
|
-
|
|
137
|
-
Shipped in @windyroad/itil@1.2.3."
|
|
138
|
-
make_rfc "RFC-050-stub.proposed.md" "P500" "$PLACEHOLDER"
|
|
139
|
-
|
|
140
|
-
run bash "$SCRIPT" "$RFCS_DIR" "$PROBLEMS_DIR"
|
|
141
|
-
[ "$status" -eq 0 ]
|
|
142
|
-
[[ "$output" == *"AUTOCREATE-RFC under-scoped rfc=RFC-050"* ]]
|
|
143
|
-
[[ "$output" == *"shipped=P500:fix-released"* ]]
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
# ── Non-candidate: skeleton RFC tracing an open, no-fix problem ──────────────
|
|
147
|
-
# A legitimately-still-skeleton RFC — the fix has not been scoped yet, so the
|
|
148
|
-
# RFC SHOULD still be a skeleton. Counted in proposed_skeletons, NOT under_scoped.
|
|
149
|
-
|
|
150
|
-
@test "skeleton RFC tracing an open problem with no fix is NOT under-scoped" {
|
|
151
|
-
make_problem "open" "304" "## Symptoms
|
|
152
|
-
|
|
153
|
-
Duplicate-and-sync is fragile. No fix proposed yet."
|
|
154
|
-
make_rfc "RFC-023-stub.proposed.md" "P304" "$PLACEHOLDER"
|
|
155
|
-
|
|
156
|
-
run bash "$SCRIPT" "$RFCS_DIR" "$PROBLEMS_DIR"
|
|
157
|
-
[ "$status" -eq 0 ]
|
|
158
|
-
[[ "$output" != *"rfc=RFC-023"* ]]
|
|
159
|
-
[[ "$output" == *"TOTAL proposed_skeletons=1 under_scoped=0"* ]]
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
# ── Robustness: a bare/empty Fix Strategy heading is NOT populated ──────────
|
|
163
|
-
# (architect note — distinguish a populated section from a stub heading.)
|
|
164
|
-
|
|
165
|
-
@test "skeleton RFC tracing a problem with an EMPTY Fix Strategy heading is NOT under-scoped" {
|
|
166
|
-
make_problem "known-error" "600" "## Fix Strategy
|
|
167
|
-
|
|
168
|
-
## Root Cause Analysis
|
|
169
|
-
|
|
170
|
-
Some analysis."
|
|
171
|
-
make_rfc "RFC-060-stub.proposed.md" "P600" "$PLACEHOLDER"
|
|
172
|
-
|
|
173
|
-
run bash "$SCRIPT" "$RFCS_DIR" "$PROBLEMS_DIR"
|
|
174
|
-
[ "$status" -eq 0 ]
|
|
175
|
-
[[ "$output" != *"rfc=RFC-060"* ]]
|
|
176
|
-
[[ "$output" == *"TOTAL proposed_skeletons=1 under_scoped=0"* ]]
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
# ── Non-candidate: a fleshed-out (non-skeleton) RFC is never counted ─────────
|
|
180
|
-
|
|
181
|
-
@test "non-skeleton RFC (Scope fleshed out) tracing a shipped problem is NOT counted" {
|
|
182
|
-
make_problem "closed" "700" "## Fix Strategy
|
|
183
|
-
|
|
184
|
-
Done and shipped."
|
|
185
|
-
make_rfc "RFC-070-stub.proposed.md" "P700" "This RFC has a real scope paragraph describing the change."
|
|
186
|
-
|
|
187
|
-
run bash "$SCRIPT" "$RFCS_DIR" "$PROBLEMS_DIR"
|
|
188
|
-
[ "$status" -eq 0 ]
|
|
189
|
-
[[ "$output" != *"rfc=RFC-070"* ]]
|
|
190
|
-
[[ "$output" == *"TOTAL proposed_skeletons=0 under_scoped=0"* ]]
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
# ── closed/ lifecycle-directory basis ───────────────────────────────────────
|
|
194
|
-
|
|
195
|
-
@test "skeleton RFC tracing a closed/ problem is under-scoped (directory basis)" {
|
|
196
|
-
make_problem "closed" "800" "## Fix Strategy
|
|
197
|
-
|
|
198
|
-
Resolved and verified."
|
|
199
|
-
make_rfc "RFC-080-stub.proposed.md" "P800" "$PLACEHOLDER"
|
|
200
|
-
|
|
201
|
-
run bash "$SCRIPT" "$RFCS_DIR" "$PROBLEMS_DIR"
|
|
202
|
-
[ "$status" -eq 0 ]
|
|
203
|
-
[[ "$output" == *"AUTOCREATE-RFC under-scoped rfc=RFC-080"* ]]
|
|
204
|
-
[[ "$output" == *"shipped=P800:closed"* ]]
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
# ── Multi-RFC aggregation + TOTAL summary ───────────────────────────────────
|
|
208
|
-
|
|
209
|
-
@test "multi-RFC aggregation: one candidate line per under-scoped skeleton + TOTAL" {
|
|
210
|
-
# under-scoped (known-error + Fix Strategy)
|
|
211
|
-
make_problem "known-error" "361" "## Fix Strategy
|
|
212
|
-
|
|
213
|
-
Shipped."
|
|
214
|
-
make_rfc "RFC-026-stub.proposed.md" "P361" "$PLACEHOLDER"
|
|
215
|
-
# under-scoped (verifying)
|
|
216
|
-
make_problem "verifying" "215" "## Fix Strategy
|
|
217
|
-
|
|
218
|
-
Shipped."
|
|
219
|
-
make_rfc "RFC-021-stub.proposed.md" "P215" "$PLACEHOLDER"
|
|
220
|
-
# legitimately-skeleton (open, no fix)
|
|
221
|
-
make_problem "open" "304" "## Symptoms
|
|
222
|
-
|
|
223
|
-
No fix yet."
|
|
224
|
-
make_rfc "RFC-023-stub.proposed.md" "P304" "$PLACEHOLDER"
|
|
225
|
-
|
|
226
|
-
run bash "$SCRIPT" "$RFCS_DIR" "$PROBLEMS_DIR"
|
|
227
|
-
[ "$status" -eq 0 ]
|
|
228
|
-
[[ "$output" == *"rfc=RFC-026"* ]]
|
|
229
|
-
[[ "$output" == *"rfc=RFC-021"* ]]
|
|
230
|
-
[[ "$output" != *"rfc=RFC-023"* ]]
|
|
231
|
-
[[ "$output" == *"TOTAL proposed_skeletons=3 under_scoped=2"* ]]
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
# ── Multi-problem trace: any one shipped problem makes the RFC under-scoped ──
|
|
235
|
-
|
|
236
|
-
@test "skeleton RFC tracing multiple problems is under-scoped if ANY is fix-shipped" {
|
|
237
|
-
make_problem "open" "900" "## Symptoms
|
|
238
|
-
|
|
239
|
-
No fix."
|
|
240
|
-
make_problem "verifying" "901" "## Fix Strategy
|
|
241
|
-
|
|
242
|
-
Shipped."
|
|
243
|
-
make_rfc "RFC-090-stub.proposed.md" "P900, P901" "$PLACEHOLDER"
|
|
244
|
-
|
|
245
|
-
run bash "$SCRIPT" "$RFCS_DIR" "$PROBLEMS_DIR"
|
|
246
|
-
[ "$status" -eq 0 ]
|
|
247
|
-
[[ "$output" == *"AUTOCREATE-RFC under-scoped rfc=RFC-090"* ]]
|
|
248
|
-
[[ "$output" == *"problems=P900,P901"* ]]
|
|
249
|
-
[[ "$output" == *"shipped=P901:verifying"* ]]
|
|
250
|
-
}
|