1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
//! verbatim --slice/--slices: fixed-fleet chunking and reassembly.
use crate::harness::*;
#[test]
fn turns_slice_reassembles_out_document_within_window() {
// --slice paginates the SAME verbatim document `--out` writes into ≤window-CHAR chunks with
// NO chrome. Assert: every chunk ≤ window, concatenating slices 1..K reproduces the `--out`
// document byte-for-byte (the zero-drift contract between build_document_body and out_blob),
// and an out-of-range slice is empty (exit 0).
let h = turns_home();
let window = 500usize;
let out_path = h.root.join("turns_doc.md");
let r = h.run(&[
"verbatim",
at(SESS).as_str(),
"--budget",
"20000",
"--no-subagents",
"--out",
out_path.to_str().unwrap(),
]);
assert!(r.success, "stderr: {}", r.stderr);
let document = std::fs::read_to_string(&out_path).expect("out document written");
assert!(!document.is_empty(), "fixture yields a non-empty document");
assert!(
document.chars().count() > window,
"document must exceed one window to exercise multi-slice ({} chars)",
document.chars().count()
);
let win = window.to_string();
let mut reassembled = String::new();
let mut n = 1usize;
loop {
let ns = n.to_string();
let s = h.run(&[
"verbatim",
at(SESS).as_str(),
"--budget",
"20000",
"--no-subagents",
"--window",
&win,
"--slice",
&ns,
]);
assert!(s.success, "slice {n} stderr: {}", s.stderr);
if s.stdout.is_empty() {
break; // out-of-range slice → empty → done
}
assert!(
s.stdout.chars().count() <= window,
"slice {n} exceeds the {window}-char window ({} chars)",
s.stdout.chars().count()
);
reassembled.push_str(&s.stdout);
n += 1;
assert!(n < 1000, "runaway slice loop");
}
assert!(
n > 2,
"fixture should span at least two slices, got {}",
n - 1
);
assert_eq!(
reassembled, document,
"concatenated slices must reproduce the --out document byte-for-byte"
);
}
#[test]
fn turns_slices_pins_emitted_count_to_the_fleet() {
// `--slices N` makes the slice COUNT the hard constraint: it emits AT MOST N chunks no matter
// how many a char budget would have produced, and each chunk stays within the window. A 2-slice
// fleet over this multi-block fixture: slices 1-2 are within window, and any index > 2 is empty
// - the count can never drift to 3/4/5 as the turns grow.
let h = turns_home();
let win = 1500usize;
for i in 1..=2 {
let o = h.run(&[
"verbatim",
at(SESS).as_str(),
"--no-subagents",
"--slices",
"2",
"--window",
"1500",
"--slice",
&i.to_string(),
]);
assert!(o.success, "stderr: {}", o.stderr);
assert!(
o.stdout.chars().count() <= win,
"slice {i} exceeds the window: {}",
o.stdout.chars().count()
);
}
let s1 = h.run(&[
"verbatim",
at(SESS).as_str(),
"--no-subagents",
"--slices",
"2",
"--window",
"1500",
"--slice",
"1",
]);
assert!(
!s1.stdout.is_empty(),
"slice 1 of a filled 2-fleet is non-empty"
);
let s3 = h.run(&[
"verbatim",
at(SESS).as_str(),
"--no-subagents",
"--slices",
"2",
"--window",
"1500",
"--slice",
"3",
]);
assert!(
s3.stdout.is_empty(),
"an index beyond the fixed fleet must be empty, got: {}",
s3.stdout
);
}
#[test]
fn turns_slices_keeps_newest_discards_oldest() {
// The fleet fills newest-first; the oldest turns that don't fit are DISCARDED (not truncated).
// A tight 2-slice fleet keeps the live tail and drops the oldest round-trip ("the very first
// ask … café").
let h = turns_home();
let mut doc = String::new();
for i in 1..=2 {
doc.push_str(
&h.run(&[
"verbatim",
at(SESS).as_str(),
"--no-subagents",
"--slices",
"2",
"--window",
"1500",
"--slice",
&i.to_string(),
])
.stdout,
);
}
assert!(
!doc.contains("the very first ask"),
"the oldest turn must be discarded by a small fleet: {doc}"
);
assert!(
doc.contains("final committed answer")
|| doc.contains("TAILuser")
|| doc.contains("short live ask")
|| doc.contains("do the final thing"),
"the newest turns must be kept: {doc}"
);
}
#[test]
fn turns_slices_keeps_user_turns_whole_no_role_cap() {
// The defect a peer session caught: budget mode middle-truncates a USER turn at the 600-char
// role cap even with budget to spare. In `--slices` mode the only cap is the WINDOW, so a
// multi-hundred-char user directive survives VERBATIM. The fixture's huge_user (≈817 chars)
// appears whole (no mid-cut) when the window comfortably exceeds it.
let h = turns_home();
let mut doc = String::new();
for i in 1..=8 {
doc.push_str(
&h.run(&[
"verbatim",
at(SESS).as_str(),
"--no-subagents",
"--slices",
"8",
"--window",
"9000",
"--slice",
&i.to_string(),
])
.stdout,
);
}
let whole = format!("HEADuser {} TAILuser", "u".repeat(800));
assert!(
doc.contains(&whole),
"a long user turn must be kept whole in --slices mode (it was gutted at the 600 cap?)"
);
// Contrast: the SAME fixture under budget mode STILL applies the 600 user cap (legacy behavior
// is untouched) - so the verbatim user body is NOT present and the elision marker IS.
let budgeted = h.run(&[
"verbatim",
at(SESS).as_str(),
"--no-subagents",
"--budget",
"40000",
]);
assert!(
!budgeted.stdout.contains(&whole),
"budget mode must still apply the 600 user cap (legacy unchanged)"
);
assert!(
budgeted.stdout.contains("chars elided") || budgeted.stdout.contains("chars]"),
"budget mode shows the elision marker"
);
}
#[test]
fn turns_slices_ellipsizes_only_a_turn_bigger_than_one_window() {
// The ONLY content cut in --slices mode is a single turn that ALONE exceeds one window. With a
// small window the big assistant turn (≈3000 chars) is middle-elided, while the shorter user
// turn (≈817) in the same fleet is kept whole.
let h = turns_home();
let mut doc = String::new();
for i in 1..=8 {
doc.push_str(
&h.run(&[
"verbatim",
at(SESS).as_str(),
"--no-subagents",
"--slices",
"8",
"--window",
"1200",
"--slice",
&i.to_string(),
])
.stdout,
);
}
assert!(
doc.contains("chars elided") || doc.contains("chars]"),
"a turn larger than one window is ellipsized: {doc}"
);
assert!(
doc.contains(&format!("HEADuser {} TAILuser", "u".repeat(800))),
"a turn that fits within one window is kept whole alongside it: {doc}"
);
}