headroom/crates
Zhenjia ZHOU 8879c50dbe
fix(adaptive-sizer): char bigrams for spaceless CJK items (#1748)
## Description

`compute_unique_bigram_curve` — the adaptive sizer's coverage-curve
builder, mirrored in Rust and Python — word-splits each item on
whitespace to form word bigrams. A spaceless CJK item has no whitespace,
so it collapsed into one `(whole_string, "")` pseudo-bigram: the
coverage curve then grew ~1 per item, the kneedle knee detector found no
knee, and CJK lists under-compressed.

Spaceless CJK items now use character bigrams, producing a real coverage
curve. Mirrored byte-exactly in Rust and Python (identical
reference-test curve values). Non-CJK items — anything
whitespace-bearing or spaceless-ASCII — are byte-identical to before, so
the `smart_crusher` parity fixtures are unchanged.

## Type of Change

- [x] Bug fix (non-breaking change that fixes an issue)

## Changes Made

- `crates/headroom-core/src/transforms/adaptive_sizer.rs` +
`headroom/transforms/adaptive_sizer.py`: add
`is_cjk_char`/`_is_cjk_char` (identical code-point ranges) and a
spaceless-CJK character-bigram branch in `compute_unique_bigram_curve`.
- Rust unit tests + `tests/test_adaptive_sizer.py`: CJK curve,
single-char CJK, ASCII-unchanged, empty-item — the Rust and Python
reference values are identical.

## Testing

- [x] Unit tests pass (`cargo test` + `pytest`)
- [x] Linting passes (`cargo clippy` / `cargo fmt` / `ruff` / `mypy`)
- [x] New tests added for new functionality
- [x] Manual testing performed (see Real Behavior Proof)

### Test Output

```text
$ cargo test -p headroom-core --lib adaptive_sizer
test result: ok. 35 passed; 0 failed

$ .venv/bin/python -m pytest tests/test_adaptive_sizer.py
20 passed

$ .venv/bin/python -m pytest -k "smart_crusher and parity"
18 passed, 6 skipped   # non-CJK fixtures unchanged
```

## Real Behavior Proof

- Environment: macOS (Darwin), Rust via cargo, Python in a uv venv,
branch `feat/adaptive-sizer-cjk` off `main`.
- Exact command / steps: called `compute_unique_bigram_curve` on a CJK
list and on ASCII lists, in both implementations.
- Observed result: `compute_unique_bigram_curve(["数据库连接失败", "数据库连接成功"])`
returns `[6, 8]` in **both** Rust and Python (before: ~`[1, 2]` — one
pseudo-bigram per item, no coverage signal). ASCII curves are unchanged:
`["the cat", "the dog", "a fish"]` → `[1, 2, 3]`. The `smart_crusher`
parity suite (all-ASCII fixtures) stays green, confirming non-CJK output
is byte-identical.
- Byte-exact parity: the Rust reference test (`vec![6, 8]`) and the
Python test (`[6, 8]`) use the same inputs and the same expected values,
so the two implementations are pinned to agree.

## Review Readiness

- [x] I have performed a self-review
- [x] This PR is ready for human review

## Checklist

- [x] My code follows the project's style guidelines
- [x] I have performed a self-review of my code
- [x] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation — N/A
(internal sizing heuristic)
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective
- [x] New and existing unit tests pass locally with my changes
- [ ] I have updated the CHANGELOG.md — N/A: internal sizing-heuristic
fix, no user-facing surface change

## Additional Notes

- This is a parity-locked function (Rust and Python must agree
byte-for-byte). The fix is CJK-gated, so non-CJK output is
byte-identical and the `smart_crusher` parity fixtures need no
re-recording.
2026-07-09 17:01:29 -05:00
..
headroom-core fix(adaptive-sizer): char bigrams for spaceless CJK items (#1748) 2026-07-09 17:01:29 -05:00
headroom-parity feat: compression extraction — Rust knob exposure, CCR hardening, traffic audits (#818) 2026-06-16 20:21:13 -07:00
headroom-proxy fix(deps): remediate dependency CVEs and publish SBOM (#1509) 2026-06-27 15:28:12 -07:00
headroom-py fix(deps): remediate dependency CVEs and publish SBOM (#1509) 2026-06-27 15:28:12 -07:00