@windyroad/retrospective 0.18.2 → 0.19.0-preview.339
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/package.json
CHANGED
|
@@ -331,12 +331,12 @@ The script's threshold defaults to `5120` bytes (the upper bound of ADR-040's Ti
|
|
|
331
331
|
- If a coherent sub-topic boundary exists (a sub-section that's grown big enough to stand alone, ≥1 KB; e.g. a worked example in a topic that's grown to its own sub-section): **split-by-subtopic** — extract to `docs/briefing/<sub-topic>.md`, update README Topic Index.
|
|
332
332
|
- Else: **split-by-date** — this is the **safe default** when no sub-topic boundary is obvious. Older entries archive cleanly without semantic judgement (mtime-sort + median-age threshold), so the action is mechanical and AFK-safe. Archive oldest entries to `docs/briefing/<topic>-archive.md`. Do NOT pick split-by-subtopic with a weak boundary just because it appears first in the heuristic — split-by-date is preferred when the boundary is unclear because it has zero false-split risk.
|
|
333
333
|
|
|
334
|
-
**Branch B — file has only OVER line (ratio between 1.0× and 2.0× ceiling)**: the
|
|
334
|
+
**Branch B — file has only OVER line (ratio between 1.0× and 2.0× ceiling)**: rotation is required. Being OVER threshold IS the evidence; "wait for more signal to accumulate" is the fictional-defer anti-pattern P247 closes (sibling-class to P246's calendar-trigger anti-pattern at the cohort-graduation surface). Per the P246 principle (evidence-based, not time-based — user direction verbatim 2026-05-17: *"The 14 files are over the limit, but you are deferring splitting them. Why? When are you hoping they will get dealt with?"*), the agent picks the best-fit rotation shape from the three concrete options below; fall-through is **split-by-date** as the safe default (zero false-split risk per Branch A precedent), NOT "leave-as-is".
|
|
335
335
|
|
|
336
336
|
- If a coherent sub-topic boundary exists (≥1 KB sub-section): **split-by-subtopic** — extract to `docs/briefing/<sub-topic>.md`, update README Topic Index.
|
|
337
337
|
- Else if the file has clear date-stratified entries (HTML-comment `first-written` fields per Step 1.5) AND ≥30% of bytes are entries older than the median age: **split-by-date** — archive oldest entries to `docs/briefing/<topic>-archive.md`.
|
|
338
|
-
- Else if Step 1.5 surfaced ≥3 noise-classified entries in this file this retro: **trim-noise** —
|
|
339
|
-
- Else: **
|
|
338
|
+
- Else if Step 1.5 surfaced ≥3 noise-classified entries in this file this retro: **trim-noise** — apply the Step 1.5 noise-trim decisions inline; if the trim alone brings the file below threshold, record `trim-noise` as the rotation action with the per-entry deltas in the Step 5 summary. If the file is still OVER after trim, fall through to split-by-date in the same retro turn — do NOT defer.
|
|
339
|
+
- Else (no subtopic boundary AND no date stratification AND no ≥3 noise entries): **split-by-date (safe default)** — mtime-sort entries, archive the oldest half to `docs/briefing/<topic>-archive.md`. This is the same safe-default Branch A uses when its boundary is unclear; the fall-through here aligns Branch B with Branch A's evidence-based rotation discipline. Per ADR-013 Rule 5 (policy-authorised silent proceed) + ADR-044 framework-mediated surface ("Briefing add / remove / rotate" line 77), the rotation is silent agent judgement — no per-file `AskUserQuestion`.
|
|
340
340
|
|
|
341
341
|
Apply the chosen rotation; record the choice + rationale + per-file delta (`bytes before` → `bytes after`) in the Step 5 summary `Topic File Rotation` section. User reads the summary and corrects via authentic-correction (ADR-044 category 6) if the rotation was wrong (rotations are reversible — `git mv` the archive sibling back; restore deletions from git).
|
|
342
342
|
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
#!/usr/bin/env bats
|
|
2
|
+
#
|
|
3
|
+
# P247: run-retro SKILL.md Step 3 Tier 3 Branch B MUST encode the
|
|
4
|
+
# evidence-based rotation contract — "leave-as-is" is eliminated; the
|
|
5
|
+
# fall-through when none of the three concrete triggers (subtopic /
|
|
6
|
+
# date / ≥3 noise entries) fire is **split-by-date as the safe default**,
|
|
7
|
+
# mirroring Branch A's existing precedent.
|
|
8
|
+
#
|
|
9
|
+
# This file mirrors the architecture established for P148's Stage 1
|
|
10
|
+
# fallback-gating clause: behavioural assertions exercise the
|
|
11
|
+
# enforcement layer (check-briefing-budgets.sh) for the OVER /
|
|
12
|
+
# MUST_SPLIT signal shape that drives Branch B input, plus narrow
|
|
13
|
+
# structural backstops linking SKILL.md prose (canonical human source)
|
|
14
|
+
# to the enforcement layer + driver-ticket evidence trail.
|
|
15
|
+
#
|
|
16
|
+
# Architect verdict (2026-05-18, P247): the rotation decision itself
|
|
17
|
+
# is silent agent judgement per ADR-044 framework-mediated surface
|
|
18
|
+
# "Briefing add / remove / rotate" — there is no script to behaviourally
|
|
19
|
+
# exercise the rotation. The script-side behavioural coverage for the
|
|
20
|
+
# Branch B INPUT signal (OVER without MUST_SPLIT) lives in
|
|
21
|
+
# `packages/retrospective/scripts/test/check-briefing-budgets.bats`;
|
|
22
|
+
# this file is the SKILL-prose backstop that confirms the prose names
|
|
23
|
+
# the evidence-based contract terms and the driver ticket.
|
|
24
|
+
#
|
|
25
|
+
# # @adr ADR-037 permitted exception — narrowest justifiable scope.
|
|
26
|
+
# # @adr ADR-044 framework-mediated surface boundary (silent agent rotation).
|
|
27
|
+
# # @adr ADR-061 evidence-based-not-time-based principle (parent class).
|
|
28
|
+
# # @adr ADR-013 Rule 5 (policy-authorised silent proceed).
|
|
29
|
+
# # @adr ADR-052 behavioural-tests-default (structural backstops permitted
|
|
30
|
+
# # for SKILL-prose-to-enforcement-layer linkage per P081).
|
|
31
|
+
# # @ticket P247 — Branch B fictional-defer (driver).
|
|
32
|
+
# # @ticket P246 — sibling-class at cohort-graduation surface (mirror precedent).
|
|
33
|
+
# # @ticket P145 — predecessor at this surface (MUST_SPLIT subset already
|
|
34
|
+
# # evidence-based; P247 generalises to OVER subset).
|
|
35
|
+
# # @ticket P081 — behavioural-tests-preferred direction.
|
|
36
|
+
|
|
37
|
+
setup() {
|
|
38
|
+
REPO_ROOT="$(cd "$(dirname "$BATS_TEST_FILENAME")/../../../../.." && pwd)"
|
|
39
|
+
SKILL_MD="$REPO_ROOT/packages/retrospective/skills/run-retro/SKILL.md"
|
|
40
|
+
SCRIPT="$REPO_ROOT/packages/retrospective/scripts/check-briefing-budgets.sh"
|
|
41
|
+
FIXTURE_DIR="$(mktemp -d)"
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
teardown() {
|
|
45
|
+
rm -rf "$FIXTURE_DIR"
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
# Helper: write a markdown file with N bytes of body content.
|
|
49
|
+
write_briefing_entry() {
|
|
50
|
+
local path="$1"
|
|
51
|
+
local target_bytes="$2"
|
|
52
|
+
: > "$path"
|
|
53
|
+
printf '# Topic\n\n' >> "$path"
|
|
54
|
+
local header_size
|
|
55
|
+
header_size=$(wc -c < "$path" | tr -d ' ')
|
|
56
|
+
local body_target=$(( target_bytes - header_size ))
|
|
57
|
+
if [ "$body_target" -gt 0 ]; then
|
|
58
|
+
local line="- entry text padded out to a known length for byte-budget testing. "
|
|
59
|
+
local line_size=${#line}
|
|
60
|
+
line+=$'\n'
|
|
61
|
+
local line_count=$(( (body_target + line_size) / (line_size + 1) ))
|
|
62
|
+
local i=0
|
|
63
|
+
while [ "$i" -lt "$line_count" ]; do
|
|
64
|
+
printf '%s' "$line" >> "$path"
|
|
65
|
+
i=$(( i + 1 ))
|
|
66
|
+
done
|
|
67
|
+
fi
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
# ── Behavioural: Branch B INPUT signal shape ────────────────────────────────
|
|
71
|
+
#
|
|
72
|
+
# Branch B is defined as "file has only OVER line (ratio between 1.0× and
|
|
73
|
+
# 2.0× ceiling)". The check-briefing-budgets.sh script is the enforcement
|
|
74
|
+
# layer that produces this signal. These assertions confirm the signal
|
|
75
|
+
# shape the SKILL contract reads — they exercise the script (not the
|
|
76
|
+
# agent's rotation choice), giving Branch B its input definition.
|
|
77
|
+
|
|
78
|
+
@test "Branch B input: file at 1.5x ratio emits OVER without MUST_SPLIT (Branch B selector)" {
|
|
79
|
+
# 1.5x of default 5120 ceiling = 7680 bytes — the canonical Branch B input.
|
|
80
|
+
mkdir -p "$FIXTURE_DIR/briefing"
|
|
81
|
+
write_briefing_entry "$FIXTURE_DIR/briefing/branch-b-canonical.md" 7680
|
|
82
|
+
run "$SCRIPT" "$FIXTURE_DIR/briefing"
|
|
83
|
+
[ "$status" -eq 0 ]
|
|
84
|
+
echo "$output" | grep -E "^OVER branch-b-canonical.md bytes=[0-9]+ threshold=5120"
|
|
85
|
+
! echo "$output" | grep -q "^MUST_SPLIT branch-b-canonical.md"
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
@test "Branch B input: file at 1.0x exactly emits OVER without MUST_SPLIT (Branch B lower edge)" {
|
|
89
|
+
mkdir -p "$FIXTURE_DIR/briefing"
|
|
90
|
+
printf '%.0s.' $(seq 1 5120) > "$FIXTURE_DIR/briefing/branch-b-lower-edge.md"
|
|
91
|
+
run "$SCRIPT" "$FIXTURE_DIR/briefing"
|
|
92
|
+
[ "$status" -eq 0 ]
|
|
93
|
+
echo "$output" | grep -E "^OVER branch-b-lower-edge.md bytes=5120 threshold=5120"
|
|
94
|
+
! echo "$output" | grep -q "^MUST_SPLIT branch-b-lower-edge.md"
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
@test "Branch B input: file just under 2.0x (e.g. 1.96x) emits OVER without MUST_SPLIT (P247 evidence — hooks-and-gates-archive.md at 1.96x was deferred)" {
|
|
98
|
+
# 1.96x of 5120 = 10035 bytes — the upper edge of Branch B, exactly the
|
|
99
|
+
# case the 2026-05-17 session-4 wrap retro hit and deferred via the
|
|
100
|
+
# now-eliminated "leave-as-is" branch.
|
|
101
|
+
mkdir -p "$FIXTURE_DIR/briefing"
|
|
102
|
+
printf '%.0s.' $(seq 1 10035) > "$FIXTURE_DIR/briefing/upper-edge.md"
|
|
103
|
+
run "$SCRIPT" "$FIXTURE_DIR/briefing"
|
|
104
|
+
[ "$status" -eq 0 ]
|
|
105
|
+
echo "$output" | grep -E "^OVER upper-edge.md bytes=10035 threshold=5120"
|
|
106
|
+
! echo "$output" | grep -q "^MUST_SPLIT upper-edge.md"
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
@test "Branch B input: file UNDER threshold emits NEITHER signal (no Branch B action)" {
|
|
110
|
+
# The pre-existing skip path: file below threshold = no rotation pass
|
|
111
|
+
# entry. The SKILL contract's "Empty stdout means no files are over
|
|
112
|
+
# budget — skip the rest of this pass" precedent is preserved.
|
|
113
|
+
mkdir -p "$FIXTURE_DIR/briefing"
|
|
114
|
+
write_briefing_entry "$FIXTURE_DIR/briefing/within-budget.md" 3000
|
|
115
|
+
run "$SCRIPT" "$FIXTURE_DIR/briefing"
|
|
116
|
+
[ "$status" -eq 0 ]
|
|
117
|
+
! echo "$output" | grep -q "within-budget.md"
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
@test "Branch B / Branch A boundary: file at exactly 2.0x emits BOTH OVER and MUST_SPLIT (Branch A selector)" {
|
|
121
|
+
# The contract boundary: 2.0x and above is Branch A (rotation required,
|
|
122
|
+
# no defer options eligible). 1.0x-2.0x is Branch B. The script-side
|
|
123
|
+
# MUST_SPLIT signal is the discriminator the SKILL prose reads.
|
|
124
|
+
mkdir -p "$FIXTURE_DIR/briefing"
|
|
125
|
+
printf '%.0s.' $(seq 1 10240) > "$FIXTURE_DIR/briefing/exactly-2x.md"
|
|
126
|
+
run "$SCRIPT" "$FIXTURE_DIR/briefing"
|
|
127
|
+
[ "$status" -eq 0 ]
|
|
128
|
+
echo "$output" | grep -E "^OVER exactly-2x.md bytes=10240 threshold=5120"
|
|
129
|
+
echo "$output" | grep -E "^MUST_SPLIT exactly-2x.md reason=ratio-exceeds-2x"
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
# ── Structural backstops: SKILL.md prose contract terms (narrow per P081) ───
|
|
133
|
+
#
|
|
134
|
+
# These assertions link SKILL.md prose (canonical human-readable source)
|
|
135
|
+
# to the evidence-based-rotation contract and the driver ticket. Without
|
|
136
|
+
# these links, the prose contract could drift independently from the
|
|
137
|
+
# enforcement layer + driver-ticket evidence trail. Per P081, the scope
|
|
138
|
+
# is narrowed to the smallest set of tokens that prove the contract
|
|
139
|
+
# terms exist in the prose; assertions intentionally avoid coupling to
|
|
140
|
+
# line numbers or sentence-level structure.
|
|
141
|
+
|
|
142
|
+
@test "Branch B prose: SKILL.md no longer permits the 'leave-as-is' fall-through (P247 fix verification)" {
|
|
143
|
+
# The contract negative-assertion: the eliminated branch's literal
|
|
144
|
+
# token "leave-as-is" must NOT appear as a permitted Branch B
|
|
145
|
+
# rotation option. The token may legitimately appear inside a
|
|
146
|
+
# historical-reference context (e.g. "the eliminated 'leave-as-is'
|
|
147
|
+
# branch") — that's why we don't grep for the bare token but for the
|
|
148
|
+
# specific surface that previously authorised the defer.
|
|
149
|
+
! grep -F "Else: **leave-as-is**" "$SKILL_MD"
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
@test "Branch B prose: SKILL.md names 'split-by-date (safe default)' as the Branch B fall-through (P247 fix verification)" {
|
|
153
|
+
# The contract positive-assertion: the new fall-through must be named
|
|
154
|
+
# explicitly as "split-by-date (safe default)" — the same naming
|
|
155
|
+
# Branch A already uses, so a reader of the prose sees the alignment
|
|
156
|
+
# without having to cross-reference Branch A's bullet.
|
|
157
|
+
grep -F "split-by-date (safe default)" "$SKILL_MD"
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
@test "Branch B prose: SKILL.md cites P247 as the driver ticket (audit-trail link)" {
|
|
161
|
+
# Audit-trail link: the prose names P247 so future readers can locate
|
|
162
|
+
# the evidence trail (user correction quote, sibling-class relationship
|
|
163
|
+
# to P246, the 14-file evidence from 2026-05-17 session 4 wrap retro).
|
|
164
|
+
grep -F "P247" "$SKILL_MD"
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
@test "Branch B prose: SKILL.md cites P246 sibling fix as the evidence-based principle precedent (cross-class linkage)" {
|
|
168
|
+
# Cross-class linkage: P246 (cohort-graduation surface) is the immediate
|
|
169
|
+
# sibling fix. The Branch B prose must cite it so the evidence-based-
|
|
170
|
+
# not-time-based principle is discoverable as a class, not a one-off
|
|
171
|
+
# SKILL fix.
|
|
172
|
+
grep -F "P246" "$SKILL_MD"
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
@test "Branch B prose: SKILL.md cites ADR-044 framework-mediated surface for silent rotation (governance link)" {
|
|
176
|
+
# Governance link: per architect verdict, Branch B's silent-rotation
|
|
177
|
+
# discipline is authorised by ADR-044's framework-resolution boundary
|
|
178
|
+
# ("Briefing add / remove / rotate" line 77). The prose must cite the
|
|
179
|
+
# ADR so a reader sees the authority for not firing AskUserQuestion
|
|
180
|
+
# per file in Branch B's fall-through.
|
|
181
|
+
grep -F "ADR-044" "$SKILL_MD"
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
@test "Branch B prose: SKILL.md cites ADR-013 Rule 5 for policy-authorised silent proceed (governance link)" {
|
|
185
|
+
# Companion governance link: ADR-013 Rule 5 is the originating rule
|
|
186
|
+
# for silent-proceed under policy. Branch B inherits this discipline;
|
|
187
|
+
# the citation makes the rule chain explicit.
|
|
188
|
+
grep -F "ADR-013 Rule 5" "$SKILL_MD"
|
|
189
|
+
}
|