Cap persisted command output in paginated history at 64 KiB (#50427)

## Why

Paginated history previously persisted completed commands' full `aggregated_output`, allowing large command outputs to inflate stored history.

## What changed

- Limit persisted command `aggregated_output` to 64 KiB, including a truncation marker. Preserve the beginning and end of the output without splitting UTF-8 characters.
- Apply the shared persistence policy to rollout recording, thread-store appends, and legacy-to-paginated history migration.
- Measure persisted payload bytes after truncation so persistence metrics reflect the stored representation.

## Testing

Add coverage for the byte limit, UTF-8 boundaries, unchanged inputs that fit, and markers that exceed the budget. Verify capped output in paginated thread history and migrated legacy history, and verify persistence metrics use the truncated payload size.

GitOrigin-RevId: 01d420d396ad34b42dc5dc208c0bf88d890639ee
This commit is contained in:
Owen Lin
2026-10-02 21:00:06 +00:00
committed by copyberry
parent 44dd77b71e
commit bee28e8a06
18 changed files with 353 additions and 80 deletions
@@ -1,5 +1,6 @@
use super::split_string;
use super::truncate_middle_chars;
use super::truncate_middle_with_marker;
use super::truncate_middle_with_token_budget;
use pretty_assertions::assert_eq;
@@ -129,3 +130,36 @@ fn truncate_middle_bytes_handles_utf8_content() {
let out = truncate_middle_chars(s, /*max_bytes*/ 20);
assert_eq!(out, "😀😀…21 chars truncated…with text\n");
}
#[test]
fn truncate_middle_with_marker_enforces_the_total_byte_limit() {
let input = format!("head{}tail", "x".repeat(100));
assert_eq!(
truncate_middle_with_marker(&input, /*max_bytes*/ 32, "<truncated>"),
"headxxxxxx<truncated>xxxxxxxtail"
);
}
#[test]
fn truncate_middle_with_marker_preserves_utf8_boundaries() {
assert_eq!(
truncate_middle_with_marker("head🦀🦀🦀🦀🦀tail", /*max_bytes*/ 18, "..."),
"head...🦀tail"
);
}
#[test]
fn truncate_middle_with_marker_returns_input_that_fits() {
assert_eq!(
truncate_middle_with_marker("short", /*max_bytes*/ 5, "..."),
"short"
);
}
#[test]
fn truncate_middle_with_marker_keeps_a_prefix_when_the_marker_does_not_fit() {
assert_eq!(
truncate_middle_with_marker("🦀abc", /*max_bytes*/ 4, "marker"),
"🦀"
);
}