v0.16.0 — synthesis lifecycle, provenance, and the embedder-identity gate
Behavior change: embedder identity is now checked (#117, #138)
Attaching an embedder whose declared fingerprint/digest contradicts the
store's recorded identity now raises instead of silently accepting. Measured
motivation: cosine distance between two unrelated embedding spaces still
returns a plausible number (0.595 in the incident that drove this) — results
look fine and are wrong. set_embedder(..., allow_unverified_embedder=True)
is the documented escape hatch.
And the gate knows when the record itself is wrong. A real production
store carried a meta identity row claiming potion-base-2M / dim 64 while
holding 384-dim MiniLM vectors — a provably false record, stamped by an
incidental embed() long ago. 0.16.0 refuses to brick such databases: when
the recorded dimension contradicts the width of the vectors actually stored,
the row is treated as evidence of nothing — the engine attaches, warns loudly
naming both dimensions, and adopt_embedder_identity ships as the honest
repair path (derive the digest by re-embedding stored text; never assert it).
"Cannot verify" and "verified mismatch" are distinct states; collapsing them
was the bug.
Synthesis lifecycle (schema v43 → v46)
Typed synthesis columns, the synthesis_dependencies table, evidence-versioned
lifecycle state, and the rollup-impression ledger with outcome finalization.
Migrations are idempotent and were verified on a copy of a live 5,751-row
production store before any deploy (43 → 46 clean, integrity ok).
Diagnosability: a failing open names its stage (#146, #147)
Every SQL call in the constructor is stage-tagged; the migration runner
attaches the exact statement it choked on. A truncated-SQL error that
previously read database error: incomplete input — naming nothing — now
reads database error at <stage>: ....
Fixes
search_entitiesclamp panic whenlimit > 10_000- Source filters now genuinely filter: recall no longer returns assistant
turns undersource=user(behavior change for callers who depended on it) - Version declarations unified across all four manifests, with a test so the
wheel version can never again depend on which directory built it recall_candidate_captelemetry: the engine reports when a cap bounded a
result rather than silently narrowing it
Verification
Dogfooded before tagging: deployed to a live production store (5,751 rows),
verify-on-copy first, schema 43 → 46 via lazy migration, integrity ok, reads
and writes exercised through the MCP surface. Six consecutive full-suite CI
runs with the new instrumentation, zero anomalies. Clean-venv wheel
verification: 48 Python files, all gate markers present by content, 13/13
identity-gate tests against the installed artifact.
Co-developed by Claude and Codex working as adversarial reviewers of each
other's changes; the embedder-gate fix in this release was reshaped twice by
that review loop before it shipped.