mirror of
https://github.com/headroomlabs-ai/headroom.git
synced 2026-08-27 14:17:10 -04:00
When a placeholder is lost during compression, restore_tags now
discards the wrap rather than appending the original tag at the
trailing edge of the output. The old "append" fallback emitted
malformed XML — an opening tag with no body and no closing tag —
on ~350 production requests over 9 days. Per the proxy log
findings, the corruption pattern was `compressed-stuff <tag>`,
which downstream models interpret as a truncated message.
Concrete changes:
* `crates/headroom-core/src/transforms/tag_protector.rs`:
- `restore_tags` no longer accumulates `tail_appends`. Lost
placeholders are silently dropped from the output bytes.
- New `restore_tags_with_request_id` entry point threads an
optional request id into the structured ERROR log so the
proxy layer can wire request context end-to-end. PyO3 binding
keeps the existing 2-arg signature (no Python caller has a
request id today).
- `tag_lost_warn` is replaced by `tag_lost_error`. Severity
moves from WARN to ERROR with structured fields
(`event=tag_protector_placeholder_lost`, `tag_preview`,
`compressed_length`, `action=discarded_wrap`, optional
`request_id`) so operators can alert on the corruption rather
than have it disappear into a WARN line.
- `parse_tag_at` gained a bounds check after consuming a
leading '/' — proptest discovered an OOB on input `</`.
- The old `restore_lost_placeholder_appended` test (which
pinned the broken behavior) is replaced with three positive
tests: wrap-discard, idempotence on full loss, and
partial-loss-keeps-present-drops-lost.
- New proptest suite enforces three invariants over arbitrary
inputs: no introduced asymmetry, idempotence on full
placeholder loss, and no orphan-byte injection.
* `headroom/transforms/tag_protector.py`: docstring updated
to document the discard-wrap semantics — the prior text
("appended on the trailing edge") is now incorrect.
* `tests/test_tag_protector_invariant.py` (new): Python-side
invariant suite that exercises the same three properties
end-to-end through the public Python API. Uses a deterministic
seeded random walk (no `hypothesis` dependency) so CI is stable
and reproducible.
* `tests/test_transforms/test_tag_protector.py`: replaces the
broken-behavior test with the new wrap-discard semantics.
Per-finding-#3: ~/Desktop/HEADROOM_PROXY_LOG_FINDINGS_2026_05_03.md.
|
||
|---|---|---|
| .. | ||
| __init__.py | ||
| test_code_compressor.py | ||
| test_content_router.py | ||
| test_diff_compressor.py | ||
| test_diff_compressor_rust_parity.py | ||
| test_html_extractor.py | ||
| test_kompress_compressor.py | ||
| test_read_lifecycle.py | ||
| test_smart_crusher_bugs.py | ||
| test_smart_crusher_ccr_roundtrip.py | ||
| test_smart_crusher_lossless_default.py | ||
| test_smart_crusher_rust_parity.py | ||
| test_tag_protector.py | ||