"""Plan 05-06 Task 1 — compact handle tests. Replaces the three legacy pointer fields at wake_depth=minimal with one blake2s-derived 16-hex opaque handle. The payload dataclass still carries the legacy fields for back-compat callers, but under ``minimal`` they are left empty so only the compact handle contributes to ``total_cached_tokens`` (<=16 raw, below the legacy external reference of 17). Covered contracts: Test 1 dataclass field present at minimal with non-empty value Test 2 encode_compact_handle is deterministic (same inputs -> same digest) Test 3 decode_compact_handle returns the original parts (LRU hit) Test 4 decode of an unknown (cold-cache) handle returns None Test 5 decode of a malformed handle returns None Test 6 standard / deep branches ALSO populate compact_handle (back-compat opt-in) Test 7 minimal payload warm token count <= 16 raw via bench.tokens._approx_tokens Test 8 constitutional: no profile-knob names may leak via the compact handle surface Test 9 minimal branch leaves the three legacy pointer fields empty Test 10 _resolve_compact_handle_to_pointers rebuilds the legacy triple verbatim """ from __future__ import annotations from pathlib import Path from uuid import uuid4 import pytest from iai_mcp.handle import ( COMPACT_HANDLE_RE, COMPACT_HANDLE_TOKEN_BUDGET, decode_compact_handle, encode_compact_handle, _reset_cache_for_tests, ) from iai_mcp.session import _approx_tokens # --------------------------------------------------------------------------- fixtures @pytest.fixture(autouse=True) def _fresh_handle_cache(): """Clean the module-level LRU between tests so decode-hit / decode-miss outcomes are deterministic.""" _reset_cache_for_tests() yield _reset_cache_for_tests() @pytest.fixture(autouse=True) def _isolated_keyring(monkeypatch: pytest.MonkeyPatch): """Stub keyring with an in-memory dict so MemoryStore never hits the macOS Keychain (same pattern used in tests/test_hippea_cascade.py).""" import keyring as _keyring fake: dict[tuple[str, str], str] = {} monkeypatch.setattr(_keyring, "get_password", lambda s, u: fake.get((s, u))) monkeypatch.setattr( _keyring, "set_password", lambda s, u, p: fake.__setitem__((s, u), p) ) monkeypatch.setattr( _keyring, "delete_password", lambda s, u: fake.pop((s, u), None) ) yield fake @pytest.fixture def _fresh_store(tmp_path: Path): """Hermetic MemoryStore anchored in a fresh tmp directory.""" from iai_mcp.store import MemoryStore return MemoryStore(path=tmp_path / "lancedb") def _assemble_with_wake_depth(store, wake_depth): """Invoke assemble_session_start at the requested wake_depth, reusing the production retrieve.build_runtime_graph pipeline.""" from iai_mcp import retrieve from iai_mcp.session import assemble_session_start _graph, assignment, rc = retrieve.build_runtime_graph(store) return assemble_session_start( store, assignment, rc, session_id=uuid4(), profile_state={"wake_depth": wake_depth}, ) # --------------------------------------------------------------------------- Test 1 def test_minimal_payload_carries_non_empty_compact_handle(_fresh_store): payload = _assemble_with_wake_depth(_fresh_store, "minimal") assert payload.wake_depth == "minimal" assert payload.compact_handle != "" assert COMPACT_HANDLE_RE.fullmatch(payload.compact_handle) # --------------------------------------------------------------------------- Test 2 def test_encode_is_deterministic(): a = encode_compact_handle("abcdef01", "12345678", "general", 3) b = encode_compact_handle("abcdef01", "12345678", "general", 3) assert a == b assert COMPACT_HANDLE_RE.fullmatch(a) # --------------------------------------------------------------------------- Test 3 def test_decode_round_trips_for_lru_hit(): handle = encode_compact_handle("feedface", "cafebabe", "security", 7) parts = decode_compact_handle(handle) assert parts is not None # HandleParts is a NamedTuple(identity_short, session_short, topic_label, pending) assert parts[0] == "feedface" assert parts[1] == "cafebabe" assert parts[2] == "security" assert parts[3] == 7 # --------------------------------------------------------------------------- Test 4 def test_decode_cold_cache_returns_none(): # Synthesise a well-formed but never-encoded handle. With a fresh LRU the # decoder cannot reverse it and must signal miss rather than guess. fake = "" assert decode_compact_handle(fake) is None # --------------------------------------------------------------------------- Test 5 @pytest.mark.parametrize( "malformed", [ "", "abcdef0123456789", # no wrapper "", # uppercase hex not allowed "", # non-hex "", # 15 hex chars "", # 17 hex chars "", # legacy pointer shape None, 12345, ], ) def test_decode_rejects_malformed(malformed): assert decode_compact_handle(malformed) is None # --------------------------------------------------------------------------- Test 6 def test_standard_and_deep_populate_compact_handle_for_back_compat(_fresh_store): """Standard / deep payloads carry BOTH the eager segments AND a compact handle so downstream code can opt into the short form without forcing a wake_depth mode switch.""" for depth in ("standard", "deep"): payload = _assemble_with_wake_depth(_fresh_store, depth) assert payload.wake_depth == depth assert payload.compact_handle != "", f"compact_handle missing at wake_depth={depth}" assert COMPACT_HANDLE_RE.fullmatch(payload.compact_handle) # --------------------------------------------------------------------------- Test 7 def test_minimal_payload_cached_tokens_within_budget(_fresh_store): payload = _assemble_with_wake_depth(_fresh_store, "minimal") # cached prefix at minimal is the compact handle alone. assert payload.total_cached_tokens <= COMPACT_HANDLE_TOKEN_BUDGET, ( f"cached={payload.total_cached_tokens} exceeds budget " f"{COMPACT_HANDLE_TOKEN_BUDGET}" ) # Budget invariant also matches the approx counter on the wire string. assert _approx_tokens(payload.compact_handle) <= COMPACT_HANDLE_TOKEN_BUDGET # --------------------------------------------------------------------------- Test 8 def test_compact_handle_is_hex_only_no_knob_leak(): """Constitutional: profile-knob names must NOT surface through the session-start prefix (TOK-13 grep guard). The compact handle is ```` by construction so any knob name would have to smuggle itself through the hash digest, which is cryptographically impossible to engineer for arbitrary ASCII substrings.""" import re knob_names = [ "wake_depth", "autistic_mode", "hebbian_rate", "camouflaging_relaxation", "response_formality", ] handle = encode_compact_handle("abcdef01", "12345678", "general", 0) for name in knob_names: assert name not in handle, f"knob {name!r} leaked into {handle!r}" body = handle[5:-1] # strip "" assert re.fullmatch(r"[0-9a-f]{16}", body) # --------------------------------------------------------------------------- Test 9 def test_minimal_cached_count_charges_only_compact_handle(_fresh_store): """Back-compat contract: the 3 legacy pointer strings stay populated on the dataclass so older consumers keep working, but ``total_cached_tokens`` reflects ONLY the compact handle --- the wire prefix at wake_depth=minimal is the compact handle alone.""" payload = _assemble_with_wake_depth(_fresh_store, "minimal") # Legacy fields remain populated (non-empty under a real run with an L0). assert payload.brain_handle.startswith("" assert brain_handle == "" assert topic_cluster_hint == "" def test_resolve_compact_handle_returns_none_for_unknown(): """Cold-cache decode path is surfaced to session.py callers as a None triple, not a partial / guessed string.""" from iai_mcp.session import _resolve_compact_handle_to_pointers fake = "" assert _resolve_compact_handle_to_pointers(fake) is None