Skip to content

v0.10.0 — the Reliability release

Latest

Choose a tag to compare

@spranab spranab released this 17 Jul 18:53
9bbcd8e

Item 4 (Reliability) is complete: all 13 trace contracts implemented and release-blocking. This release was validated as a coordinated train — yantrikdb-server (2,118 tests) and yantrikdb-mcp (consumer-simulation gate + full suite) each built and tested the exact release rev before this tag existed. The mutual review is the product.

Durable idempotency (trace T07: repetition is not corroboration)

  • record(), record_text(), and record_batch() accept idempotency keys. Same key + identical payload = the ORIGINAL rid, zero writes — no stats advance, no certainty change. Same key + different payload = typed IdempotencyConflict carrying the existing rid. Claims are durable, immutable, and commit atomically with the write they guard.
  • Cross-surface digests: an identical payload under one key is the same write via record() or a batch item; record_text's digest excludes the engine-generated embedding, so embedder drift can never fake a conflict.

Anti-laundering chokepoint (trace T06)

  • source=inference cannot claim kind=fact/observation without raised confidence basis — enforced at every write surface: record, batch (atomic whole-batch refusal), record_with_rid at Origin admission, correct(metadata_merge), links-after-record. Admitted (replicated) applies are deliberately not re-gated: one chokepoint, at origin ingress.

Write-path hardening

  • Every writer now runs reserve → commit → publish: capacity failures surface before a single durable byte, and the crash windows between rows, ops, and vectors are gone — including record_with_rid's previously UNREPAIRABLE orphan (a kill between row and op lost the op forever; now kill-proven both-or-neither).
  • RAII savepoints (#91-class leaks closed), oplog entries atomic with their rows (#94 closed), replicated batch writes carry their idempotency identity to followers.

Behavioral changes — read this if you consume recall

  • recall() now excludes superseded results by default (include_superseded=True restores history access). Current-by-default is the correct default for agent context; as yantrikdb-mcp put it during validation: the outcome that matters is correct, current context after restart and correction, not raw recall volume.
  • record_text / record_batch now normalize blank namespaces to default — as record() has since v0.7.23.

Python error surface

  • Typed exceptions: yantrikdb.{Backpressure, IdempotencyConflict, InvalidIdempotencyKey, ProvenanceInconsistent, RecallContended, CorrectionDeferredDuringReembed, BatchDeferredDuringReembed} — all subclass RuntimeError (existing handlers unaffected); branch retryable-vs-conflict-vs-fatal on type, never on message text.
  • Note the split: a key with a python-side fallback embedder (e.g. ONNX backend) raises plain ValueError — a host-capability refusal from the wrapper, not an engine verdict.
  • __version__ now reads distribution metadata (a hardcoded string had drifted).

The lesson this release keeps

Three workspaces independently converged on it during validation: version pins fail (the version doesn't move), signature checks fail (behavior moves without them), and expert attention fails (a version lie sat in validation stdout and was walked past). Mechanical behavioral contract tests are the only gate that gates. Pin immutable refs, probe features not versions, and declare unsupported capabilities at runtime instead of silently degrading.

Wire-protocol precondition: yantrikdb-server's oplog wire format v2 (their #52) carries embedding bytes so followers apply identical vectors — required for Item 3's byte-determinism to hold across peer sync.