Skip to content

feat(h-protocol): body-buffer audit + adaptive sampling for 1M-token contexts (H007) #68

Description

@rivercg

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

  • Current body-buffer behavior documented in docs/design/ with cap-boundary failure modes.
  • Configurable request-body cap implemented: full-header capture + first-N/last-M retention + unconditional terminal-chunk retention.
  • llm_calls.body_bytes_dropped present and correct across DuckDB / PostgreSQL / ClickHouse backends.
  • Cap defaults configurable via config/default.toml (not hard-coded).
  • Test fixture with a >1 MB request body verifies gen_ai.usage.* extraction still succeeds after sampling.

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions