Note: crate names below use the Heron h-* naming that already landed on main (rebrand Phase 2, #66). Product/repo prose still says TokenScope.
Goal
Stop multi-megabyte 1M-token request bodies from either silently truncating gen_ai.usage.* extraction or causing memory pressure on capture nodes — keep S1 (infra ops, stage 1) TTFB/throughput/usage accuracy correct under modern context sizes.
Why now
1M-token context windows normalized in 2026 (Sonnet 4/4.5 and GPT-5.5 ship 1M as a default tier; Helicone defaults 1M on Sonnet 4/4.5). Today h-protocol's BodyReader.decoded_body accumulates the full reassembled body into an uncapped BytesMut; the only byte bound is snaplen (per-packet, 262144), which truncates reassembly rather than sampling. This is a stage-1 accuracy and capture-node-stability risk now, not hypothetically.
In scope
- Audit + document current body-buffering behavior (uncapped accumulation, SSE
suppress_accumulation path, snaplen interaction) in docs/design/.
- Configurable request-body cap with "keep first N bytes + last M bytes" sampling on the accumulated body.
- Unconditional retention of the terminal chunk carrying the
usage block, regardless of size budget.
body_bytes_dropped counter on llm_calls, non-zero exactly when policy truncates.
- Cap defaults in
config/default.toml, per-deployment overridable.
Out of scope (explicit)
- Tail-aware sampling that parses the body to locate the
usage event (deferred).
- Any change to
snaplen / per-packet capture in h-capture.
- Realtime / full-duplex transports (WebSocket/WebRTC) — owned by a separate horizon (H008).
- Coupling the policy to provider detection (
h-llm); it must run before classification.
Success criteria
Suggested approach
Inject a body-cap config into BodyReader (currently takes framing only); intercept decoded_body accumulation to retain head + sliding tail windows and emit a dropped-bytes count; plumb the count onto LlmCall; add the column to all storage backends with default 0.
Files / crates touched
server/h-protocol/src/http.rs (BodyReader)
server/h-common/ (body-cap config struct) + server/config/default.toml
server/h-llm/ (plumb body_bytes_dropped onto LlmCall)
server/h-storage/ + server/h-storage-duckdb/ (add llm_calls.body_bytes_dropped, all backends)
docs/design/ (buffering documentation)
Open questions for human
- Symmetric vs asymmetric request/response cap? (Proposed: start symmetric, config shaped to allow a separate response cap later.)
- Is a fixed tail window always sufficient to capture
usage, or is tail-aware parsing needed for some provider framing?
Generated by /evo-blueprint from horizon H007 (TokenScopeEvolution planning repo). Design doc: docs/superpowers/specs/2026-05-28-body-buffer-audit-design.md.
Goal
Stop multi-megabyte 1M-token request bodies from either silently truncating
gen_ai.usage.*extraction or causing memory pressure on capture nodes — keep S1 (infra ops, stage 1) TTFB/throughput/usage accuracy correct under modern context sizes.Why now
1M-token context windows normalized in 2026 (Sonnet 4/4.5 and GPT-5.5 ship 1M as a default tier; Helicone defaults 1M on Sonnet 4/4.5). Today
h-protocol'sBodyReader.decoded_bodyaccumulates the full reassembled body into an uncappedBytesMut; the only byte bound issnaplen(per-packet, 262144), which truncates reassembly rather than sampling. This is a stage-1 accuracy and capture-node-stability risk now, not hypothetically.In scope
suppress_accumulationpath,snapleninteraction) indocs/design/.usageblock, regardless of size budget.body_bytes_droppedcounter onllm_calls, non-zero exactly when policy truncates.config/default.toml, per-deployment overridable.Out of scope (explicit)
usageevent (deferred).snaplen/ per-packet capture inh-capture.h-llm); it must run before classification.Success criteria
docs/design/with cap-boundary failure modes.llm_calls.body_bytes_droppedpresent and correct across DuckDB / PostgreSQL / ClickHouse backends.config/default.toml(not hard-coded).gen_ai.usage.*extraction still succeeds after sampling.Suggested approach
Inject a body-cap config into
BodyReader(currently takes framing only); interceptdecoded_bodyaccumulation to retain head + sliding tail windows and emit a dropped-bytes count; plumb the count ontoLlmCall; add the column to all storage backends with default 0.Files / crates touched
server/h-protocol/src/http.rs(BodyReader)server/h-common/(body-cap config struct) +server/config/default.tomlserver/h-llm/(plumbbody_bytes_droppedontoLlmCall)server/h-storage/+server/h-storage-duckdb/(addllm_calls.body_bytes_dropped, all backends)docs/design/(buffering documentation)Open questions for human
usage, or is tail-aware parsing needed for some provider framing?Generated by
/evo-blueprintfrom horizon H007 (TokenScopeEvolution planning repo). Design doc:docs/superpowers/specs/2026-05-28-body-buffer-audit-design.md.