@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,298 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bats
|
|
2
|
-
|
|
3
|
-
# @problem P101 — wr-retrospective has no context-usage analysis. ADR-043
|
|
4
|
-
# (Progressive context-usage measurement and reporting for retrospective
|
|
5
|
-
# sessions) introduces a read-only diagnostic script
|
|
6
|
-
# `packages/retrospective/scripts/measure-context-budget.sh` as the cheap-
|
|
7
|
-
# layer measurement primitive. This fixture pins the script's behavioural
|
|
8
|
-
# contract.
|
|
9
|
-
#
|
|
10
|
-
# Contract: `measure-context-budget.sh [<project-root>]` walks the
|
|
11
|
-
# session's on-disk context contributors and reports per-source bucket
|
|
12
|
-
# byte totals. Default project-root is $CLAUDE_PROJECT_DIR if set, else
|
|
13
|
-
# the current working directory.
|
|
14
|
-
#
|
|
15
|
-
# Threshold default 10240 (the 5% / 200K cheap-layer envelope per ADR-043),
|
|
16
|
-
# overridable via CONTEXT_BUDGET_MAX_BYTES.
|
|
17
|
-
#
|
|
18
|
-
# Exit codes:
|
|
19
|
-
# 0 = always (advisory only — overflow is signal, not failure)
|
|
20
|
-
# 2 = parse error (project root missing or unreadable)
|
|
21
|
-
#
|
|
22
|
-
# Output format (one line per bucket, terse machine-readable per ADR-038
|
|
23
|
-
# progressive-disclosure budget — ≤150 bytes per row):
|
|
24
|
-
# BUCKET <name> bytes=<N>
|
|
25
|
-
# BUCKET <name> not-measured reason=<reason>
|
|
26
|
-
#
|
|
27
|
-
# Plus one trailing diagnostic row carrying the threshold:
|
|
28
|
-
# THRESHOLD bytes=<N>
|
|
29
|
-
#
|
|
30
|
-
# @adr ADR-043 (Progressive context-usage measurement; this script is the
|
|
31
|
-
# measurement primitive)
|
|
32
|
-
# @adr ADR-038 (Progressive disclosure — per-row byte budget)
|
|
33
|
-
# @adr ADR-026 (Agent output grounding — explicit not-measured sentinels)
|
|
34
|
-
# @adr ADR-013 Rule 1 / Rule 6 — interactive vs AFK
|
|
35
|
-
# @adr ADR-005 (Plugin testing strategy — behavioural fixture)
|
|
36
|
-
# @adr ADR-037 (Skill testing strategy — bats-contract precedent)
|
|
37
|
-
# @jtbd JTBD-001 / JTBD-005 / JTBD-006
|
|
38
|
-
|
|
39
|
-
setup() {
|
|
40
|
-
SCRIPTS_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
|
|
41
|
-
SCRIPT="$SCRIPTS_DIR/measure-context-budget.sh"
|
|
42
|
-
FIXTURE_DIR="$(mktemp -d)"
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
teardown() {
|
|
46
|
-
rm -rf "$FIXTURE_DIR"
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
# ── Existence + executable ──────────────────────────────────────────────────
|
|
50
|
-
|
|
51
|
-
@test "measure-context-budget: script file exists at expected path" {
|
|
52
|
-
[ -f "$SCRIPT" ]
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
@test "measure-context-budget: script is executable" {
|
|
56
|
-
[ -x "$SCRIPT" ]
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
# ── Exit codes ──────────────────────────────────────────────────────────────
|
|
60
|
-
|
|
61
|
-
@test "measure-context-budget: empty project root exits 0 (advisory)" {
|
|
62
|
-
run bash "$SCRIPT" "$FIXTURE_DIR"
|
|
63
|
-
[ "$status" -eq 0 ]
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
@test "measure-context-budget: missing project root exits 2 (parse error)" {
|
|
67
|
-
run bash "$SCRIPT" "/path/that/does/not/exist/zz_$$"
|
|
68
|
-
[ "$status" -eq 2 ]
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
# ── Output shape — every run emits all buckets ──────────────────────────────
|
|
72
|
-
|
|
73
|
-
@test "measure-context-budget: output contains hooks bucket row" {
|
|
74
|
-
run bash "$SCRIPT" "$FIXTURE_DIR"
|
|
75
|
-
[ "$status" -eq 0 ]
|
|
76
|
-
echo "$output" | grep -q '^BUCKET hooks '
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
@test "measure-context-budget: output contains skills bucket row" {
|
|
80
|
-
run bash "$SCRIPT" "$FIXTURE_DIR"
|
|
81
|
-
echo "$output" | grep -q '^BUCKET skills '
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
@test "measure-context-budget: output contains briefing bucket row" {
|
|
85
|
-
run bash "$SCRIPT" "$FIXTURE_DIR"
|
|
86
|
-
echo "$output" | grep -q '^BUCKET briefing '
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
@test "measure-context-budget: output contains decisions bucket row" {
|
|
90
|
-
run bash "$SCRIPT" "$FIXTURE_DIR"
|
|
91
|
-
echo "$output" | grep -q '^BUCKET decisions '
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
@test "measure-context-budget: output contains problems bucket row" {
|
|
95
|
-
run bash "$SCRIPT" "$FIXTURE_DIR"
|
|
96
|
-
echo "$output" | grep -q '^BUCKET problems '
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
@test "measure-context-budget: output contains jtbd bucket row" {
|
|
100
|
-
run bash "$SCRIPT" "$FIXTURE_DIR"
|
|
101
|
-
echo "$output" | grep -q '^BUCKET jtbd '
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
@test "measure-context-budget: output contains project-claude-md bucket row" {
|
|
105
|
-
run bash "$SCRIPT" "$FIXTURE_DIR"
|
|
106
|
-
echo "$output" | grep -q '^BUCKET project-claude-md '
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
@test "measure-context-budget: output contains memory bucket row" {
|
|
110
|
-
run bash "$SCRIPT" "$FIXTURE_DIR"
|
|
111
|
-
echo "$output" | grep -q '^BUCKET memory '
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
# ── Framework-injected sentinel (ADR-026 ungrounded-field rule) ─────────────
|
|
115
|
-
|
|
116
|
-
@test "measure-context-budget: framework-injected bucket emits not-measured sentinel" {
|
|
117
|
-
run bash "$SCRIPT" "$FIXTURE_DIR"
|
|
118
|
-
[ "$status" -eq 0 ]
|
|
119
|
-
echo "$output" | grep -q '^BUCKET framework-injected not-measured '
|
|
120
|
-
echo "$output" | grep -q 'reason=framework-injected-no-on-disk-source'
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
# ── Surface-absent sentinels (ADR-026 ungrounded-field rule) ────────────────
|
|
124
|
-
# Empty fixture has no docs/decisions/, docs/problems/, docs/jtbd/, etc.
|
|
125
|
-
|
|
126
|
-
@test "measure-context-budget: empty fixture marks decisions not-measured" {
|
|
127
|
-
run bash "$SCRIPT" "$FIXTURE_DIR"
|
|
128
|
-
echo "$output" | grep -q '^BUCKET decisions not-measured '
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
@test "measure-context-budget: empty fixture marks problems not-measured" {
|
|
132
|
-
run bash "$SCRIPT" "$FIXTURE_DIR"
|
|
133
|
-
echo "$output" | grep -q '^BUCKET problems not-measured '
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
@test "measure-context-budget: empty fixture marks jtbd not-measured" {
|
|
137
|
-
run bash "$SCRIPT" "$FIXTURE_DIR"
|
|
138
|
-
echo "$output" | grep -q '^BUCKET jtbd not-measured '
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
@test "measure-context-budget: empty fixture marks briefing not-measured" {
|
|
142
|
-
run bash "$SCRIPT" "$FIXTURE_DIR"
|
|
143
|
-
echo "$output" | grep -q '^BUCKET briefing not-measured '
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
@test "measure-context-budget: empty fixture marks project-claude-md not-measured" {
|
|
147
|
-
run bash "$SCRIPT" "$FIXTURE_DIR"
|
|
148
|
-
echo "$output" | grep -q '^BUCKET project-claude-md not-measured '
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
# ── Surface-present byte counts ─────────────────────────────────────────────
|
|
152
|
-
|
|
153
|
-
@test "measure-context-budget: populated decisions bucket reports byte count" {
|
|
154
|
-
mkdir -p "$FIXTURE_DIR/docs/decisions"
|
|
155
|
-
printf '# ADR-001\nbody body body\n' > "$FIXTURE_DIR/docs/decisions/001-foo.proposed.md"
|
|
156
|
-
run bash "$SCRIPT" "$FIXTURE_DIR"
|
|
157
|
-
[ "$status" -eq 0 ]
|
|
158
|
-
echo "$output" | grep -qE '^BUCKET decisions bytes=[0-9]+$'
|
|
159
|
-
# Sanity: byte count is non-zero
|
|
160
|
-
decisions_line=$(echo "$output" | grep '^BUCKET decisions ')
|
|
161
|
-
bytes_value="${decisions_line##*bytes=}"
|
|
162
|
-
[ "$bytes_value" -gt 0 ]
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
@test "measure-context-budget: populated problems bucket reports byte count" {
|
|
166
|
-
mkdir -p "$FIXTURE_DIR/docs/problems"
|
|
167
|
-
printf '# Problem 001\nbody\n' > "$FIXTURE_DIR/docs/problems/001-foo.open.md"
|
|
168
|
-
run bash "$SCRIPT" "$FIXTURE_DIR"
|
|
169
|
-
echo "$output" | grep -qE '^BUCKET problems bytes=[0-9]+$'
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
# ── Dual-tolerant per-state subdir enumeration (P182 / RFC-002 T4 / ADR-031) ─
|
|
173
|
-
# RFC-002 T5 migrated problem tickets from the flat layout
|
|
174
|
-
# (docs/problems/<NNN>-*.<state>.md) to per-state subdirs
|
|
175
|
-
# (docs/problems/<state>/<NNN>-*.md). The flat-only glob misses the subdir
|
|
176
|
-
# tickets and under-counts the bucket ~99% post-migration (P182). The fix
|
|
177
|
-
# walks BOTH layouts and dedups on ticket ID — the per-state subdir copy
|
|
178
|
-
# wins on collision per ADR-031 §"Authoritative state signal" — mirroring
|
|
179
|
-
# the proven reconcile-readme.sh pattern.
|
|
180
|
-
|
|
181
|
-
@test "measure-context-budget: per-state subdir problem tickets are counted" {
|
|
182
|
-
mkdir -p "$FIXTURE_DIR/docs/problems/open" "$FIXTURE_DIR/docs/problems/known-error"
|
|
183
|
-
printf '# Problem 100\nbody body body\n' > "$FIXTURE_DIR/docs/problems/open/100-foo.md"
|
|
184
|
-
printf '# Problem 101\nbody body\n' > "$FIXTURE_DIR/docs/problems/known-error/101-bar.md"
|
|
185
|
-
run bash "$SCRIPT" "$FIXTURE_DIR"
|
|
186
|
-
[ "$status" -eq 0 ]
|
|
187
|
-
echo "$output" | grep -qE '^BUCKET problems bytes=[0-9]+$'
|
|
188
|
-
problems_line=$(echo "$output" | grep '^BUCKET problems ')
|
|
189
|
-
bytes_value="${problems_line##*bytes=}"
|
|
190
|
-
[ "$bytes_value" -gt 0 ]
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
@test "measure-context-budget: problems bucket sums flat + per-state subdir tickets" {
|
|
194
|
-
mkdir -p "$FIXTURE_DIR/docs/problems/open" "$FIXTURE_DIR/docs/problems/verifying"
|
|
195
|
-
# Flat top-level (README + a pre-migration flat ticket) and per-state
|
|
196
|
-
# subdir tickets must all contribute to the bucket total.
|
|
197
|
-
printf '# Problems index\nrow\n' > "$FIXTURE_DIR/docs/problems/README.md"
|
|
198
|
-
printf '# Problem 050 legacy flat\nbody\n' > "$FIXTURE_DIR/docs/problems/050-legacy.open.md"
|
|
199
|
-
printf '# Problem 100\nbody body\n' > "$FIXTURE_DIR/docs/problems/open/100-foo.md"
|
|
200
|
-
printf '# Problem 101\nbody body body body\n' > "$FIXTURE_DIR/docs/problems/verifying/101-bar.md"
|
|
201
|
-
expected=0
|
|
202
|
-
for f in "$FIXTURE_DIR/docs/problems/README.md" \
|
|
203
|
-
"$FIXTURE_DIR/docs/problems/050-legacy.open.md" \
|
|
204
|
-
"$FIXTURE_DIR/docs/problems/open/100-foo.md" \
|
|
205
|
-
"$FIXTURE_DIR/docs/problems/verifying/101-bar.md"; do
|
|
206
|
-
b=$(wc -c < "$f" | tr -d ' ')
|
|
207
|
-
expected=$(( expected + b ))
|
|
208
|
-
done
|
|
209
|
-
run bash "$SCRIPT" "$FIXTURE_DIR"
|
|
210
|
-
[ "$status" -eq 0 ]
|
|
211
|
-
problems_line=$(echo "$output" | grep '^BUCKET problems ')
|
|
212
|
-
bytes_value="${problems_line##*bytes=}"
|
|
213
|
-
[ "$bytes_value" -eq "$expected" ]
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
@test "measure-context-budget: same ticket in flat + per-state subdir counted once (per-state wins)" {
|
|
217
|
-
# Mid-migration race: the same ticket ID exists as a flat file
|
|
218
|
-
# (200-dup.open.md) AND a per-state subdir file (open/200-dup.md) with a
|
|
219
|
-
# DIFFERENT byte size. ID-keyed dedup must count it once; the per-state
|
|
220
|
-
# subdir copy wins (ADR-031). Asserting the total equals the subdir file's
|
|
221
|
-
# size alone proves both: counted-once (not flat+subdir) and per-state-wins
|
|
222
|
-
# (subdir size, not flat size).
|
|
223
|
-
mkdir -p "$FIXTURE_DIR/docs/problems/open"
|
|
224
|
-
printf 'flat\n' > "$FIXTURE_DIR/docs/problems/200-dup.open.md"
|
|
225
|
-
printf 'per-state subdir copy is longer\n' > "$FIXTURE_DIR/docs/problems/open/200-dup.md"
|
|
226
|
-
subdir_bytes=$(wc -c < "$FIXTURE_DIR/docs/problems/open/200-dup.md" | tr -d ' ')
|
|
227
|
-
run bash "$SCRIPT" "$FIXTURE_DIR"
|
|
228
|
-
[ "$status" -eq 0 ]
|
|
229
|
-
problems_line=$(echo "$output" | grep '^BUCKET problems ')
|
|
230
|
-
bytes_value="${problems_line##*bytes=}"
|
|
231
|
-
[ "$bytes_value" -eq "$subdir_bytes" ]
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
@test "measure-context-budget: populated briefing bucket reports byte count" {
|
|
235
|
-
mkdir -p "$FIXTURE_DIR/docs/briefing"
|
|
236
|
-
printf '# Topic\nentry\n' > "$FIXTURE_DIR/docs/briefing/foo.md"
|
|
237
|
-
run bash "$SCRIPT" "$FIXTURE_DIR"
|
|
238
|
-
echo "$output" | grep -qE '^BUCKET briefing bytes=[0-9]+$'
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
@test "measure-context-budget: project CLAUDE.md reports byte count" {
|
|
242
|
-
printf '# Project\ninstructions\n' > "$FIXTURE_DIR/CLAUDE.md"
|
|
243
|
-
run bash "$SCRIPT" "$FIXTURE_DIR"
|
|
244
|
-
echo "$output" | grep -qE '^BUCKET project-claude-md bytes=[0-9]+$'
|
|
245
|
-
claude_md_line=$(echo "$output" | grep '^BUCKET project-claude-md ')
|
|
246
|
-
bytes_value="${claude_md_line##*bytes=}"
|
|
247
|
-
[ "$bytes_value" -gt 0 ]
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
# ── Threshold ────────────────────────────────────────────────────────────────
|
|
251
|
-
|
|
252
|
-
@test "measure-context-budget: trailing THRESHOLD row emitted" {
|
|
253
|
-
run bash "$SCRIPT" "$FIXTURE_DIR"
|
|
254
|
-
[ "$status" -eq 0 ]
|
|
255
|
-
echo "$output" | grep -qE '^THRESHOLD bytes=[0-9]+$'
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
@test "measure-context-budget: default threshold is 10240" {
|
|
259
|
-
unset CONTEXT_BUDGET_MAX_BYTES
|
|
260
|
-
run bash "$SCRIPT" "$FIXTURE_DIR"
|
|
261
|
-
echo "$output" | grep -q '^THRESHOLD bytes=10240$'
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
@test "measure-context-budget: CONTEXT_BUDGET_MAX_BYTES override respected" {
|
|
265
|
-
CONTEXT_BUDGET_MAX_BYTES=42 run bash "$SCRIPT" "$FIXTURE_DIR"
|
|
266
|
-
[ "$status" -eq 0 ]
|
|
267
|
-
echo "$output" | grep -q '^THRESHOLD bytes=42$'
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
# ── Per-row byte budget (ADR-038 progressive-disclosure ≤150 bytes/row) ─────
|
|
271
|
-
|
|
272
|
-
@test "measure-context-budget: every row is at most 150 bytes" {
|
|
273
|
-
run bash "$SCRIPT" "$FIXTURE_DIR"
|
|
274
|
-
[ "$status" -eq 0 ]
|
|
275
|
-
while IFS= read -r line; do
|
|
276
|
-
[ "${#line}" -le 150 ]
|
|
277
|
-
done <<< "$output"
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
# ── Read-only contract — script does not mutate the project tree ────────────
|
|
281
|
-
|
|
282
|
-
@test "measure-context-budget: read-only — fixture tree unchanged after run" {
|
|
283
|
-
mkdir -p "$FIXTURE_DIR/docs/decisions"
|
|
284
|
-
printf '# ADR-001\nbody\n' > "$FIXTURE_DIR/docs/decisions/001-foo.proposed.md"
|
|
285
|
-
pre_hash=$(find "$FIXTURE_DIR" -type f -exec cksum {} \; 2>/dev/null | sort | cksum | awk '{print $1}')
|
|
286
|
-
run bash "$SCRIPT" "$FIXTURE_DIR"
|
|
287
|
-
[ "$status" -eq 0 ]
|
|
288
|
-
post_hash=$(find "$FIXTURE_DIR" -type f -exec cksum {} \; 2>/dev/null | sort | cksum | awk '{print $1}')
|
|
289
|
-
[ "$pre_hash" = "$post_hash" ]
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
# ── CLAUDE_PROJECT_DIR fallback when no arg ─────────────────────────────────
|
|
293
|
-
|
|
294
|
-
@test "measure-context-budget: CLAUDE_PROJECT_DIR env var respected when no arg" {
|
|
295
|
-
CLAUDE_PROJECT_DIR="$FIXTURE_DIR" run bash "$SCRIPT"
|
|
296
|
-
[ "$status" -eq 0 ]
|
|
297
|
-
echo "$output" | grep -q '^BUCKET hooks '
|
|
298
|
-
}
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bats
|
|
2
|
-
|
|
3
|
-
# P101 / ADR-043: new skill /wr-retrospective:analyze-context (deep layer)
|
|
4
|
-
# at packages/retrospective/skills/analyze-context/SKILL.md. Doc-lint
|
|
5
|
-
# structural test (Permitted Exception per ADR-005). Asserts the SKILL.md
|
|
6
|
-
# carries: the canonical name, citations of ADR-043 / ADR-026 / ADR-014 /
|
|
7
|
-
# ADR-013, references to the cheap-layer measurement primitive, the report
|
|
8
|
-
# path convention, the HTML-comment-trailer snapshot schema, the AFK
|
|
9
|
-
# never-auto-fires discipline, the ADR-014 commit-message convention, and
|
|
10
|
-
# the ADR-026 forbidden-qualitative-phrase ban.
|
|
11
|
-
|
|
12
|
-
setup() {
|
|
13
|
-
REPO_ROOT="$(cd "$(dirname "$BATS_TEST_FILENAME")/../../../../.." && pwd)"
|
|
14
|
-
SKILL_MD="$REPO_ROOT/packages/retrospective/skills/analyze-context/SKILL.md"
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
@test "analyze-context: SKILL.md exists at expected path" {
|
|
18
|
-
[ -f "$SKILL_MD" ]
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
@test "analyze-context: frontmatter declares the wr-retrospective:analyze-context name" {
|
|
22
|
-
run grep -F 'name: wr-retrospective:analyze-context' "$SKILL_MD"
|
|
23
|
-
[ "$status" -eq 0 ]
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
@test "analyze-context: cites ADR-043 as the source decision" {
|
|
27
|
-
run grep -F 'ADR-043' "$SKILL_MD"
|
|
28
|
-
[ "$status" -eq 0 ]
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
@test "analyze-context: cites ADR-026 (Agent output grounding)" {
|
|
32
|
-
run grep -F 'ADR-026' "$SKILL_MD"
|
|
33
|
-
[ "$status" -eq 0 ]
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
@test "analyze-context: cites ADR-014 (Governance skills commit own work)" {
|
|
37
|
-
run grep -F 'ADR-014' "$SKILL_MD"
|
|
38
|
-
[ "$status" -eq 0 ]
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
@test "analyze-context: cites ADR-013 Rule 6 (AFK fallback)" {
|
|
42
|
-
run grep -F 'ADR-013 Rule 6' "$SKILL_MD"
|
|
43
|
-
[ "$status" -eq 0 ]
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
@test "analyze-context: references the cheap-layer measurement primitive" {
|
|
47
|
-
run grep -F 'packages/retrospective/scripts/measure-context-budget.sh' "$SKILL_MD"
|
|
48
|
-
[ "$status" -eq 0 ]
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
@test "analyze-context: declares the report path convention docs/retros/<date>-context-analysis.md" {
|
|
52
|
-
run grep -F 'docs/retros/' "$SKILL_MD"
|
|
53
|
-
[ "$status" -eq 0 ]
|
|
54
|
-
# `--` separates flags from pattern; `-context-analysis.md` would otherwise
|
|
55
|
-
# parse as an option flag.
|
|
56
|
-
run grep -F -- '-context-analysis.md' "$SKILL_MD"
|
|
57
|
-
[ "$status" -eq 0 ]
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
@test "analyze-context: HTML-comment trailer schema present (context-snapshot)" {
|
|
61
|
-
run grep -F 'context-snapshot:' "$SKILL_MD"
|
|
62
|
-
[ "$status" -eq 0 ]
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
@test "analyze-context: trailer schema cites measurement-method and measured-at fields" {
|
|
66
|
-
run grep -F 'measurement-method' "$SKILL_MD"
|
|
67
|
-
[ "$status" -eq 0 ]
|
|
68
|
-
run grep -F 'measured-at' "$SKILL_MD"
|
|
69
|
-
[ "$status" -eq 0 ]
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
@test "analyze-context: auto-fires from run-retro Step 2c per ADR-043 Amendment 2026-06-08 (P295)" {
|
|
73
|
-
# P295 settlement: deep layer auto-fires from cheap-layer Step 2c when the
|
|
74
|
-
# combined trigger holds. Replaces the prior 'never auto-invoked' clause.
|
|
75
|
-
run grep -iF 'auto-fires from run-retro Step 2c' "$SKILL_MD"
|
|
76
|
-
[ "$status" -eq 0 ]
|
|
77
|
-
run grep -F 'Amendment 2026-06-08' "$SKILL_MD"
|
|
78
|
-
[ "$status" -eq 0 ]
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
@test "analyze-context: SKILL.md no longer asserts 'never auto-invoked' / 'never auto-fires' (P295 supersedes)" {
|
|
82
|
-
# The supersession discipline: the post-P295 SKILL.md MUST NOT carry the
|
|
83
|
-
# contradicting 'never auto-fires' / 'never auto-invoked' prose, or future
|
|
84
|
-
# agents will read it as still-authoritative and revert the wiring.
|
|
85
|
-
run grep -F 'never auto-invoked' "$SKILL_MD"
|
|
86
|
-
[ "$status" -ne 0 ]
|
|
87
|
-
run grep -F 'Never auto-fires' "$SKILL_MD"
|
|
88
|
-
[ "$status" -ne 0 ]
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
@test "analyze-context: cites the combined-trigger threshold values (14 days + 20%)" {
|
|
92
|
-
# ADR-043 Amendment 2026-06-08 chosen initial thresholds per ADR-026
|
|
93
|
-
# grounding rule (concrete numerics + no-prior-data sentinel).
|
|
94
|
-
run grep -F '14 days' "$SKILL_MD"
|
|
95
|
-
[ "$status" -eq 0 ]
|
|
96
|
-
run grep -F '20%' "$SKILL_MD"
|
|
97
|
-
[ "$status" -eq 0 ]
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
@test "analyze-context: cites the once-per-day guard via TODAY snapshot file presence" {
|
|
101
|
-
run grep -F 'once-per-day guard' "$SKILL_MD"
|
|
102
|
-
[ "$status" -eq 0 ]
|
|
103
|
-
run grep -F '<TODAY>-context-analysis.md' "$SKILL_MD"
|
|
104
|
-
[ "$status" -eq 0 ]
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
@test "analyze-context: ADR-014 commit-message convention declared (docs(retros): context analysis)" {
|
|
108
|
-
run grep -F 'docs(retros): context analysis' "$SKILL_MD"
|
|
109
|
-
[ "$status" -eq 0 ]
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
@test "analyze-context: bans qualitative-only phrases per ADR-026" {
|
|
113
|
-
run grep -F 'load is negligible' "$SKILL_MD"
|
|
114
|
-
[ "$status" -eq 0 ]
|
|
115
|
-
run grep -F 'microseconds only' "$SKILL_MD"
|
|
116
|
-
[ "$status" -eq 0 ]
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
@test "analyze-context: requires comparable-prior citation in suggestions" {
|
|
120
|
-
run grep -F 'comparable prior' "$SKILL_MD"
|
|
121
|
-
[ "$status" -eq 0 ]
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
@test "analyze-context: routes to /wr-risk-scorer:assess-release fallback when subagent unavailable" {
|
|
125
|
-
run grep -F '/wr-risk-scorer:assess-release' "$SKILL_MD"
|
|
126
|
-
[ "$status" -eq 0 ]
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
@test "analyze-context: documents per-plugin decomposition step" {
|
|
130
|
-
run grep -F 'Per-Plugin Decomposition' "$SKILL_MD"
|
|
131
|
-
[ "$status" -eq 0 ]
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
@test "analyze-context: documents policy-breach detection step" {
|
|
135
|
-
run grep -F 'Policy Breaches' "$SKILL_MD"
|
|
136
|
-
[ "$status" -eq 0 ]
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
@test "analyze-context: cites P101 (driver ticket) and P091 (parent meta)" {
|
|
140
|
-
run grep -F 'P101' "$SKILL_MD"
|
|
141
|
-
[ "$status" -eq 0 ]
|
|
142
|
-
}
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bats
|
|
2
|
-
|
|
3
|
-
# Contract-level structural tests for /wr-retrospective:migrate-briefing.
|
|
4
|
-
# Permitted Exception per ADR-005 — structural SKILL.md content checks,
|
|
5
|
-
# mirrored on scaffold-intake-contract.bats. Behavioural coverage lives
|
|
6
|
-
# in migrate-briefing-fixture.bats per ADR-052.
|
|
7
|
-
#
|
|
8
|
-
# Closes P204 verification surface.
|
|
9
|
-
|
|
10
|
-
setup() {
|
|
11
|
-
REPO_ROOT="$(cd "$(dirname "$BATS_TEST_FILENAME")/../../../../.." && pwd)"
|
|
12
|
-
SKILL_DIR="$REPO_ROOT/packages/retrospective/skills/migrate-briefing"
|
|
13
|
-
SKILL_MD="$SKILL_DIR/SKILL.md"
|
|
14
|
-
REFERENCE_MD="$SKILL_DIR/REFERENCE.md"
|
|
15
|
-
SCRIPT="$REPO_ROOT/packages/retrospective/scripts/migrate-briefing.sh"
|
|
16
|
-
SHIM="$REPO_ROOT/packages/retrospective/bin/wr-retrospective-migrate-briefing"
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
@test "migrate-briefing: SKILL.md exists" {
|
|
20
|
-
[ -f "$SKILL_MD" ]
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
@test "migrate-briefing: REFERENCE.md exists (ADR-038 split)" {
|
|
24
|
-
[ -f "$REFERENCE_MD" ]
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
@test "migrate-briefing: implementation script exists and is executable" {
|
|
28
|
-
[ -x "$SCRIPT" ]
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
@test "migrate-briefing: bin shim exists and is executable" {
|
|
32
|
-
[ -x "$SHIM" ]
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
@test "migrate-briefing: SKILL.md frontmatter declares the skill name" {
|
|
36
|
-
run grep -F 'name: wr-retrospective:migrate-briefing' "$SKILL_MD"
|
|
37
|
-
[ "$status" -eq 0 ]
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
@test "migrate-briefing: SKILL.md cites ADR-040 (target tree shape — load-bearing per architect)" {
|
|
41
|
-
run grep -F 'ADR-040' "$SKILL_MD"
|
|
42
|
-
[ "$status" -eq 0 ]
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
@test "migrate-briefing: SKILL.md cites ADR-032 foreground-synchronous pattern" {
|
|
46
|
-
run grep -F 'ADR-032' "$SKILL_MD"
|
|
47
|
-
[ "$status" -eq 0 ]
|
|
48
|
-
run grep -iE 'foreground.synchronous' "$SKILL_MD"
|
|
49
|
-
[ "$status" -eq 0 ]
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
@test "migrate-briefing: SKILL.md cites ADR-014 self-commit pattern" {
|
|
53
|
-
run grep -F 'ADR-014' "$SKILL_MD"
|
|
54
|
-
[ "$status" -eq 0 ]
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
@test "migrate-briefing: SKILL.md cites ADR-038 progressive-disclosure pattern" {
|
|
58
|
-
run grep -F 'ADR-038' "$SKILL_MD"
|
|
59
|
-
[ "$status" -eq 0 ]
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
@test "migrate-briefing: SKILL.md cites ADR-052 behavioural-tests-default" {
|
|
63
|
-
run grep -F 'ADR-052' "$SKILL_MD"
|
|
64
|
-
[ "$status" -eq 0 ]
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
@test "migrate-briefing: SKILL.md cites ADR-049 (no repo-relative paths — recurring class)" {
|
|
68
|
-
run grep -F 'ADR-049' "$SKILL_MD"
|
|
69
|
-
[ "$status" -eq 0 ]
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
@test "migrate-briefing: SKILL.md declares two-direction idempotency clause" {
|
|
73
|
-
# Both no-op directions named: tree already present + no legacy file.
|
|
74
|
-
run grep -iE 'tree.already.present|already.migrated' "$SKILL_MD"
|
|
75
|
-
[ "$status" -eq 0 ]
|
|
76
|
-
run grep -iE 'no.legacy.file|legacy.*does.not.exist|missing or empty' "$SKILL_MD"
|
|
77
|
-
[ "$status" -eq 0 ]
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
@test "migrate-briefing: SKILL.md carries Rule 6 audit section (ADR-013)" {
|
|
81
|
-
run grep -F 'Rule 6' "$SKILL_MD"
|
|
82
|
-
[ "$status" -eq 0 ]
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
@test "migrate-briefing: SKILL.md cross-references P204 (the closing ticket)" {
|
|
86
|
-
run grep -F 'P204' "$SKILL_MD"
|
|
87
|
-
[ "$status" -eq 0 ]
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
@test "migrate-briefing: SKILL.md does NOT carry repo-relative packages/ paths (P151/P153/P219/P317 class)" {
|
|
91
|
-
# No bash invocations that hardcode a packages/.../scripts/ path —
|
|
92
|
-
# the script ships via ADR-049 PATH shim.
|
|
93
|
-
run grep -E 'packages/[a-z]+/scripts/migrate-briefing\.sh' "$SKILL_MD"
|
|
94
|
-
[ "$status" -ne 0 ]
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
@test "migrate-briefing: REFERENCE.md documents the heading-extraction algorithm" {
|
|
98
|
-
run grep -iE 'heading.extraction|slug.derivation|collision' "$REFERENCE_MD"
|
|
99
|
-
[ "$status" -eq 0 ]
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
@test "migrate-briefing: REFERENCE.md documents code-fence-aware parsing" {
|
|
103
|
-
run grep -iE 'fence|code.fence|in_fence' "$REFERENCE_MD"
|
|
104
|
-
[ "$status" -eq 0 ]
|
|
105
|
-
}
|