docs(compaction): describe the transcript cut as it actually behaves

The comments promised that a boundary-less head hands its share to the tail. It doesn't: the tail keeps its own half, and only a boundary-less tail gets the full newest budget. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Co-Authored-By: siGit Code v1.5.11 <noreply@sigit.si>

Seto Elkahfi committed Oct 4, 2026 at 23:44 UTC a99173f2eb68c59401438c593484e403678e0337
1 file changed +7 -7
src/backend.rs
+7 -7
@@ -97,11 +97,11 @@ const SUMMARY_TRANSCRIPT_TOKEN_CAP: usize = 12_000;
97 /// whole lines keeps individual messages intact. A transcript already under
98 /// the cap is returned unchanged.
99 ///
100 -/// Line boundaries are best-effort: when one side of the cut can't land on a
101 -/// newline (a transcript of very long lines, or a single huge message), that
102 -/// side gives up its share rather than the other — the newest exchanges are
103 -/// the ones the summary can least afford to lose, so the head shrinks to make
104 -/// room. Both sides failing degrades to keeping only the newest budget.
100 +/// Line boundaries are best-effort. A head with no newline in its half is
101 +/// dropped and the tail keeps its own half. A tail with no newline in its half
102 +/// (a single huge message, or a giant final tool result) can't be cut on a
103 +/// line, so the newest `cap` worth of text is kept instead and the head goes:
104 +/// the newest exchanges are the ones the summary can least afford to lose.
105 fn truncate_transcript_middle(transcript: &str, cap: usize) -> String {
106 let budget = cap * 4; // estimate_tokens is chars / 4; invert it.
107 if transcript.len() <= budget {
@@ -110,8 +110,8 @@ fn truncate_transcript_middle(transcript: &str, cap: usize) -> String {
110
111 let total = transcript.len();
112 // Each side gets half the budget, so the two together stay inside the cap.
113 - // Walk each half to a line boundary. A side with no boundary in reach
114 - // contributes nothing; the newest side may then use the whole budget.
113 + // Walk each half to a line boundary. A head with no boundary in reach
114 + // contributes nothing; a tail with none takes the hard cut below.
115 let half = budget / 2;
116 let head_end = {
117 let mut cut = half.min(total);