headroom/tests/test_ccr.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

362 lines
11 KiB
Python
Raw Normal View History

feat: Add CCR architecture, TOIN telemetry, and DevEx improvements ## Core Features ### Compress-Cache-Retrieve (CCR) Architecture - Implement reversible compression with automatic retrieval support - Add CompressionStore for caching original content with TTL-based eviction - Add CompressionFeedback for learning from retrieval patterns - Implement tool injection for LLM retrieval capability - Add MCP server support for CCR operations - Track retrieval rates to dynamically adjust compression aggressiveness ### Tool Output Intelligence Network (TOIN) - Implement cross-session pattern learning for tool compression - Add ToolSignature for structural hashing of tool outputs - Track compression success rates per strategy (top_n, sample, truncate, etc.) - Implement privacy-preserving telemetry with SHA256 hashing - Add persistent storage with JSON file backend - Support network-effect learning across tool types ### SmartCrusher Enhancements - Add crushability analysis with variance/uniqueness detection - Implement statistical anomaly detection for outlier preservation - Add relevance-based item prioritization using BM25 scoring - Support multiple compression strategies with quality retention - Add change point detection for time-series data - Implement constant factoring for homogeneous datasets ## Developer Experience Improvements ### Exception Hierarchy - Add HeadroomError base class for all custom exceptions - Add specific exceptions: ConfigurationError, ProviderError, StorageError, CompressionError, TokenizationError, CacheError, ValidationError, TransformError ### Client Enhancements - Add validate_setup() for configuration verification - Add get_stats() for in-memory session metrics without DB query - Track session statistics (requests, tokens saved, cache hits) ### Logging Infrastructure - Add structured logging to TransformPipeline with token savings - Add logging to RollingWindow for dropped message tracking - Add logging to ToolCrusher for compression events - Add logging to CacheAligner for cache hit/miss detection - Add logging to SmartCrusher for strategy selection ## Bug Fixes (from deep analysis) ### Critical Fixes - Fix eviction heap memory leak with stale entry tracking - Fix hash collision detection in compression store - Fix strategy truncation desync in TOIN - Fix non-deterministic set truncation with sorted iteration - Fix race conditions in lazy initialization with proper locking - Fix user count double-counting in TOIN metrics ### High Priority Fixes - Fix unbounded strategy_success_rates growth with LRU eviction - Fix mutable pattern references with defensive copying - Fix lock held during file I/O with copy-then-write pattern - Fix state divergence on eviction with success event recording - Fix TOIN skip check order for CPU efficiency - Fix preserve_fields type mismatch (set vs list) - Fix prioritize_indices exceeding max_items limit - Fix instance ID collision risk (32-bit to 64-bit hash) ## Testing - Add comprehensive test suites for CCR, TOIN, and telemetry - Add crushability detection tests - Add quality retention tests for compression - Add integration tests for cross-component data flow - All 902 tests passing
2026-01-10 10:12:13 -08:00
"""Tests for Compress-Cache-Retrieve (CCR) architecture.
These tests verify that:
1. CompressionStore correctly caches compressed content
2. SmartCrusher integrates with CompressionStore
3. Retrieval works correctly (full and search)
4. Feedback tracking works
5. TTL expiration works
"""
import json
import time
feat: Add CCR architecture, TOIN telemetry, and DevEx improvements ## Core Features ### Compress-Cache-Retrieve (CCR) Architecture - Implement reversible compression with automatic retrieval support - Add CompressionStore for caching original content with TTL-based eviction - Add CompressionFeedback for learning from retrieval patterns - Implement tool injection for LLM retrieval capability - Add MCP server support for CCR operations - Track retrieval rates to dynamically adjust compression aggressiveness ### Tool Output Intelligence Network (TOIN) - Implement cross-session pattern learning for tool compression - Add ToolSignature for structural hashing of tool outputs - Track compression success rates per strategy (top_n, sample, truncate, etc.) - Implement privacy-preserving telemetry with SHA256 hashing - Add persistent storage with JSON file backend - Support network-effect learning across tool types ### SmartCrusher Enhancements - Add crushability analysis with variance/uniqueness detection - Implement statistical anomaly detection for outlier preservation - Add relevance-based item prioritization using BM25 scoring - Support multiple compression strategies with quality retention - Add change point detection for time-series data - Implement constant factoring for homogeneous datasets ## Developer Experience Improvements ### Exception Hierarchy - Add HeadroomError base class for all custom exceptions - Add specific exceptions: ConfigurationError, ProviderError, StorageError, CompressionError, TokenizationError, CacheError, ValidationError, TransformError ### Client Enhancements - Add validate_setup() for configuration verification - Add get_stats() for in-memory session metrics without DB query - Track session statistics (requests, tokens saved, cache hits) ### Logging Infrastructure - Add structured logging to TransformPipeline with token savings - Add logging to RollingWindow for dropped message tracking - Add logging to ToolCrusher for compression events - Add logging to CacheAligner for cache hit/miss detection - Add logging to SmartCrusher for strategy selection ## Bug Fixes (from deep analysis) ### Critical Fixes - Fix eviction heap memory leak with stale entry tracking - Fix hash collision detection in compression store - Fix strategy truncation desync in TOIN - Fix non-deterministic set truncation with sorted iteration - Fix race conditions in lazy initialization with proper locking - Fix user count double-counting in TOIN metrics ### High Priority Fixes - Fix unbounded strategy_success_rates growth with LRU eviction - Fix mutable pattern references with defensive copying - Fix lock held during file I/O with copy-then-write pattern - Fix state divergence on eviction with success event recording - Fix TOIN skip check order for CPU efficiency - Fix preserve_fields type mismatch (set vs list) - Fix prioritize_indices exceeding max_items limit - Fix instance ID collision risk (32-bit to 64-bit hash) ## Testing - Add comprehensive test suites for CCR, TOIN, and telemetry - Add crushability detection tests - Add quality retention tests for compression - Add integration tests for cross-component data flow - All 902 tests passing
2026-01-10 10:12:13 -08:00
import pytest
feat: Add CCR architecture, TOIN telemetry, and DevEx improvements ## Core Features ### Compress-Cache-Retrieve (CCR) Architecture - Implement reversible compression with automatic retrieval support - Add CompressionStore for caching original content with TTL-based eviction - Add CompressionFeedback for learning from retrieval patterns - Implement tool injection for LLM retrieval capability - Add MCP server support for CCR operations - Track retrieval rates to dynamically adjust compression aggressiveness ### Tool Output Intelligence Network (TOIN) - Implement cross-session pattern learning for tool compression - Add ToolSignature for structural hashing of tool outputs - Track compression success rates per strategy (top_n, sample, truncate, etc.) - Implement privacy-preserving telemetry with SHA256 hashing - Add persistent storage with JSON file backend - Support network-effect learning across tool types ### SmartCrusher Enhancements - Add crushability analysis with variance/uniqueness detection - Implement statistical anomaly detection for outlier preservation - Add relevance-based item prioritization using BM25 scoring - Support multiple compression strategies with quality retention - Add change point detection for time-series data - Implement constant factoring for homogeneous datasets ## Developer Experience Improvements ### Exception Hierarchy - Add HeadroomError base class for all custom exceptions - Add specific exceptions: ConfigurationError, ProviderError, StorageError, CompressionError, TokenizationError, CacheError, ValidationError, TransformError ### Client Enhancements - Add validate_setup() for configuration verification - Add get_stats() for in-memory session metrics without DB query - Track session statistics (requests, tokens saved, cache hits) ### Logging Infrastructure - Add structured logging to TransformPipeline with token savings - Add logging to RollingWindow for dropped message tracking - Add logging to ToolCrusher for compression events - Add logging to CacheAligner for cache hit/miss detection - Add logging to SmartCrusher for strategy selection ## Bug Fixes (from deep analysis) ### Critical Fixes - Fix eviction heap memory leak with stale entry tracking - Fix hash collision detection in compression store - Fix strategy truncation desync in TOIN - Fix non-deterministic set truncation with sorted iteration - Fix race conditions in lazy initialization with proper locking - Fix user count double-counting in TOIN metrics ### High Priority Fixes - Fix unbounded strategy_success_rates growth with LRU eviction - Fix mutable pattern references with defensive copying - Fix lock held during file I/O with copy-then-write pattern - Fix state divergence on eviction with success event recording - Fix TOIN skip check order for CPU efficiency - Fix preserve_fields type mismatch (set vs list) - Fix prioritize_indices exceeding max_items limit - Fix instance ID collision risk (32-bit to 64-bit hash) ## Testing - Add comprehensive test suites for CCR, TOIN, and telemetry - Add crushability detection tests - Add quality retention tests for compression - Add integration tests for cross-component data flow - All 902 tests passing
2026-01-10 10:12:13 -08:00
from headroom.cache.compression_store import (
CompressionStore,
get_compression_store,
reset_compression_store,
)
from headroom.config import CCRConfig
feat: Add CCR architecture, TOIN telemetry, and DevEx improvements ## Core Features ### Compress-Cache-Retrieve (CCR) Architecture - Implement reversible compression with automatic retrieval support - Add CompressionStore for caching original content with TTL-based eviction - Add CompressionFeedback for learning from retrieval patterns - Implement tool injection for LLM retrieval capability - Add MCP server support for CCR operations - Track retrieval rates to dynamically adjust compression aggressiveness ### Tool Output Intelligence Network (TOIN) - Implement cross-session pattern learning for tool compression - Add ToolSignature for structural hashing of tool outputs - Track compression success rates per strategy (top_n, sample, truncate, etc.) - Implement privacy-preserving telemetry with SHA256 hashing - Add persistent storage with JSON file backend - Support network-effect learning across tool types ### SmartCrusher Enhancements - Add crushability analysis with variance/uniqueness detection - Implement statistical anomaly detection for outlier preservation - Add relevance-based item prioritization using BM25 scoring - Support multiple compression strategies with quality retention - Add change point detection for time-series data - Implement constant factoring for homogeneous datasets ## Developer Experience Improvements ### Exception Hierarchy - Add HeadroomError base class for all custom exceptions - Add specific exceptions: ConfigurationError, ProviderError, StorageError, CompressionError, TokenizationError, CacheError, ValidationError, TransformError ### Client Enhancements - Add validate_setup() for configuration verification - Add get_stats() for in-memory session metrics without DB query - Track session statistics (requests, tokens saved, cache hits) ### Logging Infrastructure - Add structured logging to TransformPipeline with token savings - Add logging to RollingWindow for dropped message tracking - Add logging to ToolCrusher for compression events - Add logging to CacheAligner for cache hit/miss detection - Add logging to SmartCrusher for strategy selection ## Bug Fixes (from deep analysis) ### Critical Fixes - Fix eviction heap memory leak with stale entry tracking - Fix hash collision detection in compression store - Fix strategy truncation desync in TOIN - Fix non-deterministic set truncation with sorted iteration - Fix race conditions in lazy initialization with proper locking - Fix user count double-counting in TOIN metrics ### High Priority Fixes - Fix unbounded strategy_success_rates growth with LRU eviction - Fix mutable pattern references with defensive copying - Fix lock held during file I/O with copy-then-write pattern - Fix state divergence on eviction with success event recording - Fix TOIN skip check order for CPU efficiency - Fix preserve_fields type mismatch (set vs list) - Fix prioritize_indices exceeding max_items limit - Fix instance ID collision risk (32-bit to 64-bit hash) ## Testing - Add comprehensive test suites for CCR, TOIN, and telemetry - Add crushability detection tests - Add quality retention tests for compression - Add integration tests for cross-component data flow - All 902 tests passing
2026-01-10 10:12:13 -08:00
from headroom.transforms.smart_crusher import (
SmartCrusherConfig,
smart_crush_tool_output,
)
class TestCompressionStore:
"""Test CompressionStore functionality."""
@pytest.fixture(autouse=True)
def reset_store(self):
"""Reset global store before each test."""
reset_compression_store()
yield
reset_compression_store()
def test_store_and_retrieve(self):
"""Basic store and retrieve flow."""
store = CompressionStore()
original = json.dumps([{"id": i} for i in range(100)])
compressed = json.dumps([{"id": i} for i in range(10)])
hash_key = store.store(
original=original,
compressed=compressed,
original_tokens=1000,
compressed_tokens=100,
original_item_count=100,
compressed_item_count=10,
)
assert (
len(hash_key) == 24
) # SHA256 truncated to 24 chars (96 bits for collision resistance)
feat: Add CCR architecture, TOIN telemetry, and DevEx improvements ## Core Features ### Compress-Cache-Retrieve (CCR) Architecture - Implement reversible compression with automatic retrieval support - Add CompressionStore for caching original content with TTL-based eviction - Add CompressionFeedback for learning from retrieval patterns - Implement tool injection for LLM retrieval capability - Add MCP server support for CCR operations - Track retrieval rates to dynamically adjust compression aggressiveness ### Tool Output Intelligence Network (TOIN) - Implement cross-session pattern learning for tool compression - Add ToolSignature for structural hashing of tool outputs - Track compression success rates per strategy (top_n, sample, truncate, etc.) - Implement privacy-preserving telemetry with SHA256 hashing - Add persistent storage with JSON file backend - Support network-effect learning across tool types ### SmartCrusher Enhancements - Add crushability analysis with variance/uniqueness detection - Implement statistical anomaly detection for outlier preservation - Add relevance-based item prioritization using BM25 scoring - Support multiple compression strategies with quality retention - Add change point detection for time-series data - Implement constant factoring for homogeneous datasets ## Developer Experience Improvements ### Exception Hierarchy - Add HeadroomError base class for all custom exceptions - Add specific exceptions: ConfigurationError, ProviderError, StorageError, CompressionError, TokenizationError, CacheError, ValidationError, TransformError ### Client Enhancements - Add validate_setup() for configuration verification - Add get_stats() for in-memory session metrics without DB query - Track session statistics (requests, tokens saved, cache hits) ### Logging Infrastructure - Add structured logging to TransformPipeline with token savings - Add logging to RollingWindow for dropped message tracking - Add logging to ToolCrusher for compression events - Add logging to CacheAligner for cache hit/miss detection - Add logging to SmartCrusher for strategy selection ## Bug Fixes (from deep analysis) ### Critical Fixes - Fix eviction heap memory leak with stale entry tracking - Fix hash collision detection in compression store - Fix strategy truncation desync in TOIN - Fix non-deterministic set truncation with sorted iteration - Fix race conditions in lazy initialization with proper locking - Fix user count double-counting in TOIN metrics ### High Priority Fixes - Fix unbounded strategy_success_rates growth with LRU eviction - Fix mutable pattern references with defensive copying - Fix lock held during file I/O with copy-then-write pattern - Fix state divergence on eviction with success event recording - Fix TOIN skip check order for CPU efficiency - Fix preserve_fields type mismatch (set vs list) - Fix prioritize_indices exceeding max_items limit - Fix instance ID collision risk (32-bit to 64-bit hash) ## Testing - Add comprehensive test suites for CCR, TOIN, and telemetry - Add crushability detection tests - Add quality retention tests for compression - Add integration tests for cross-component data flow - All 902 tests passing
2026-01-10 10:12:13 -08:00
entry = store.retrieve(hash_key)
assert entry is not None
assert entry.original_content == original
assert entry.compressed_content == compressed
assert entry.original_tokens == 1000
assert entry.compressed_tokens == 100
def test_retrieve_nonexistent(self):
"""Retrieve returns None for nonexistent hash."""
store = CompressionStore()
entry = store.retrieve("nonexistent1234")
assert entry is None
def test_ttl_expiration(self):
"""Entries expire after TTL."""
store = CompressionStore(default_ttl=1) # 1 second TTL
hash_key = store.store(
original="[1,2,3]",
compressed="[1]",
ttl=1,
)
# Should exist immediately
assert store.exists(hash_key)
# Wait for expiration
time.sleep(1.1)
# Should be expired
assert not store.exists(hash_key)
entry = store.retrieve(hash_key)
assert entry is None
def test_eviction_at_capacity(self):
"""Oldest entries evicted when at capacity."""
store = CompressionStore(max_entries=3)
hashes = []
for i in range(5):
h = store.store(
original=f"original_{i}",
compressed=f"compressed_{i}",
)
hashes.append(h)
time.sleep(0.01) # Ensure different timestamps
# Only last 3 should exist
assert not store.exists(hashes[0])
assert not store.exists(hashes[1])
assert store.exists(hashes[2])
assert store.exists(hashes[3])
assert store.exists(hashes[4])
def test_retrieval_tracking(self):
"""Retrieval events are tracked for feedback."""
store = CompressionStore(enable_feedback=True)
hash_key = store.store(
original="[1,2,3]",
compressed="[1]",
tool_name="test_tool",
)
# Retrieve multiple times
store.retrieve(hash_key)
store.retrieve(hash_key, query="test query")
events = store.get_retrieval_events(limit=10)
assert len(events) >= 2
fix(ccr): make headroom_retrieve a hash-only full-content lookup (#1532) The optional `query` parameter on headroom_retrieve routed retrieval through CompressionStore.search(), which BM25-scored the items inside a single cached blob and dropped everything below a 0.3 relevance floor. On small per-blob corpora with conversational queries this returned an empty result the large majority of the time, so the LLM saw "nothing found" for content that was actually present — pushing users to turn compression off entirely. Retrieval is fundamentally a hash lookup (this already matches the Rust proxy's CCR store, which is put/get only — "no BM25 search"). Remove the query/search path end to end and always return the full original content: Core (Python proxy): - tool schemas (anthropic/openai/google) drop the `query` property - parse_tool_call returns the hash (str | None) instead of (hash, query) - response handler, proxy POST/GET/tool-call handlers, the MCP retrieve tool, and the streaming feedback recorders retrieve by hash only - proactive context-tracker expansion always restores full content - delete CompressionStore.search() and its BM25 machinery (the bm25 module stays — it is still used by relevance/) - CCRToolCall.query, CCRToolResult.was_search, and ExpansionRecommendation.expand_full/search_query are removed Plugins (advertised a now-defunct query param to the LLM): - hermes (Python), openclaw + opencode (TypeScript) retrieve tools drop `query` from their schemas, signatures, request URLs, and tests Benchmarks/docs: - ccr_regression + adversarial benchmarks switch from store.search() to full hash retrieval (search input-injection tests repurposed to the hash, the only remaining input surface) - wiki/ARCHITECTURE.md, wiki/ccr.md, docs/content/docs/ccr.mdx, config.py and store docstrings updated to describe hash-only retrieval Tests updated to assert full-content retrieval and guard the removed surface; the full CCR/proxy/store/TOIN suite passes. ruff + mypy clean. ## Description <!-- Briefly explain the change and why it is needed. --> Closes # ## Type of Change - [ ] Bug fix (non-breaking change that fixes an issue) - [ ] New feature (non-breaking change that adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ ] Documentation update - [ ] Performance improvement - [ ] Code refactoring (no functional changes) ## Changes Made - ## Testing <!-- Check what you actually ran, then paste the real command output below. --> - [ ] Unit tests pass (`pytest`) - [ ] Linting passes (`ruff check .`) - [ ] Type checking passes (`mypy headroom`) - [ ] New tests added for new functionality - [ ] Manual testing performed ### Test Output ```text # Paste relevant command output or artifact links here ``` ## Real Behavior Proof - Environment: - Exact command / steps: - Observed result: - Not tested: ## Review Readiness - [ ] I have performed a self-review - [ ] This PR is ready for human review ## Checklist - [ ] My code follows the project's style guidelines - [ ] I have performed a self-review of my code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] I have updated the CHANGELOG.md if applicable ## Screenshots (if applicable) Add screenshots to help explain your changes. ## Additional Notes <!-- Mention any N/A checklist items, tradeoffs, follow-ups, or maintainer context. -->
2026-06-28 10:32:43 -07:00
# Check event details — retrieval is always full
feat: Add CCR architecture, TOIN telemetry, and DevEx improvements ## Core Features ### Compress-Cache-Retrieve (CCR) Architecture - Implement reversible compression with automatic retrieval support - Add CompressionStore for caching original content with TTL-based eviction - Add CompressionFeedback for learning from retrieval patterns - Implement tool injection for LLM retrieval capability - Add MCP server support for CCR operations - Track retrieval rates to dynamically adjust compression aggressiveness ### Tool Output Intelligence Network (TOIN) - Implement cross-session pattern learning for tool compression - Add ToolSignature for structural hashing of tool outputs - Track compression success rates per strategy (top_n, sample, truncate, etc.) - Implement privacy-preserving telemetry with SHA256 hashing - Add persistent storage with JSON file backend - Support network-effect learning across tool types ### SmartCrusher Enhancements - Add crushability analysis with variance/uniqueness detection - Implement statistical anomaly detection for outlier preservation - Add relevance-based item prioritization using BM25 scoring - Support multiple compression strategies with quality retention - Add change point detection for time-series data - Implement constant factoring for homogeneous datasets ## Developer Experience Improvements ### Exception Hierarchy - Add HeadroomError base class for all custom exceptions - Add specific exceptions: ConfigurationError, ProviderError, StorageError, CompressionError, TokenizationError, CacheError, ValidationError, TransformError ### Client Enhancements - Add validate_setup() for configuration verification - Add get_stats() for in-memory session metrics without DB query - Track session statistics (requests, tokens saved, cache hits) ### Logging Infrastructure - Add structured logging to TransformPipeline with token savings - Add logging to RollingWindow for dropped message tracking - Add logging to ToolCrusher for compression events - Add logging to CacheAligner for cache hit/miss detection - Add logging to SmartCrusher for strategy selection ## Bug Fixes (from deep analysis) ### Critical Fixes - Fix eviction heap memory leak with stale entry tracking - Fix hash collision detection in compression store - Fix strategy truncation desync in TOIN - Fix non-deterministic set truncation with sorted iteration - Fix race conditions in lazy initialization with proper locking - Fix user count double-counting in TOIN metrics ### High Priority Fixes - Fix unbounded strategy_success_rates growth with LRU eviction - Fix mutable pattern references with defensive copying - Fix lock held during file I/O with copy-then-write pattern - Fix state divergence on eviction with success event recording - Fix TOIN skip check order for CPU efficiency - Fix preserve_fields type mismatch (set vs list) - Fix prioritize_indices exceeding max_items limit - Fix instance ID collision risk (32-bit to 64-bit hash) ## Testing - Add comprehensive test suites for CCR, TOIN, and telemetry - Add crushability detection tests - Add quality retention tests for compression - Add integration tests for cross-component data flow - All 902 tests passing
2026-01-10 10:12:13 -08:00
assert any(e.retrieval_type == "full" for e in events)
def test_access_tracking_on_entry(self):
"""Entry tracks access count and queries."""
store = CompressionStore()
hash_key = store.store(
original=json.dumps([{"id": i} for i in range(10)]),
compressed="[]",
)
# Access multiple times with queries
store.retrieve(hash_key, query="first query")
store.retrieve(hash_key, query="second query")
store.retrieve(hash_key, query="first query") # Duplicate
entry = store.retrieve(hash_key)
assert entry.retrieval_count >= 3
assert "first query" in entry.search_queries
assert "second query" in entry.search_queries
def test_stats(self):
"""Store statistics are accurate."""
store = CompressionStore()
store.store(
original="x" * 100,
compressed="x" * 10,
original_tokens=100,
compressed_tokens=10,
)
store.store(
original="y" * 200,
compressed="y" * 20,
original_tokens=200,
compressed_tokens=20,
)
stats = store.get_stats()
assert stats["entry_count"] == 2
assert stats["total_original_tokens"] == 300
assert stats["total_compressed_tokens"] == 30
def test_global_store_singleton(self):
"""Global store uses singleton pattern."""
reset_compression_store()
store1 = get_compression_store()
store2 = get_compression_store()
assert store1 is store2
def test_thread_safety(self):
"""Store is thread-safe."""
import threading
store = CompressionStore()
hashes = []
lock = threading.Lock()
def store_item(i):
h = store.store(
original=f"original_{i}",
compressed=f"compressed_{i}",
)
with lock:
hashes.append(h)
threads = [threading.Thread(target=store_item, args=(i,)) for i in range(10)]
for t in threads:
t.start()
for t in threads:
t.join()
assert len(hashes) == 10
for h in hashes:
assert store.exists(h)
class TestCCRConfig:
"""Test CCR configuration options."""
def test_default_config(self):
"""Default CCR config values."""
config = CCRConfig()
assert config.enabled is True
assert config.store_max_entries == 1000
feat: compression extraction — Rust knob exposure, CCR hardening, traffic audits (#818) ## Description A data-driven push for better compression savings without accuracy loss, in four parts: expose and tune the Rust compressor knobs, harden the CCR retrieval store, add traffic-audit tooling that sizes opportunities from real transcripts, and introduce **read maturation** — a new, live-validated mechanism that compresses Read outputs *before* they ever enter the provider prefix cache. ## Type of Change - [x] Bug fix (non-breaking change that fixes an issue) - [x] New feature (non-breaking change that adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ ] Documentation update - [x] Performance improvement - [ ] Code refactoring (no functional changes) ## Changes Made ### 1. Rust compressor extraction - Expose `lossless_min_savings_ratio` end-to-end and lower the default 0.30 → 0.15 (lockstep across Rust, PyO3, and both Python config classes) so the lossless Table/CSV compaction path wins more often. - Expose the `CompactConfig` heuristics (core-field fraction, heterogeneity ratio, flatten cap, bucket bounds) through PyO3 + Python. - `SearchCompressor` grouped-by-file output (`rg --heading` style — path once per file instead of per match). Library default off; the proxy enables it in token mode. - Complete `factor_out_constants`: constant fields now emit once in a `_constant_fields` sentinel with slim rows (defensive per-item value match; default off). - `ContentRouter` accepts a SmartCrusher config override and the search-grouping knob. ### 2. CCR store hardening - Session-scale TTL: 300s → 1800s (CCRConfig, CompressionEntry, CompressionStore, Rust `DEFAULT_TTL` — lockstep). - **SQLite is the default CCR backend** (`~/.headroom/ccr_store.db`, WAL): survives proxy restarts and is shared across workers. `HEADROOM_CCR_BACKEND=memory` opts out. - Multi-worker safety: `busy_timeout`, and corruption detection narrowed so transient `SQLITE_BUSY` errors can never trigger database deletion. - Data-at-rest hygiene: `chmod 600` on db + sidecars, expired rows swept at open. - Retrieval-miss messages are actionable (re-read the file / re-run the command). ### 3. Traffic audit tooling (measure before tuning) - `headroom audit-reads`: sizes Read opportunities from local Claude Code transcripts (read share, stale %, line-number overhead, context residency, cache-death windows). - `--simulate-maturation`: Mechanism B risk sizing (re-read rates, never-touched-again share, quiesce coverage, at-risk edits). - `--codex`: shell-read classifier for Codex transcripts (rtk-wrapper aware, workdir resolution). - Findings that shaped this PR (81 sessions): Reads are 67% of tool bytes; median Read lingers 118 turns (~13x lifetime cost); a prototyped repeat-Read dedup measured 0.1% and was **removed** rather than shipped as dead code. ### 4. Read maturation (Mechanism B) — experimental, default OFF - Activity-based: a fresh large Read is held **out** of the provider cache (trailing breakpoint relocated before it), stays verbatim while its file is active, and matures into a CCR-backed marker once the file is quiet for `quiesce_turns` (default 5; `max_hold_turns` bounds busy files). - Only the final compressed form ever enters the cache — **no cached byte is ever mutated**; matured markers replay byte-identically. - Wired into the Anthropic handler behind `--read-maturation` / `HEADROOM_READ_MATURATION=1`; session state rides on the prefix tracker; advisory (can never fail a request). - Live-validated against the Anthropic API: held content excluded from cache_creation; after maturation the prior cached prefix still served — the no-bust invariant holds end-to-end. ### 5. Rebase / CI fixups (this update) - Rebased onto latest `main` (was 28 commits behind): picks up `ci: pass CODECOV_TOKEN to coverage uploads (#968)`, which is what was turning the 4 test shards red — the tests themselves passed (1528) but the post-test codecov upload exited non-zero on a protected branch. - Resolved the duplicate `lossless_min_savings_ratio` that two independent main/branch additions left in `SmartCrusherConfig` and the Rust-config kwarg (import-time `SyntaxError` + mypy `no-redef`). - Aligned CCR tests with the new defaults (SQLite backend, 1800s TTL) across `test_ccr`, `test_adapter_hooks`, `test_compression_store`, `test_proxy_ccr`, and the lossy row-drop bridge test. ## Testing <!-- Check what you actually ran, then paste the real command output below. --> - [x] Unit tests pass (`pytest`) - [x] Linting passes (`ruff check .`) - [x] Type checking passes (`mypy headroom`) - [x] New tests added for new functionality - [ ] Manual testing performed ### Test Output ```text $ python -m pytest tests/test_proxy_ccr.py tests/test_ccr.py tests/test_compression_store.py tests/test_adapter_hooks.py tests/test_ccr_row_drop_store_bridge.py -q 170 passed, 4 warnings in 42.49s $ python -m pytest tests/test_audit_reads.py tests/test_audit_codex.py tests/test_read_maturation.py tests/test_transforms_content_router.py tests/test_smart_crusher_toin_attachment.py -q 83 passed $ mypy headroom/ Success: no issues found in 365 source files $ python -m compileall headroom/ -q COMPILE-OK # CI (run 27488990477, pre-rebase head): all 4 shards ran to completion — # "1528 passed, 120 skipped, 4922 deselected" # The red shards were the codecov upload step, not test failures; fixed by # the #968 rebase above. ``` ## Real Behavior Proof - Environment: macOS (darwin), Python 3.12 venv; branch `feat/compression-extraction` rebased onto `origin/main` (head 7cb0f43b); GitHub Actions CI run 27488990477 for the test shards - Exact command / steps: rebased onto latest main (clean, 13 commits replayed, 0 conflicts); ran the pytest suites and mypy above locally; inspected CI shard logs to confirm the failure was the codecov upload, not the test phase - Observed result: 253 targeted tests pass locally; mypy clean on 365 files; CI test phase reports `1528 passed, 120 skipped`; the only red step (codecov `upload-coverage` → "Token required because branch is protected") is resolved by the rebased-in #968 CODECOV_TOKEN fix - Not tested: the read-maturation live-API no-bust validation (`tests/test_live/`) was not re-run in this rebase pass (requires provider keys); it was validated when the feature first landed, and no maturation code changed in the rebase — only CCR-default test assertions and the duplicate-field resolution ## 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 - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] I have updated the CHANGELOG.md if applicable ## Additional Notes CHANGELOG is generated by release-please from the conventional commits, so the CHANGELOG box is intentionally left unchecked. "Manual testing performed" is unchecked deliberately — see `Real Behavior Proof` → `Not tested` for the exact boundary (the live-API maturation validation was not re-run in this rebase pass). ### Follow-ups (tracked, not in this PR) - Mechanism B provider extensions: OpenAI-family wiring (no breakpoint hold — bounded near-tail bust) and the Codex runtime read-detector (the audit classifier is the prototype). - Pilot enablement playbook: run `audit-reads --simulate-maturation` on target traffic → pick `quiesce_turns` → enable via env → watch cache hit rate + `read_maturation:N` transform tags.
2026-06-16 20:21:13 -07:00
assert config.store_ttl_seconds == 1800 # session-scale (was 300)
feat: Add CCR architecture, TOIN telemetry, and DevEx improvements ## Core Features ### Compress-Cache-Retrieve (CCR) Architecture - Implement reversible compression with automatic retrieval support - Add CompressionStore for caching original content with TTL-based eviction - Add CompressionFeedback for learning from retrieval patterns - Implement tool injection for LLM retrieval capability - Add MCP server support for CCR operations - Track retrieval rates to dynamically adjust compression aggressiveness ### Tool Output Intelligence Network (TOIN) - Implement cross-session pattern learning for tool compression - Add ToolSignature for structural hashing of tool outputs - Track compression success rates per strategy (top_n, sample, truncate, etc.) - Implement privacy-preserving telemetry with SHA256 hashing - Add persistent storage with JSON file backend - Support network-effect learning across tool types ### SmartCrusher Enhancements - Add crushability analysis with variance/uniqueness detection - Implement statistical anomaly detection for outlier preservation - Add relevance-based item prioritization using BM25 scoring - Support multiple compression strategies with quality retention - Add change point detection for time-series data - Implement constant factoring for homogeneous datasets ## Developer Experience Improvements ### Exception Hierarchy - Add HeadroomError base class for all custom exceptions - Add specific exceptions: ConfigurationError, ProviderError, StorageError, CompressionError, TokenizationError, CacheError, ValidationError, TransformError ### Client Enhancements - Add validate_setup() for configuration verification - Add get_stats() for in-memory session metrics without DB query - Track session statistics (requests, tokens saved, cache hits) ### Logging Infrastructure - Add structured logging to TransformPipeline with token savings - Add logging to RollingWindow for dropped message tracking - Add logging to ToolCrusher for compression events - Add logging to CacheAligner for cache hit/miss detection - Add logging to SmartCrusher for strategy selection ## Bug Fixes (from deep analysis) ### Critical Fixes - Fix eviction heap memory leak with stale entry tracking - Fix hash collision detection in compression store - Fix strategy truncation desync in TOIN - Fix non-deterministic set truncation with sorted iteration - Fix race conditions in lazy initialization with proper locking - Fix user count double-counting in TOIN metrics ### High Priority Fixes - Fix unbounded strategy_success_rates growth with LRU eviction - Fix mutable pattern references with defensive copying - Fix lock held during file I/O with copy-then-write pattern - Fix state divergence on eviction with success event recording - Fix TOIN skip check order for CPU efficiency - Fix preserve_fields type mismatch (set vs list) - Fix prioritize_indices exceeding max_items limit - Fix instance ID collision risk (32-bit to 64-bit hash) ## Testing - Add comprehensive test suites for CCR, TOIN, and telemetry - Add crushability detection tests - Add quality retention tests for compression - Add integration tests for cross-component data flow - All 902 tests passing
2026-01-10 10:12:13 -08:00
assert config.inject_retrieval_marker is True
assert config.feedback_enabled is True
assert config.min_items_to_cache == 20
class TestCCRFeedbackLoop:
"""Test CCR feedback tracking for learning."""
@pytest.fixture(autouse=True)
def reset_store(self):
"""Reset global store before each test."""
reset_compression_store()
yield
reset_compression_store()
def test_retrieval_events_logged(self):
"""Retrieval events are logged for feedback."""
store = CompressionStore(enable_feedback=True)
items = [{"id": i, "data": f"item_{i}"} for i in range(50)]
hash_key = store.store(
original=json.dumps(items),
compressed=json.dumps(items[:10]),
original_item_count=50,
compressed_item_count=10,
tool_name="search_api",
)
# Simulate retrievals
store.retrieve(hash_key)
fix(ccr): make headroom_retrieve a hash-only full-content lookup (#1532) The optional `query` parameter on headroom_retrieve routed retrieval through CompressionStore.search(), which BM25-scored the items inside a single cached blob and dropped everything below a 0.3 relevance floor. On small per-blob corpora with conversational queries this returned an empty result the large majority of the time, so the LLM saw "nothing found" for content that was actually present — pushing users to turn compression off entirely. Retrieval is fundamentally a hash lookup (this already matches the Rust proxy's CCR store, which is put/get only — "no BM25 search"). Remove the query/search path end to end and always return the full original content: Core (Python proxy): - tool schemas (anthropic/openai/google) drop the `query` property - parse_tool_call returns the hash (str | None) instead of (hash, query) - response handler, proxy POST/GET/tool-call handlers, the MCP retrieve tool, and the streaming feedback recorders retrieve by hash only - proactive context-tracker expansion always restores full content - delete CompressionStore.search() and its BM25 machinery (the bm25 module stays — it is still used by relevance/) - CCRToolCall.query, CCRToolResult.was_search, and ExpansionRecommendation.expand_full/search_query are removed Plugins (advertised a now-defunct query param to the LLM): - hermes (Python), openclaw + opencode (TypeScript) retrieve tools drop `query` from their schemas, signatures, request URLs, and tests Benchmarks/docs: - ccr_regression + adversarial benchmarks switch from store.search() to full hash retrieval (search input-injection tests repurposed to the hash, the only remaining input surface) - wiki/ARCHITECTURE.md, wiki/ccr.md, docs/content/docs/ccr.mdx, config.py and store docstrings updated to describe hash-only retrieval Tests updated to assert full-content retrieval and guard the removed surface; the full CCR/proxy/store/TOIN suite passes. ruff + mypy clean. ## Description <!-- Briefly explain the change and why it is needed. --> Closes # ## Type of Change - [ ] Bug fix (non-breaking change that fixes an issue) - [ ] New feature (non-breaking change that adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ ] Documentation update - [ ] Performance improvement - [ ] Code refactoring (no functional changes) ## Changes Made - ## Testing <!-- Check what you actually ran, then paste the real command output below. --> - [ ] Unit tests pass (`pytest`) - [ ] Linting passes (`ruff check .`) - [ ] Type checking passes (`mypy headroom`) - [ ] New tests added for new functionality - [ ] Manual testing performed ### Test Output ```text # Paste relevant command output or artifact links here ``` ## Real Behavior Proof - Environment: - Exact command / steps: - Observed result: - Not tested: ## Review Readiness - [ ] I have performed a self-review - [ ] This PR is ready for human review ## Checklist - [ ] My code follows the project's style guidelines - [ ] I have performed a self-review of my code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] I have updated the CHANGELOG.md if applicable ## Screenshots (if applicable) Add screenshots to help explain your changes. ## Additional Notes <!-- Mention any N/A checklist items, tradeoffs, follow-ups, or maintainer context. -->
2026-06-28 10:32:43 -07:00
store.retrieve(hash_key)
store.retrieve(hash_key)
feat: Add CCR architecture, TOIN telemetry, and DevEx improvements ## Core Features ### Compress-Cache-Retrieve (CCR) Architecture - Implement reversible compression with automatic retrieval support - Add CompressionStore for caching original content with TTL-based eviction - Add CompressionFeedback for learning from retrieval patterns - Implement tool injection for LLM retrieval capability - Add MCP server support for CCR operations - Track retrieval rates to dynamically adjust compression aggressiveness ### Tool Output Intelligence Network (TOIN) - Implement cross-session pattern learning for tool compression - Add ToolSignature for structural hashing of tool outputs - Track compression success rates per strategy (top_n, sample, truncate, etc.) - Implement privacy-preserving telemetry with SHA256 hashing - Add persistent storage with JSON file backend - Support network-effect learning across tool types ### SmartCrusher Enhancements - Add crushability analysis with variance/uniqueness detection - Implement statistical anomaly detection for outlier preservation - Add relevance-based item prioritization using BM25 scoring - Support multiple compression strategies with quality retention - Add change point detection for time-series data - Implement constant factoring for homogeneous datasets ## Developer Experience Improvements ### Exception Hierarchy - Add HeadroomError base class for all custom exceptions - Add specific exceptions: ConfigurationError, ProviderError, StorageError, CompressionError, TokenizationError, CacheError, ValidationError, TransformError ### Client Enhancements - Add validate_setup() for configuration verification - Add get_stats() for in-memory session metrics without DB query - Track session statistics (requests, tokens saved, cache hits) ### Logging Infrastructure - Add structured logging to TransformPipeline with token savings - Add logging to RollingWindow for dropped message tracking - Add logging to ToolCrusher for compression events - Add logging to CacheAligner for cache hit/miss detection - Add logging to SmartCrusher for strategy selection ## Bug Fixes (from deep analysis) ### Critical Fixes - Fix eviction heap memory leak with stale entry tracking - Fix hash collision detection in compression store - Fix strategy truncation desync in TOIN - Fix non-deterministic set truncation with sorted iteration - Fix race conditions in lazy initialization with proper locking - Fix user count double-counting in TOIN metrics ### High Priority Fixes - Fix unbounded strategy_success_rates growth with LRU eviction - Fix mutable pattern references with defensive copying - Fix lock held during file I/O with copy-then-write pattern - Fix state divergence on eviction with success event recording - Fix TOIN skip check order for CPU efficiency - Fix preserve_fields type mismatch (set vs list) - Fix prioritize_indices exceeding max_items limit - Fix instance ID collision risk (32-bit to 64-bit hash) ## Testing - Add comprehensive test suites for CCR, TOIN, and telemetry - Add crushability detection tests - Add quality retention tests for compression - Add integration tests for cross-component data flow - All 902 tests passing
2026-01-10 10:12:13 -08:00
events = store.get_retrieval_events(limit=10)
# Should have logged all retrievals
assert len(events) >= 3
fix(ccr): make headroom_retrieve a hash-only full-content lookup (#1532) The optional `query` parameter on headroom_retrieve routed retrieval through CompressionStore.search(), which BM25-scored the items inside a single cached blob and dropped everything below a 0.3 relevance floor. On small per-blob corpora with conversational queries this returned an empty result the large majority of the time, so the LLM saw "nothing found" for content that was actually present — pushing users to turn compression off entirely. Retrieval is fundamentally a hash lookup (this already matches the Rust proxy's CCR store, which is put/get only — "no BM25 search"). Remove the query/search path end to end and always return the full original content: Core (Python proxy): - tool schemas (anthropic/openai/google) drop the `query` property - parse_tool_call returns the hash (str | None) instead of (hash, query) - response handler, proxy POST/GET/tool-call handlers, the MCP retrieve tool, and the streaming feedback recorders retrieve by hash only - proactive context-tracker expansion always restores full content - delete CompressionStore.search() and its BM25 machinery (the bm25 module stays — it is still used by relevance/) - CCRToolCall.query, CCRToolResult.was_search, and ExpansionRecommendation.expand_full/search_query are removed Plugins (advertised a now-defunct query param to the LLM): - hermes (Python), openclaw + opencode (TypeScript) retrieve tools drop `query` from their schemas, signatures, request URLs, and tests Benchmarks/docs: - ccr_regression + adversarial benchmarks switch from store.search() to full hash retrieval (search input-injection tests repurposed to the hash, the only remaining input surface) - wiki/ARCHITECTURE.md, wiki/ccr.md, docs/content/docs/ccr.mdx, config.py and store docstrings updated to describe hash-only retrieval Tests updated to assert full-content retrieval and guard the removed surface; the full CCR/proxy/store/TOIN suite passes. ruff + mypy clean. ## Description <!-- Briefly explain the change and why it is needed. --> Closes # ## Type of Change - [ ] Bug fix (non-breaking change that fixes an issue) - [ ] New feature (non-breaking change that adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ ] Documentation update - [ ] Performance improvement - [ ] Code refactoring (no functional changes) ## Changes Made - ## Testing <!-- Check what you actually ran, then paste the real command output below. --> - [ ] Unit tests pass (`pytest`) - [ ] Linting passes (`ruff check .`) - [ ] Type checking passes (`mypy headroom`) - [ ] New tests added for new functionality - [ ] Manual testing performed ### Test Output ```text # Paste relevant command output or artifact links here ``` ## Real Behavior Proof - Environment: - Exact command / steps: - Observed result: - Not tested: ## Review Readiness - [ ] I have performed a self-review - [ ] This PR is ready for human review ## Checklist - [ ] My code follows the project's style guidelines - [ ] I have performed a self-review of my code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] I have updated the CHANGELOG.md if applicable ## Screenshots (if applicable) Add screenshots to help explain your changes. ## Additional Notes <!-- Mention any N/A checklist items, tradeoffs, follow-ups, or maintainer context. -->
2026-06-28 10:32:43 -07:00
# Check event types — retrieval is always full
feat: Add CCR architecture, TOIN telemetry, and DevEx improvements ## Core Features ### Compress-Cache-Retrieve (CCR) Architecture - Implement reversible compression with automatic retrieval support - Add CompressionStore for caching original content with TTL-based eviction - Add CompressionFeedback for learning from retrieval patterns - Implement tool injection for LLM retrieval capability - Add MCP server support for CCR operations - Track retrieval rates to dynamically adjust compression aggressiveness ### Tool Output Intelligence Network (TOIN) - Implement cross-session pattern learning for tool compression - Add ToolSignature for structural hashing of tool outputs - Track compression success rates per strategy (top_n, sample, truncate, etc.) - Implement privacy-preserving telemetry with SHA256 hashing - Add persistent storage with JSON file backend - Support network-effect learning across tool types ### SmartCrusher Enhancements - Add crushability analysis with variance/uniqueness detection - Implement statistical anomaly detection for outlier preservation - Add relevance-based item prioritization using BM25 scoring - Support multiple compression strategies with quality retention - Add change point detection for time-series data - Implement constant factoring for homogeneous datasets ## Developer Experience Improvements ### Exception Hierarchy - Add HeadroomError base class for all custom exceptions - Add specific exceptions: ConfigurationError, ProviderError, StorageError, CompressionError, TokenizationError, CacheError, ValidationError, TransformError ### Client Enhancements - Add validate_setup() for configuration verification - Add get_stats() for in-memory session metrics without DB query - Track session statistics (requests, tokens saved, cache hits) ### Logging Infrastructure - Add structured logging to TransformPipeline with token savings - Add logging to RollingWindow for dropped message tracking - Add logging to ToolCrusher for compression events - Add logging to CacheAligner for cache hit/miss detection - Add logging to SmartCrusher for strategy selection ## Bug Fixes (from deep analysis) ### Critical Fixes - Fix eviction heap memory leak with stale entry tracking - Fix hash collision detection in compression store - Fix strategy truncation desync in TOIN - Fix non-deterministic set truncation with sorted iteration - Fix race conditions in lazy initialization with proper locking - Fix user count double-counting in TOIN metrics ### High Priority Fixes - Fix unbounded strategy_success_rates growth with LRU eviction - Fix mutable pattern references with defensive copying - Fix lock held during file I/O with copy-then-write pattern - Fix state divergence on eviction with success event recording - Fix TOIN skip check order for CPU efficiency - Fix preserve_fields type mismatch (set vs list) - Fix prioritize_indices exceeding max_items limit - Fix instance ID collision risk (32-bit to 64-bit hash) ## Testing - Add comprehensive test suites for CCR, TOIN, and telemetry - Add crushability detection tests - Add quality retention tests for compression - Add integration tests for cross-component data flow - All 902 tests passing
2026-01-10 10:12:13 -08:00
full_events = [e for e in events if e.retrieval_type == "full"]
fix(ccr): make headroom_retrieve a hash-only full-content lookup (#1532) The optional `query` parameter on headroom_retrieve routed retrieval through CompressionStore.search(), which BM25-scored the items inside a single cached blob and dropped everything below a 0.3 relevance floor. On small per-blob corpora with conversational queries this returned an empty result the large majority of the time, so the LLM saw "nothing found" for content that was actually present — pushing users to turn compression off entirely. Retrieval is fundamentally a hash lookup (this already matches the Rust proxy's CCR store, which is put/get only — "no BM25 search"). Remove the query/search path end to end and always return the full original content: Core (Python proxy): - tool schemas (anthropic/openai/google) drop the `query` property - parse_tool_call returns the hash (str | None) instead of (hash, query) - response handler, proxy POST/GET/tool-call handlers, the MCP retrieve tool, and the streaming feedback recorders retrieve by hash only - proactive context-tracker expansion always restores full content - delete CompressionStore.search() and its BM25 machinery (the bm25 module stays — it is still used by relevance/) - CCRToolCall.query, CCRToolResult.was_search, and ExpansionRecommendation.expand_full/search_query are removed Plugins (advertised a now-defunct query param to the LLM): - hermes (Python), openclaw + opencode (TypeScript) retrieve tools drop `query` from their schemas, signatures, request URLs, and tests Benchmarks/docs: - ccr_regression + adversarial benchmarks switch from store.search() to full hash retrieval (search input-injection tests repurposed to the hash, the only remaining input surface) - wiki/ARCHITECTURE.md, wiki/ccr.md, docs/content/docs/ccr.mdx, config.py and store docstrings updated to describe hash-only retrieval Tests updated to assert full-content retrieval and guard the removed surface; the full CCR/proxy/store/TOIN suite passes. ruff + mypy clean. ## Description <!-- Briefly explain the change and why it is needed. --> Closes # ## Type of Change - [ ] Bug fix (non-breaking change that fixes an issue) - [ ] New feature (non-breaking change that adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ ] Documentation update - [ ] Performance improvement - [ ] Code refactoring (no functional changes) ## Changes Made - ## Testing <!-- Check what you actually ran, then paste the real command output below. --> - [ ] Unit tests pass (`pytest`) - [ ] Linting passes (`ruff check .`) - [ ] Type checking passes (`mypy headroom`) - [ ] New tests added for new functionality - [ ] Manual testing performed ### Test Output ```text # Paste relevant command output or artifact links here ``` ## Real Behavior Proof - Environment: - Exact command / steps: - Observed result: - Not tested: ## Review Readiness - [ ] I have performed a self-review - [ ] This PR is ready for human review ## Checklist - [ ] My code follows the project's style guidelines - [ ] I have performed a self-review of my code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] I have updated the CHANGELOG.md if applicable ## Screenshots (if applicable) Add screenshots to help explain your changes. ## Additional Notes <!-- Mention any N/A checklist items, tradeoffs, follow-ups, or maintainer context. -->
2026-06-28 10:32:43 -07:00
assert len(full_events) >= 3
feat: Add CCR architecture, TOIN telemetry, and DevEx improvements ## Core Features ### Compress-Cache-Retrieve (CCR) Architecture - Implement reversible compression with automatic retrieval support - Add CompressionStore for caching original content with TTL-based eviction - Add CompressionFeedback for learning from retrieval patterns - Implement tool injection for LLM retrieval capability - Add MCP server support for CCR operations - Track retrieval rates to dynamically adjust compression aggressiveness ### Tool Output Intelligence Network (TOIN) - Implement cross-session pattern learning for tool compression - Add ToolSignature for structural hashing of tool outputs - Track compression success rates per strategy (top_n, sample, truncate, etc.) - Implement privacy-preserving telemetry with SHA256 hashing - Add persistent storage with JSON file backend - Support network-effect learning across tool types ### SmartCrusher Enhancements - Add crushability analysis with variance/uniqueness detection - Implement statistical anomaly detection for outlier preservation - Add relevance-based item prioritization using BM25 scoring - Support multiple compression strategies with quality retention - Add change point detection for time-series data - Implement constant factoring for homogeneous datasets ## Developer Experience Improvements ### Exception Hierarchy - Add HeadroomError base class for all custom exceptions - Add specific exceptions: ConfigurationError, ProviderError, StorageError, CompressionError, TokenizationError, CacheError, ValidationError, TransformError ### Client Enhancements - Add validate_setup() for configuration verification - Add get_stats() for in-memory session metrics without DB query - Track session statistics (requests, tokens saved, cache hits) ### Logging Infrastructure - Add structured logging to TransformPipeline with token savings - Add logging to RollingWindow for dropped message tracking - Add logging to ToolCrusher for compression events - Add logging to CacheAligner for cache hit/miss detection - Add logging to SmartCrusher for strategy selection ## Bug Fixes (from deep analysis) ### Critical Fixes - Fix eviction heap memory leak with stale entry tracking - Fix hash collision detection in compression store - Fix strategy truncation desync in TOIN - Fix non-deterministic set truncation with sorted iteration - Fix race conditions in lazy initialization with proper locking - Fix user count double-counting in TOIN metrics ### High Priority Fixes - Fix unbounded strategy_success_rates growth with LRU eviction - Fix mutable pattern references with defensive copying - Fix lock held during file I/O with copy-then-write pattern - Fix state divergence on eviction with success event recording - Fix TOIN skip check order for CPU efficiency - Fix preserve_fields type mismatch (set vs list) - Fix prioritize_indices exceeding max_items limit - Fix instance ID collision risk (32-bit to 64-bit hash) ## Testing - Add comprehensive test suites for CCR, TOIN, and telemetry - Add crushability detection tests - Add quality retention tests for compression - Add integration tests for cross-component data flow - All 902 tests passing
2026-01-10 10:12:13 -08:00
def test_tool_name_in_events(self):
"""Tool name is preserved in retrieval events."""
store = CompressionStore(enable_feedback=True)
hash_key = store.store(
original="[1,2,3]",
compressed="[1]",
tool_name="github_search",
)
store.retrieve(hash_key)
events = store.get_retrieval_events(tool_name="github_search")
assert len(events) >= 1
assert all(e.tool_name == "github_search" for e in events)
def test_event_filtering_by_tool(self):
"""Events can be filtered by tool name."""
store = CompressionStore(enable_feedback=True)
hash1 = store.store(
original="[1]",
compressed="[1]",
tool_name="tool_a",
)
hash2 = store.store(
original="[2]",
compressed="[2]",
tool_name="tool_b",
)
store.retrieve(hash1)
store.retrieve(hash1)
store.retrieve(hash2)
tool_a_events = store.get_retrieval_events(tool_name="tool_a")
tool_b_events = store.get_retrieval_events(tool_name="tool_b")
assert len(tool_a_events) == 2
assert len(tool_b_events) == 1
class TestCCREdgeCases:
"""Test edge cases and error handling."""
@pytest.fixture(autouse=True)
def reset_store(self):
"""Reset global store before each test."""
reset_compression_store()
yield
reset_compression_store()
def test_ccr_disabled_no_caching(self):
"""When CCR disabled, no caching occurs."""
reset_compression_store()
items = [{"id": i, "score": 100 - i} for i in range(100)]
feat: Add CCR architecture, TOIN telemetry, and DevEx improvements ## Core Features ### Compress-Cache-Retrieve (CCR) Architecture - Implement reversible compression with automatic retrieval support - Add CompressionStore for caching original content with TTL-based eviction - Add CompressionFeedback for learning from retrieval patterns - Implement tool injection for LLM retrieval capability - Add MCP server support for CCR operations - Track retrieval rates to dynamically adjust compression aggressiveness ### Tool Output Intelligence Network (TOIN) - Implement cross-session pattern learning for tool compression - Add ToolSignature for structural hashing of tool outputs - Track compression success rates per strategy (top_n, sample, truncate, etc.) - Implement privacy-preserving telemetry with SHA256 hashing - Add persistent storage with JSON file backend - Support network-effect learning across tool types ### SmartCrusher Enhancements - Add crushability analysis with variance/uniqueness detection - Implement statistical anomaly detection for outlier preservation - Add relevance-based item prioritization using BM25 scoring - Support multiple compression strategies with quality retention - Add change point detection for time-series data - Implement constant factoring for homogeneous datasets ## Developer Experience Improvements ### Exception Hierarchy - Add HeadroomError base class for all custom exceptions - Add specific exceptions: ConfigurationError, ProviderError, StorageError, CompressionError, TokenizationError, CacheError, ValidationError, TransformError ### Client Enhancements - Add validate_setup() for configuration verification - Add get_stats() for in-memory session metrics without DB query - Track session statistics (requests, tokens saved, cache hits) ### Logging Infrastructure - Add structured logging to TransformPipeline with token savings - Add logging to RollingWindow for dropped message tracking - Add logging to ToolCrusher for compression events - Add logging to CacheAligner for cache hit/miss detection - Add logging to SmartCrusher for strategy selection ## Bug Fixes (from deep analysis) ### Critical Fixes - Fix eviction heap memory leak with stale entry tracking - Fix hash collision detection in compression store - Fix strategy truncation desync in TOIN - Fix non-deterministic set truncation with sorted iteration - Fix race conditions in lazy initialization with proper locking - Fix user count double-counting in TOIN metrics ### High Priority Fixes - Fix unbounded strategy_success_rates growth with LRU eviction - Fix mutable pattern references with defensive copying - Fix lock held during file I/O with copy-then-write pattern - Fix state divergence on eviction with success event recording - Fix TOIN skip check order for CPU efficiency - Fix preserve_fields type mismatch (set vs list) - Fix prioritize_indices exceeding max_items limit - Fix instance ID collision risk (32-bit to 64-bit hash) ## Testing - Add comprehensive test suites for CCR, TOIN, and telemetry - Add crushability detection tests - Add quality retention tests for compression - Add integration tests for cross-component data flow - All 902 tests passing
2026-01-10 10:12:13 -08:00
content = json.dumps(items)
config = SmartCrusherConfig(max_items_after_crush=15)
ccr_config = CCRConfig(enabled=False) # Disabled
smart_crush_tool_output(content, config, ccr_config)
store = get_compression_store()
stats = store.get_stats()
assert stats["entry_count"] == 0
def test_concurrent_store_and_retrieve(self):
"""Concurrent operations don't corrupt data."""
import threading
store = CompressionStore()
errors = []
def store_and_retrieve(i):
try:
items = [{"id": j, "batch": i} for j in range(10)]
hash_key = store.store(
original=json.dumps(items),
compressed="[]",
tool_name=f"tool_{i}",
)
# Immediately retrieve
entry = store.retrieve(hash_key)
if entry is None:
errors.append(f"Entry {i} not found after store")
elif f'"batch": {i}' not in entry.original_content:
errors.append(f"Entry {i} has wrong content")
except Exception as e:
errors.append(str(e))
threads = [threading.Thread(target=store_and_retrieve, args=(i,)) for i in range(20)]
feat: Add CCR architecture, TOIN telemetry, and DevEx improvements ## Core Features ### Compress-Cache-Retrieve (CCR) Architecture - Implement reversible compression with automatic retrieval support - Add CompressionStore for caching original content with TTL-based eviction - Add CompressionFeedback for learning from retrieval patterns - Implement tool injection for LLM retrieval capability - Add MCP server support for CCR operations - Track retrieval rates to dynamically adjust compression aggressiveness ### Tool Output Intelligence Network (TOIN) - Implement cross-session pattern learning for tool compression - Add ToolSignature for structural hashing of tool outputs - Track compression success rates per strategy (top_n, sample, truncate, etc.) - Implement privacy-preserving telemetry with SHA256 hashing - Add persistent storage with JSON file backend - Support network-effect learning across tool types ### SmartCrusher Enhancements - Add crushability analysis with variance/uniqueness detection - Implement statistical anomaly detection for outlier preservation - Add relevance-based item prioritization using BM25 scoring - Support multiple compression strategies with quality retention - Add change point detection for time-series data - Implement constant factoring for homogeneous datasets ## Developer Experience Improvements ### Exception Hierarchy - Add HeadroomError base class for all custom exceptions - Add specific exceptions: ConfigurationError, ProviderError, StorageError, CompressionError, TokenizationError, CacheError, ValidationError, TransformError ### Client Enhancements - Add validate_setup() for configuration verification - Add get_stats() for in-memory session metrics without DB query - Track session statistics (requests, tokens saved, cache hits) ### Logging Infrastructure - Add structured logging to TransformPipeline with token savings - Add logging to RollingWindow for dropped message tracking - Add logging to ToolCrusher for compression events - Add logging to CacheAligner for cache hit/miss detection - Add logging to SmartCrusher for strategy selection ## Bug Fixes (from deep analysis) ### Critical Fixes - Fix eviction heap memory leak with stale entry tracking - Fix hash collision detection in compression store - Fix strategy truncation desync in TOIN - Fix non-deterministic set truncation with sorted iteration - Fix race conditions in lazy initialization with proper locking - Fix user count double-counting in TOIN metrics ### High Priority Fixes - Fix unbounded strategy_success_rates growth with LRU eviction - Fix mutable pattern references with defensive copying - Fix lock held during file I/O with copy-then-write pattern - Fix state divergence on eviction with success event recording - Fix TOIN skip check order for CPU efficiency - Fix preserve_fields type mismatch (set vs list) - Fix prioritize_indices exceeding max_items limit - Fix instance ID collision risk (32-bit to 64-bit hash) ## Testing - Add comprehensive test suites for CCR, TOIN, and telemetry - Add crushability detection tests - Add quality retention tests for compression - Add integration tests for cross-component data flow - All 902 tests passing
2026-01-10 10:12:13 -08:00
for t in threads:
t.start()
for t in threads:
t.join()
assert errors == [], f"Errors during concurrent operations: {errors}"