@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.
Files changed (33) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/package.json +5 -2
  3. package/hooks/test/retrospective-deferral-census.bats +0 -112
  4. package/hooks/test/retrospective-readme-jtbd-currency.bats +0 -312
  5. package/scripts/test/check-ask-hygiene.bats +0 -262
  6. package/scripts/test/check-autocreate-rfc-scope.bats +0 -250
  7. package/scripts/test/check-briefing-budgets.bats +0 -349
  8. package/scripts/test/check-internal-id-leaks.bats +0 -286
  9. package/scripts/test/check-plugin-maturity-drift.bats +0 -269
  10. package/scripts/test/check-readme-jtbd-currency.bats +0 -165
  11. package/scripts/test/check-skill-md-budgets.bats +0 -336
  12. package/scripts/test/check-tarball-shipped-shims.bats +0 -284
  13. package/scripts/test/check-tickets-deferred-cause.bats +0 -330
  14. package/scripts/test/list-plugin-attribution.bats +0 -149
  15. package/scripts/test/measure-context-budget.bats +0 -298
  16. package/skills/analyze-context/test/analyze-context-skill-contract.bats +0 -142
  17. package/skills/migrate-briefing/test/migrate-briefing-contract.bats +0 -105
  18. package/skills/migrate-briefing/test/migrate-briefing-fixture.bats +0 -242
  19. package/skills/run-retro/test/run-retro-anti-pattern-clause.bats +0 -87
  20. package/skills/run-retro/test/run-retro-codification-candidates.bats +0 -168
  21. package/skills/run-retro/test/run-retro-context-usage-step-2c.bats +0 -156
  22. package/skills/run-retro/test/run-retro-pipeline-instability-scan.bats +0 -122
  23. package/skills/run-retro/test/run-retro-signal-vs-noise.bats +0 -137
  24. package/skills/run-retro/test/run-retro-skill-candidates.bats +0 -116
  25. package/skills/run-retro/test/run-retro-stage-1-fallback-gating.bats +0 -65
  26. package/skills/run-retro/test/run-retro-step-2d-r6-auto-flag.bats +0 -82
  27. package/skills/run-retro/test/run-retro-step-3-tier-3-branch-b-evidence-based.bats +0 -189
  28. package/skills/run-retro/test/run-retro-step-4a-cross-plugin-dispatch.bats +0 -114
  29. package/skills/run-retro/test/run-retro-step-4a-prior-session-evidence-drain.bats +0 -168
  30. package/skills/run-retro/test/run-retro-step-4a-recovery-path.bats +0 -84
  31. package/skills/run-retro/test/run-retro-step-4b-retro-auto-ticket-carveout.bats +0 -115
  32. package/skills/run-retro/test/run-retro-ticket-first-flow.bats +0 -161
  33. 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
- }