Repository navigation
v0.12.0
khive v0.12.0
Minor release. Twelve changes to public Rust types break source compatibility for code that names them directly; they are listed under Upgrading with what to change. Two behaviour changes reach MCP clients: a stdio host that forwards to the daemon is now strict whenever a daemon socket or PID file exists, and a daemon that is alive but slow now answers daemon_slow with the phase it was in.
The release moves to lattice 0.12.0, adds ordered peer embedding engines with explicit per-engine search and weighted RRF fusion, lets db_diagnostics inspect one backend and survive its read deadline, cuts each pooled SQLite connection's page cache from 64 MiB to 8 MiB, makes a keyword_only or vector_only memory.recall run only the retrieval arm it keeps (with optional per-call stage timings), and accepts the ADR-048 graph lint, ADR-037 and ADR-035 contracts.
Upgrading from 0.11.0
- Memory's
RecallFtsGatherModenow re-exports the canonical storageTextGatherModeinstead of declaring a separate enum. Its public path, variant imports,Copybehavior, serialized config, and search options remain supported; code depending on the old nominal type identity must adapt. (#5104) khive-runtimeremovesRuntimeError::Sqlite; concrete backend failures now useRuntimeError::Storage, retaining typed driver sources and the existing capacity, retry, and writer-settlement wire codes. Callers matching the removed variant should inspectStorageErrorinstead. Typed policy reasons now reportStorage, rendered backend messages use the storage envelope, and direct writer-checkout failures carrysql/runtimecapability/operation context instead of nulls. (#5075)khive-runtimeaccepts ordered peer[[engines]]entries withname, unit-defaultweight, and checkeddims.EngineConfigreplacesmodel,default, andfusion_weight;RuntimeConfigadds an authoritative optional peer list andKhiveConfigrecords an explicit empty list. Legacy TOML is converted with its former default first and canonical provider/index names preserved. Duplicate aliases, storage-key collisions, mixed schemas, invalid dimensions, and weights that are not applied by every retrieval path fail explicitly. Startup checks built-in provider dimensions; custom provider binding remains unavailable pending its startup integration. Direct struct literals and exhaustiveConfigErrormatches must be updated. Usedisable_embedding_models()to clear peers and legacy projections together. Daemon reuse now requires the same ordered engine configuration. (#5102)khive_db::diagnostics::ReaderContentionDiagnosticsaddsreader_discards; direct struct constructors and exhaustive destructurings must account for it. Thedb_diagnosticsresponse now exposes this cumulative pool counter besidereader_replacement_open_failures, including successful reader recycling without changing pool behavior. (#5102)khive-retrieval'sfuse_search_results,hybrid::fuse_labelled_scored, andDualIndexRouter::merge_resultsnow returnResult<Vec<_>, khive_fusion::FuseError>; callers must handle or propagate failures. Invalid weighted-RRF parameters, source counts and score overflow now propagate through memory recall instead of appearing as no results, including empty candidate sets. The checked helper keeps itsRetrievalErrorresult type, and existing uncheckedWeighted/Customfallback behavior is preserved. (#5102)khive_storage::NoteFilteraddsmax_created_at,max_expires_at,include_deleted,expiry_fallbackandtime_order; exhaustive struct literals must add them or use..Default::default().FilterOpaddsMissingNullOrSpaceEmptyTextandTrueOrTextTrue; exhaustive matches must handle both. Typed expiry fallback and native timestamp ordering preserve complete legacy cleanup predicates before LIMIT. Thecreated_before/expires_beforebuilders use inclusive Unix-microsecond bounds, andinclude_deletedaffects reads only. Existing serialized filters retain live-only, unbounded defaults.AttachmentStore::delete_attachment_ifadds a conditional ID/role/substrate/ref delete with anUnsupporteddefault and an atomic SQLite implementation; comm cleanup adoption remains separate. (#5104)KhiveRuntime::list_embedding_modelsnow returns runtime-ownedEmbeddingModelRecordvalues with all twelve persisted registry fields. Rust callers usediminstead ofdimensionsand theEmbeddingModelStatusenum instead of a status string. Status serde values remain lowercase;kkernel engine list/statusretain their seven-field JSON shape. Invalid required fields, unknown statuses and invalid non-NULL optional dimensions/UUIDs are skipped with a warning. Existing optional timestamp decoding still maps non-integers toNone; reads never fabricate missing identity or lifecycle history. (#5104)- Symmetric-edge runtime updates now use the guarded
GraphStorecapability. Direct-fallback backend failures carrygraph/update_edgeoperation context, and blocking-task join failures returnRuntimeError::Storageinstead ofInternal; reasons and rendered prefixes on those paths change. Concrete causes and writer-settlement distinctions are retained. Backends without the new transaction method explicitly returnUnsupported. (#5105) khive_runtime::AtomicOpPlanaddsFinalizeEntityfor runtime-owned entity admission. Downstream exhaustive matches must handle the new variant. Its plan has no public constructor; direct ingest usesEntityCandidateContextandtry_commit_manifest_entity_candidate. (#5133)khive-fusionaddsWeightedRrf { k, weights }, positive-weight validation, and weighted-RRF fusion errors. This is source-breaking for consumers with exhaustive matches onFusionStrategy,FusionStrategyError, orFuseError; update those matches to handle the new rank-based strategy and its validation errors. Weighted RRF checks positive finite weights and source-count alignment, preserves empty source slots, and errors when a fused score exceeds the finite deterministic-score range. (#5031)- Breaking Rust API change:
khive_types::RerankExecutedPayload::model_idis now optional, and the payload addsreranker,query_id,tiers,ignored_weightsandunidentified_candidates. Direct constructors and exhaustive destructurings must account for those fields. Stored events without a discriminator still decode as native reranks; weighted memory reranking does not invent a model identity. (#5034) khive-storageaddsStorageError::SqliteWriteandkhive-dbaddsSqliteError::{Write, WriteSettlementUnknown}, carrying native SQLite write evidence (SqliteWriteFailure: stage, primary and extended codes, settlement flag). Exhaustive matches must handle the new variants,SqliteWriteFailureliterals must include every field, andEventsResponse::Errorliterals need the new optionalsqlite_write_failurefield. On the wire, a nativeBEGINrefusal now reportscode/stagesqlite_begin_busyinstead ofwriter_task_begin_busy, with retryability unchanged; without native evidence the code stayswriter_task_begin_busy. A definite native write failure reports its stage ascodeandstage, withsqlite_write_stage,sqlite_primary_codeandsqlite_extended_codebeside it. (#5113)- A stdio MCP host that forwards to the daemon refuses, instead of silently dispatching locally, whenever a daemon socket or PID file exists.
KHIVE_DAEMON_STRICT=0restores the fallback; the full entry is under Changed (#5304). - Moodboard descriptors report inference version 0.12.0, so existing moodboard vectors need reindexing and preference bundles trained under an earlier lattice version need retraining. The pack is opt-in at build and run time (#5183, #5322).
Added
- Weighted memory reranking recognizes a precomputed
graph_proximityfeature.RerankFeaturesgains the public field and a zero-valuedDefault; direct struct constructors must supply it. Recall handlers supply zero pending graph gathering, default weights remain empty, and rerank provenance records the recognized feature. (#5210) khive-brain-coreexposes evidence-only posteriors with explicit event/read clocks, checked half-lives, decay-before-add and a fixed read-time prior. Regressed writes preserve the entry; invalid or overflowing updates refuse atomically. Existing posterior storage, folds and serving paths remain unchanged. (#5210)- Packs can declare note property policies and discover the validated registry boot snapshot. Comm declares its nine existing kind-specific protected properties; writer enforcement is unchanged. (#5210)
db_diagnosticsacceptsbackend=<name>to inspect only the opened database serving that backend, andsize_composition=falseto skip thedbstatwalk, which reads every page of each file. Every file-backed report now carriespage_accounting(page_size_bytes,page_count,freelist_pages), three pragma reads that are reported either way. (#5312)memory.recallacceptsinclude_timings=true, which returns this call's retrieval stage wall times (embed_us,fts_us,ann_us,fresh_tail_us,hydrate_us,nullfor a stage that did not run),total_us,retrieval_rounds, and per-roundcandidate_limit,text_hits,vector_hits,hydratedandeligiblecounts. An array response becomes{results, timings}; an object response gainstimings. No environment variable or restart is needed;KHIVE_RECALL_PROFILEkeeps working as before. (#5319)khive-retrievaladds pure query-variant normalization and bounded RRF-60 admission merging. Original-query fallback preserves its bytes, generated variants are validated as a whole, and admitted IDs retain variant and retrieval-source attribution. (#5133)kkernel kg update <remote> [--ref <ref>]resolves a Git ref to a full commit SHA and atomically updates that remote in an existing schema.yaml, reporting both old and new commits while preserving archive-content pins and other YAML values. Rust clients with exhaustiveKgCommandmatches must handle the newUpdatevariant. (#5148)- Runtime packs may expose an optional
ContextContributorcapability with owned request and slice types and explicit score semantics. Registry discovery preserves pack order; context composition and execution remain separate. (#5148) EmbeddingCosineRerankerscores every supplied entity candidate in a named engine, preserves missing vectors with their incoming scores and an explicit flag, and implements the retrievalRerankertrait without a namespace-wide candidate cut. (#5148)khive-graph-diffcompares in-memory entity, edge and note NDJSON states with deterministic additions, removals and field changes, preserving missing versus null. (#5159)- Add explicit event sink declarations in
khive-types. All existing event kinds retaincaller_event_store; the closed metadata API requires each new kind to declare its sink. Event routing and storage behavior are unchanged. (#5159) - A standalone session raw-value codec writes level-3 zstd frames with BLOB prefix
0x01, borrows legacy TEXT unchanged, and refuses unknown formats or malformed data. Callers select the decoded BLOB size bound; mirror storage paths and dictionaries remain unchanged. (#5160) VectorStore::scan_vectorsenumerates persisted vectors in UUID-ordered pages with exact metadata filters and an explicit row limit. SQLite reads stored bytes through reader admission; pages do not form a cross-request snapshot. (#5160)- The opt-in
charterpack installs the seven recording tables from ADR-193 and provides revision-and-state checked transaction helpers. This schema foundation exposes no verbs, grants no action admission, and does not enforce merges. (#5095) khive_runtime::hooks::refuse_shared_createprovides a kind-owned creation refusal hook. Memory and channel-health hooks share itsInvalidInputdiagnostic, naming the specialized writer while retaining their update and proposal guards. (#5095)KhiveRuntime::resolve_prefix_inresolves UUID prefixes in a named pack-owned table, reporting distinct-ID ambiguity and storage failures. APrefixScopeargument states which rows count: one namespace or all of them, and live rows only or soft-deleted ones too. Rows outside the scope neither match nor make a prefix ambiguous; any other selection policy stays with the caller. (#5102)khive-retrieval::fuse_two_stagecombines ordered engine arms before vector/text fusion, checks both strategies even on empty input, preserves the candidate union without a final limit, and accepts an async custom-executor adapter without a runtime dependency. (#5104)- Runtime
vector_search_in,knn_inandrerank_inbind queries to an explicit engine, checking its dimensions and finite coordinates even for empty requests. Existing methods remain single-engine compatibility delegates to the configured first/default engine. (#5104) khive-fsadds bounded directory-name listing and descriptor-relative tree enumeration with caller filters, explicit depth and entry caps, and optional within-root symlink following. Caps count hidden and non-UTF-8 entries and refuse overflow instead of truncating results. (#5133)kkernel kg importaccepts--format bibtexand.bibfiles, streaming bounded entries into document/paper records with authors properties,@stringexpansion and crossref edges. Malformed entries report skip counts and optional warnings; fatal source errors refuse the import before the target database opens. (#5133)khive-runtime::BackendHandleprovides five required core capabilities and optional per-binding vector, sparse, and text factories. SQLite construction performs no storage operation; first use retains existing readiness and repair, and unavailable retrieval tiers return named errors (#4706). (#5133)brain.auto_feedback(signal="unjudged")records attributed serve telemetry without training or consuming a serve-ledger grade. Later caller-judged auto-feedback with the same scorer/serve pair commits its grade and posterior update exactly once; manual feedback behavior is unchanged. (#5133)
Changed
memory.recallwithfusion_strategy="keyword_only"no longer embeds the query or searches the vector index, andfusion_strategy="vector_only"no longer runs the full-text search. The saved work was most of the cost of akeyword_onlyrecall that finds no text match.keyword_onlyno longer applies the vectormin_raw_relevancefloor; its hits carryraw_score: nullandscoreis the composite; rank order is unchanged. Widening re-runs only the arm the strategy keeps and stops when that arm is exhausted. Akeyword_onlyrecall therefore never reportsdegraded, and a verbosekeyword_onlyrequest on a multi-model store returns the ordinary shapes instead of thevector_candidates_per_modelenvelope, since no vector recall ran. (#5319)- A
keyword_onlyrecall whose query the embedder cannot embed now returns its text hits instead of failing withrecall: all embedding engines failed, and avector_onlyrecall whose full-text table is unreadable now returns its vector hits instead of failing. (#5319) memory.recallleaves an English-only embedding model's vector list out of fusion when the query is CJK-dominant (its CJK characters outnumber its other letters). Today that model isall-minilm-l6-v2, which maps most CJK characters to[UNK], so its candidates for such queries carry no signal. The list gets weight zero under every strategy that fuses per-model vector lists, but only when another model contributed a candidate and the request does not nameembedding_model. English and mixed queries fuse as before. Theenable_cjk_fts_bypassdocumentation now states what the flag does: it skips term selection in the FTS gather path and is read only when FTS gather is enabled. (#5318)db_diagnosticsno longer fails as a whole when the request's read deadline arrives. The backends already inspected are returned, every remaining backend'serrorstarts withnot inspected: request deadline, and the new root fieldcompleteisfalse. Backend inspections stop slightly before the deadline (a tenth of the remaining time, at most two seconds) so the partial report reaches a client whose own deadline started first. A cancelled request still fails. Whenbackendselects a database, the root fields describe that database rather than main. (#5312)khive_db::diagnostics::collect_with_runtime_audit_metrics_for_process_interruptiblyandKhiveRuntime::db_diagnostics_for_opened_backend_with_audit_metricstake a trailingcollect_size_composition: bool; passtruefor the previous behavior.khive_db::diagnostics::DbDiagnosticsgains the public fieldspage_accountingandpage_accounting_error; direct struct constructors must supply them. (#5312)- A stdio MCP host that forwards to the daemon is now strict by default whenever a daemon socket or PID file exists, or existed when the request arrived: a request that would have fallen back to local dispatch is refused with its reason code (
no_socket,config_mismatchand the rest), as underKHIVE_DAEMON_STRICT=1.KHIVE_DAEMON_STRICT=0(orfalse,no,off) restores the fallback; with neither file on disk the quiet fallback is unchanged;KHIVE_NO_DAEMON=1remains the way to run without a daemon. (#5304) - A daemon that is alive but does not answer in time now returns
reason: "daemon_slow"withphase: "before_dispatch"(nothing sent,not_committed, retry is safe) orphase: "after_write"(unknown; read state before any re-send) and the elapsed wait. A connection lost after the request was sent returnsdaemon_connection_lost, and an unreadable responseparse_failure; all three post-write outcomes stay terminal.bridge.diagnosticsreportsdaemon_slowcounts per phase, outsidefallback_total. (#5304) - Client daemon recovery acts on one rendezvous. With exactly one of
KHIVE_SOCKET/KHIVE_PIDset and a socket that does not answer, a request is refused withreason: "rendezvous_split"(not_committed) instead of reading the other half's PID file and signalling the daemon it names. A client also never signals a live daemon on a rendezvous a supervisor marker claims: it returnssupervised_daemon_unresponsive(not_committed) naming the pid, the marker's job and the marker path. (#5305) - The daemon writes
<pid file>.exit(runningafter it claims the PID file,exitedwith the reason and the pid that sent the shutdown signal), logs the previous record and the effectiveRLIMIT_NOFILEat WARN on every boot, and logs its shutdown at WARN. (#5305) - Each pooled SQLite connection now keeps an 8 MiB page cache instead of 64 MiB. The cache is per connection and on the heap, so a process with many connections paid the old size many times over.
KHIVE_SQLITE_CACHE_KIB(512 to 1048576) andKHIVE_SQLITE_MMAP_BYTES(0 to 2^40,0disables memory-mapped reads; default 1 GiB) override the two settings; a value outside its range is logged and ignored. (#5288) - A stdio MCP host that forwards to the daemon no longer runs the legacy quarantine original repair at boot, whether it serves one store or several. The daemon runs it before it serves; the census read every message row on every backend, so each client start spent seconds pulling the stores through the page cache. The repair itself now stops after its first census when nothing is unowned, instead of reading the roster twice more to change nothing, and reports how many passes it made. (#5288)
- Upgrade the shared
rmcpdependency to 2.2, including its security and transport cancellation fixes. MCP, mounted tools and CLI consumers keep their existing feature configuration; MCP result tests use the renamedContentBlockAPI. (#5208) - An oversized stdio line now receives Invalid Request (-32600, no id) instead of Parse Error (-32700): rmcp 2.2 ignores syntactically invalid JSON without replying. The line cap, drain and next-request recovery are unchanged. (#5208)
khive-retrievalweight updates and batch reads now accept&dyn SqlAccessinstead of a raw SQLite connection. Pass the migrated backend's SQL access handle; updates and audit rows commit together through its writer route, and read-only handles refuse updates. Storage failures usePersistError::Storage. Core migrations now installatom_weightsandweight_events; the standaloneinit_weight_schemabootstrap remains available for compatibility. (#5217)- Lattice dependencies move from 0.9.0 to 0.12.0 (
lattice-embed,lattice-inference,lattice-fann). Moodboard descriptors now report inference version 0.12.0, so their fingerprints and model keys change and existing moodboard vectors need reindexing; preference bundles trained under 0.9.0 fail closed on load and need retraining. BLAKE3 no longer runs with thepurebackend: std members enableblake3/stddirectly. (#5183, #5322) khive-vamanagreedy search keeps its candidate list sorted and bounded: each neighbor is placed by binary search and the next candidate to expand is read from a cursor, instead of re-sorting the whole list and scanning it for the nearest unexpanded entry after every expansion. Candidates with equal SQ8 distance now order by node id rather than by exact f32 distance; the exact f32 re-score of the final list still decides the returned top-k. An index built after this change can differ from one built before it where SQ8 distances tie. (#5316)- Public brain posterior folds use the shared filter and map combinators, preserving reducer state, standalone section-feedback handling and offered-event counts. (#5133)
- Pool configuration, WAL ceiling policy and test-store guards move into an internal configuration module while preserving public paths, defaults and refusal behavior. (#5148)
- Vamana v2 saves use one checkpoint-owned publication boundary: metadata is published and synced through the shared Unix helper before the four staged segments are promoted. Sidecar reads and cleanup share component-name conversion, preserving their refusal policy and native I/O errors (Refs #4498). (#5159)
- Blob and WAL-pin publication use the shared descriptor-relative rename helper; blob-root verification uses the shared file identity type, preserving held handles and durability barriers. (#5102)
- Vamana checkpoint staging, auxiliary sidecars and external-ID sidecars share Unix descriptor-relative atomic publication helpers. Checkpoints retain their separate metadata commit and segment promotion boundaries, stale-entry policies and I/O diagnostics. (#5102)
- Git cursor inspection and annotation repair now share the bounded snapshot query, preserving their separate size limits, refusal messages and exact stored cursor bytes. (#5102)
- Session mirror enable flags now use the shared boolean parser:
onand surrounding whitespace on recognized true values enable the configured source. All four flags still default to disabled; the separately default-enabled backfill flag keeps its existing parser. Session maintenance uses shared typed SQL row accessors while preserving its error messages and rejection of negative counts. (#5104) - MCP configuration fingerprinting and verb catalog helpers now live together in the server config module, preserving public entry points, daemon identity values, and catalog output. (#5105)
- Extract blob garbage-collection ownership and database lock handling into a private module while retaining the existing public API and lock behavior. (#5105)
khive-dbmoves checkpoint escalation and transaction-age state into a dedicated module, preserving the publickhive_db::checkpointpaths and state-machine behavior. (#5113)- Extract runtime daemon wire frames and framing into a private module while preserving public paths, protocol constants, error normalization, and source-reader coverage. (#5113)
- Move MCP server state, registration errors, and stdio settings into a dedicated core module, preserving public server entry points and existing function bodies. (#5133)
- Split the
kkernel execrun paths into a private module while preserving the public entry point, test module paths, and tracing targets. (#5133) - Entity create, claim, ordinary update, bulk, and direct code ingest now share manifest-aware candidate admission. For an admitted candidate, the entity, runtime stamp, required indexes, attachments and exemption audit commit together. Production manifests remain empty; non-empty fixtures are test-only. Notes and administrative/atomic updates retain their existing gates. (#5133)
Fixed
- The secret gate treats a label ending in
_tokenas a credential label, so a UUID or opaque value assigned toaccess_token,refresh_token,session_tokenor any other*_tokenlabel is refused the way one assigned totokenis. Pagination and sync cursors (next_token,next_page_token,page_token,pagination_token,continuation_token,resume_token,sync_tokenand a few others, matched as the whole label) stay allowed, as does the sealedvisibility_tokenreceipt in a quotedmemory.rememberresponse. The label directly before a repository revision URL or a LaTeX fragment follows the same rule. (#5315) - The daemon registers its signal-sender recorder before its shutdown signal streams, so the exit record names the sender of a SIGTERM or SIGINT instead of intermittently writing
sender_pid=unknown. Registering the recorder for a signal that already has a handler is logged onkhive.boot. (#5314) - On a database without
sqlite_stat1, an ID-filtered event read (including the events-split store's check of each new audit batch against the legacy store) and the schedule creator-provenance lookup now seek the primary key andidx_schedule_creator_provenance. Before, both walked every event of the namespace increated_atorder. (#5313) - Volume-lease waiters acquire in FIFO order without changing deadline or re-entry errors. File-backed kkernel test fixtures use private lock directories to avoid unrelated contention (#5087). (#5210)
kkernel kg exportchecks file sync and removes its own temporary after a write, sync or rename failure. On Unix it publishes through shared atomic publication: it refuses an existing temporary instead of replacing it, keeps the original filename bytes, creates the file with mode 0666 under the umask and syncs the parent directory after the rename. Existing shared staging policies keep mode 0644 and their behavior (#5068). (#5210)- Named-vector and memory session exact search select equal-distance boundary hits by subject UUID before limiting candidates, keeping their order stable across database reopen. (#5217)
kkernel kg initnow creates the canonical.khive/config.tomlwith valid engine settings, preserves existing project configurations, and refuses the obsolete config path before writing scaffolding. Only the exact old generated ignore file is migrated to the canonical filename. (#5133)- Identifier splitting restores acronym boundaries in
DBUsersandAPIUsagewhile keeping terminal plural suffixes inAPIs,IDs,URLs, andAPIsFoo.URLsafenow splits asur,lsafe;XMLIsEmptyfollows the dictionary-free rule asxmlis,empty(#5103). (#5133) comm.readpreserves typed storage errors from its initial message lookup, including admission-timeout code, stage, and retry guidance. Bulk read and mark-read validation retain the same error source without marking messages after a failed lookup. (#4958) (#5159)- GTD status and priority refusals now mask credential-shaped values with the existing secret masker. Plain invalid values, accepted-value hints, and error kinds remain unchanged. (#5081)
kg_nameandIdentifierTokenizerkeep plural acronyms such asAPIs,IDsandURLswhole (a terminal lowercasesafter an acronym), while still splitting acronym-to-word boundaries such asXMLParser,HTTPServerandXMLToJSON. (#5081)- Knowledge atom list, count, cursor, coverage, and search now share import/delete's exact decoded domain-tag rule, preserving legacy malformed-tag handling. Near-marker atom tags remain visible, and an additive migration rebuilds the cursor index without rewriting rows. (#5102)
git.pushaccepts the optional booleanforcevalidation field and refusestruewithforce_deniedbefore transport. False and omission retain ordinary push behavior; null and non-boolean values returninvalid_params. (#5102)- Pack schema registration now checks table ownership in every statement of a schema entry, refusing collisions before applying any DDL. Semicolons inside quoted names, strings, and comments remain part of those tokens. (#5102)
- Pack-version regressions compare each linked pack with its factory's declared version and cover independent factory versions through the production JSON and human list formatter (#5086). (#5113)
- Finding create/update and findings-file ingestion mask credential-shaped rejected enum values while retaining ordinary values, error kinds, and accepted-value lists (Refs #4585). (#5148)
Documentation
- Accept the ADR-048 graph lint contract for #4813: thirteen built-in rules, typed reports and statistics, and guarded fix receipts. The verb remains unimplemented. (#5102)
- Accept the
kg.proposal_cleanupoperator contract: hide old applied or rejected proposals using an archive marker while retaining their identity and event history. Retention follows last projection activity. The handler remains unimplemented. (#5102) - Accept ADR-037 configuration-bound namespace and project-root rules for remote cached-entity reads, preserving origin and refusing remote mutations. The read remains unimplemented. (#5104)
- Accept ADR-035 embedding pipeline configuration, legacy-key compatibility and import strictness rules, with an ADR-001 companion distinguishing explicit import from VCS snapshot degradation; edge relations remain closed. The configuration remains unimplemented. (#5105)
Full list of changes: v0.11.0...v0.12.0