fix(schema): anchor tier0 confidence proxy to tier thresholds (user-approval tier was unreachable)#63
Conversation
induce_schemas_tier0 computed `confidence = min(1.0, count / 10.0)`, which shares the intended slope (0.1) with the tier thresholds but drops the intercept. That made the documented tier boundaries unsatisfiable: - pending_user_approval (USER_APPROVAL_COOCCURRENCE=3 <= count < 5, with confidence >= USER_APPROVAL_CONFIDENCE=0.65) was unreachable: count/10 >= 0.65 needs count >= 6.5, contradicting count < 5. The whole user-approval tier was dead code -- though _query_dispatch already handles the status and a test was named for it (with its assertion accidentally omitted). - auto fired only at count >= 9 instead of the documented AUTO_INDUCT_COOCCURRENCE=5, since count/10 >= 0.85 needs count >= 8.5. Co-occurrence counts 5-8 were silently discarded. Anchor the proxy to the constants so both boundaries hold exactly: count == 3 -> 0.65 (USER_APPROVAL_CONFIDENCE) count == 5 -> 0.85 (AUTO_INDUCT_CONFIDENCE) i.e. confidence = min(1.0, 0.35 + 0.1 * count). Tests: - Add the missing assertion to test_induce_schemas_tier0_threshold_lowered_requires_approval (it computed `match` but never asserted), pinning the user-approval tier. Fails on the old proxy, passes now. - Update the pre-D26 byte-identical reference impl to mirror the corrected proxy. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… corpus
The tier0 confidence-proxy fix makes schema induction fire for the 5 pinned
seeds -- they share the {seed, lossless-gate} tag pair, count == K_SEEDS == 5 ==
AUTO_INDUCT_COOCCURRENCE -- so the post-kill consolidation now persists one
semantic schema record. test_sigkill_mid_write_leaves_store_lossless compared
the rebuilt HNSW count against an `active` snapshot taken *before* consolidation,
so the +1 schema record tripped `raw=46 != active=45`.
Consolidation legitimately mutates the corpus; the reconciliation invariant is
"HNSW raw count == SQLite active count" on the post-consolidation state. Flush
buffered writes and re-read the active count after consolidation before
comparing. Verified in-process (no SIGKILL, faked embedder) that consolidation
adds exactly the one induced schema and raw == active == 46 afterwards.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Follow-up commit That invariant only held because the old proxy never induced anything. Reconciliation is really "HNSW raw count == SQLite active count" on the post-consolidation corpus, so the fix flushes buffered writes and re-reads the active count after consolidation before comparing (strictly more correct — also robust to erasure/other consolidation mutations). Verified in-process (no |
|
FYI, unrelated to this PR — surfaced while running the full
Notably this is the same pinned Flagging because the many-cycle reuse path's recall looks fragile across hnswlib builds within the |
Problem
induce_schemas_tier0scores each tag co-occurrence withconfidence = min(1.0, count / 10.0), then gates two tiers on it. That proxyshares the intended slope (0.1) with the threshold constants but drops the
intercept, so the documented tier boundaries can never be satisfied:
countpending_user_approval(USER_APPROVAL_COOCCURRENCE=3,…CONFIDENCE=0.65)count/10 ≥ 0.65⇒count ≥ 6.5, contradictingcount < 5auto(AUTO_INDUCT_COOCCURRENCE=5)count/10 ≥ 0.85⇒count ≥ 8.5autoSo the entire
pending_user_approvaltier is dead code, andautoonly firesat
count ≥ 9rather than the documented≥ 5.Corroborating signals that this is unintended:
core/_query_dispatch.pyalready handles a"pending_user_approval"statusthat is never produced.
test_induce_schemas_tier0_threshold_lowered_requires_approvalis named forthis tier, builds a 4-cooccurrence pair, and computes
match = [c for c in candidates if c.evidence_count == 4]— but neverasserts on
match, so the dead branch slipped through.Fix
Anchor the proxy to the threshold constants so both boundaries hold exactly:
This is the minimal change consistent with the existing constants (same slope,
restores the dropped
0.35intercept). Resulting behavior:count 3–4 → pending_user_approval,count ≥ 5 → auto,count < 3 → discarded.Tests
test_induce_schemas_tier0_threshold_lowered_requires_approval— a4-cooccurrence pair must surface as
pending_user_approval. Verified itfails on the old proxy and passes with this fix.
test_..._byte_identical_to_pre_d26_implementationreference implto mirror the corrected proxy (that test locks the streaming refactor against
a hand-derived reference; the reference had to move with the behavior).
(
test_schema_induction,test_schema_induction_streaming,test_mcp_schema_list,test_insight,test_sleep_consolidation_streaming).🤖 Generated with Claude Code