Repository navigation
khive v0.14.0
Minor release. Public Rust types in khive-runtime, khive-types, khive-pack-code, khive-pack-brain and kkernel change in ways that break source compatibility for code that constructs them directly, matches them exhaustively or relies on their auto traits; they are listed under Upgrading with what to change.
The release adds apply_changeset and kkernel kg apply for canonical change-sets, operator-registered code maps with code.list, code.search and code.deps, schema() for the loaded vocabulary, strict schema handling for explicit KG imports, receipt of authenticated mail from outside senders, an email suppression mirror, outbox scan health in comm.health, and khive_types::app for declaring a khive app as data.
Each entry below links the pull request that made the change. Every pull request in the release is listed at the end.
Upgrading from 0.13.0
khive_runtime::KhiveConfigaddsschema,code_map_rootandcode_maps, andkhive_runtime::RuntimeConfigaddscode_map_root,code_mapsandcode_map_protected_database_paths. Direct struct literals must set them. (#5128, #5612)khive_pack_code::CodeSourceIngestReportaddssource_reads,khive_types::ProposalAppliedPayloadaddspreimage, andkkernel::kg::ImportArgsaddsconfig. Direct struct literals must set them. (#5128, #5426, #5514)- New enum variants:
khive_runtime::AtomicOpFailure::{OwnerSnapshotConflict, PreimageMismatch},khive_runtime::AtomicOpPlan::Canonical,khive_runtime::RuntimeError::CanonicalAdmission,khive_runtime::ConfigError::SchemaParse,khive_types::ProposalChangeset::Canonicalandkkernel::kg::KgCommand::Apply. None of these enums is#[non_exhaustive], so downstream exhaustive matches must handle them.ProposalChangeset::CanonicalprecedesCompound, whose implicit discriminant moves from 6 to 7. (#5128, #5426) khive_runtime::AtomicOpPlanis no longerUnwindSafeorRefUnwindSafe. (#5426)khive_pack_brain::persist::PersistenceTrackerno longer has the publicincrement_dirtyandreset_dirtymethods. (#5226)khive-retrievalpersistence and weight APIs take the backend's SQL access handle instead of a raw SQLite connection; see Changed. (#5185)
Added
NoteStore::try_patch_note_propertiesapplies guarded partial property writes, forward-only expiry and a monotonic update timestamp in one storage operation. Its provided default returnsUnsupported; existing implementations remain source-compatible. Comm duplicate-quarantine repair now uses this typed operation through a channel-ingest capability, preserving its property guards and writer admission while removing the pack's repair SQL. (#5080)KHIVE_EMAIL_EXTERNAL_INBOUND=enabledreceives authenticated mail from outside senders (delivered as untrusted external messages and routed as with external senders configured) without settingKHIVE_EMAIL_EXTERNAL_SENDERS, so outbound external sending stays disabled. Start-up fails while it is enabled andKHIVE_EMAIL_EXTERNAL_INBOUND_ACTORis unset or empty, and on any other non-empty value. (#5442)- With
KHIVE_EMAIL_SUPPRESSION_MIRROR_URL,KHIVE_EMAIL_SUPPRESSION_MIRROR_TOKENandKHIVE_EMAIL_SUPPRESSION_MIRROR_MAX_AGE_SECSset, the email outbox reads the complete set of remote one-click suppressions and records every missing key in the local suppression list before an external message is sent (ADR-200 section 6, Amendment 4). A failed read keeps external messages pending, and external admission refuses withsuppression mirror staleonce the last successful read is older than the maximum age. Each outbox cycle also reads the mirror when its stamp is half the maximum age old, so an idle deployment stays fresh. (#5627) - Configured embedding engines may name custom pack providers. MCP, ingest and downstream host composition register providers before binding ordered peers and their declared dimensions, without loading models. Missing providers fail startup; explicit no-embedding runtimes keep no configured default while explicit manual named access remains available. (#5117)
khive-lion-corecopies Apache-2.0lion-core0.4.0 and addsKernel::with_keyfor caller-supplied seal keys. All-zero keys are refused; initialization starts at epoch zero with no previous key and the same empty, deny-all state. (#5111)- Add
schema()for loaded vocabulary and attributed endpoint declarations, including entity subtypes, counts and a stable content hash. The proposed ADR-084 contract remains pending acceptance and conformance validation. (#5125) apply_changesetapplies a complete canonical NDJSON change-set as one bounded, ordered writer transaction. Staged create and link identifiers survive application, updates compare the captured values of the fields they touch, and deletes compare the whole captured record exceptupdated_at.kkernel kg applysubmits the delta through the daemon, and reviewed canonical proposals use the same path. Merge is refused. (#5426)- When a coordinated kg search hits its deadline, the
backend search task timed outandbackend search task completed after the shared request deadlinewarnings addin_flight_phase,phase_elapsed_ms,active_phasesandcompleted_phases, naming what the backend search was doing.khive-storagegainsrequest_context::SearchPhaseTrace. Deadlines, budgets, retries, ordering and results are unchanged. (#5616) comm.healthreports an outbox scan health snapshot for the email and Telegram transports: completion and success times of the pending-row query and observations of the bounded eligible page. A failed scan keeps the previous success time. (#5326)- Explicit KG imports honor
[schema].strict, which defaults to true. Strict mode refuses an unknown entity kind before the destination is set up; relaxed mode keeps its spelling and warns once per distinct kind. Local VCS sync degrades unknown kinds toconceptand recordskhive:degraded_kind. (#5128) code_map_rootand[[code_maps]]entries (name,path,source_root) inconfig.tomlare validated entry by entry and loaded once into a runtime registry of code maps (ADR-139). A malformed entry is rejected by name without stopping the configuration from loading. (#5612)code.list,code.searchandcode.depsread operator-registered code maps: list and search paginate deterministically with a cursor bound to the map registration and filters, search ranks exact, then prefix, then interior name matches, and dependency traversal returns nodes breadth-first with incoming normal, dev and build dependencies, accurate node-limit truncation and every dependency edge among the returned nodes. The three verbs are classified as reads. (#5635)linkresponses disclose adependency_kindthe server inferred, with a hint for each inferred value; a caller-supplieddependency_kindsuppresses it. Bulk hints keep the caller's input indices across skips and failures, and an atomic link response carries the hint captured while the plan was prepared. (#5436)- The code pack's source ingest records the literal source-file inputs a module names:
include!,include_str!andinclude_bytes!arguments,#[path]attributes,#[doc = include_str!(...)], and filesystem read calls whose argument is a string literal. (#5514) - Guarded create-only edge insertion:
khive-storageaddsGraphStatementGuard,GraphStatementGuardFailureandEdgeInsertIfAbsentOutcome;khive-dbevaluates each read-only guard statement inside the edge's writer transaction;khive-runtimeaddslink_if_absent_with_guards. (#5198) khive_types::appdeclares a khive app as plain data (ADR-203): name, version, signer, the verb inventory with a rights class per handler, and the kinds it contributes.AppManifest::validateandAppManifest::admitrefuse incomplete or conflicting manifests, naming the conflicting owner. (#5518)
Changed
RetrievalPersistence::newnow acceptsArc<dyn SqlAccess>. Snapshot writes and namespace clears use the backend writer route; loads and statistics use its reader. Core migrations install the snapshot table and namespace index. The existinginit_schemacompatibility bootstrap now uses the admitted writer. (#5185)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. (#5185)- Edge-weight validators use the shared
khive-typespredicate, preserving numeric boundaries and validation diagnostics. (#5109) - With a configured runtime actor, a message the email channel quarantines, whatever its reason, is addressed to that actor (the maintainer) instead of the routed landing actor, so the mailbox recipient check keeps the quarantine record and its content reference out of every other actor's inbox, thread, read, get and search results. This applies to records ingested after the upgrade: a quarantine record already stored keeps the landing actor it was written with, and nothing re-addresses it. A runtime with no configured actor keeps the landing actor. (#5422)
- The email opt-out label (ADR-200 Amendment 2) now reads the first non-quoted paragraph of a reply rather than its first line, so a phrase a mail client wrapped onto the second line still counts, and the phrase list gains the plain asks for no more email ("don't email me", "do not contact me", "no more emails" and their spellings). The bare words "email me" are not a phrase: a reply asking us to email the docs is delivered without the label. (#5524)
- Email quarantine distinguishes
auth-untrusted, a message whose authentication results headers were present but not trusted, fromauth-absent. The record carries the anchor mode, the header family and the identifier as an escaped string of at most 128 bytes. (#5437) - Bulk
linkresponses reportinferred_countinstead of repeating an inference explanation for every edge;verbose=truekeeps the indexed hints and per-edge explanations. Singletoncreateedge results disclose inferred dependency kinds. (#5639) contextcharges anchor-to-anchor edges against the response budget and returns an anchor edge only when both of its anchors were admitted (ADR-140 Amendment 1). (#5323)- A best-effort mark-read failure carries
mark_error_details(typed code and stage, and the native SQLite write stage and result codes where present) besidemark_error. (#5359) - On Linux with glibc, the runtime returns the transient heap of a native embedding model load to the operating system once the built-in embedder has loaded. (#5474)
Fixed
- SQLite volume-lock refusals name the directory or lock file that could not be used and the underlying I/O error, and name both ways to choose another directory:
KHIVE_VOLUME_LOCK_DIRfor the default directory resolver, or the caller-supplied lock directory setting. Headless and containerized deployments require a writable home directory or an absolute, writable lock directory shared by all cooperating khive processes of the deployment; an unusable directory still refuses the open rather than falling back to a database-specific directory. (#5435, #5528) - An authenticated opt-out in a message that screening quarantines as
screenednow records the reply-stop suppression for its sender before the quarantine is acknowledged, as a delivered opt-out already did. No other quarantine reason records an opt-out, and ingest refuses one claimed on them. (#5421) - A registered code map whose main database file has more than one link is refused at registration and on every read, and the guarded read-only file system checks the link count on the file SQLite reads before any row is read (ADR-139 Amendment 2). A wrong-typed
code_mapsorcode_map_rootvalue fails the configuration load with the key named.khive_db::file_identity::file_link_countreads the link count from an open file. (#5720) db_diagnosticscollectssize_compositiononly when the read snapshot holds at most 8,192 pages and 32 MiB, checking both in the same snapshot; a larger store gets no composition andsize_composition_errornames the observed footprint and the limits. The limits bound the work admitted, not elapsed time.size_composition=falsestill skips the walk. (#5673)- The write-path secret gate treats
head=<40-hex>,head <40-hex>and the equals form of the other revision markers (sha=,commit=,revision=,rev=) as revision labels instead of refusing them as credential tokens. (#5459) - The web pack's disk ingestion encodes each file name as a URL path segment, so
#,?,%and\in a name no longer turn into a fragment or query and collapse two files onto one document. (#4458) khive-pack-brainbuilds without thelattice-routerfeature no longer fail clippy with unused imports. (#5621)
All pull requests (173)
Features
- feat(code): read registered maps and dependency graphs (#5635)
- khive-db: read-only open of a registered code map (#5628)
- feat(comm): pull the remote suppression mirror before external delivery (#5627)
- feat(search): name the in-flight phase when a backend search hits its deadline (#5616)
- feat(runtime): load registered code maps into a runtime registry (#5612)
- feat(types): app manifest with install refusals (#5518)
- feat(code): record literal source-file inputs (#5514)
- feat(email): receive external mail without enabling external sending (#5442)
- feat(kg): disclose inferred dependency kinds (#5436)
- feat(kg): apply canonical changesets atomically (#5426)
- feat(comm): report outbox scan health (#5326)
- feat(storage): add guarded create-only graph composition (#5198)
- feat(import): apply schema strictness without widening graph vocabulary (#5128)
- feat(kg): expose loaded ontology through schema (#5125)
- feat(runtime): bind configured embedding providers (#5117)
- feat(core): add the keyed capability kernel (#5111)
- feat(storage): support guarded partial note updates (#5080)
Fixes
- fix(code-map): refuse registered map files with more than one link (#5720)
- fix(db): admit size composition only for bounded snapshots (#5673)
- fix(kg): bound and complete dependency inference hints (#5639)
- fix(brain): compile the router module only with lattice-router (#5621)
- fix(db): clarify volume-lock failure paths and configuration (#5528)
- fix(email): read the opt-out window as the first paragraph and name asks for no more email (#5524)
- fix(runtime): recognize Git head and equals revision labels (#5459)
- fix(email): distinguish untrusted authentication headers (#5437)
- fix(db): explain unusable volume-lock directories (#5435)
- fix(comm): address quarantine records to the maintainer (#5422)
- fix(comm): record an opt-out from a screened quarantine (#5421)
- fix(comm): preserve typed mark-read failure details (#5359)
- fix(kg): charge anchor edges to the context budget (#5323)
- fix(retrieval): route index persistence through shared storage (#5185)
- fix(web): encode disk filenames as URL path segments (#4458)
Performance
- perf(runtime): release transient embedder load heap on Linux glibc (#5474)
Documentation
- docs(adr): ADR-206 Amendment 2, measured references; first references for ten crates (#5725)
- docs: correct stale facts in the developer guide (#5724)
- docs(adr): ADR-139 Amendment 2, a registered map file has exactly one link (#5719)
- docs(adr): ADR-200 amendment 5, occurrence-aware undo and complete mirror snapshots (#5716)
- docs(adr): ADR-049 points at the events daemon supervisor in its new module (#5704)
- docs(adr): ADR-040 archival, one membership parse at census and re-check (#5702)
- docs(skills): state search score and comm.read contracts as served (#5679)
- docs(adr): ADR-168 amendment, split event store and backfill version 1 (#5678)
- docs(adr): ADR-206 crate performance guarantees (#5642)
- docs(adr): ADR-040 amendment, comm message archival version 1 (#5633)
- docs(adr): ADR-200 Amendment 4, the suppression mirror's credential, answer and idle refresh (#5626)
- docs(adr): ADR-139 Amendment 1, registered maps are read in rollback mode (#5615)
- docs(adr): name the code map's dependency fields in ADR-205 (#5606)
- docs(adr): propose dependency-scoped pull-request CI from the code map (ADR-205) (#5601)
- docs(retrieval): describe the crate without the retired HNSW default (#5600)
- docs(adr): accept ADR-139, code-map read access (#5599)
- docs(adr): propose automatic freelist reclamation with incremental auto-vacuum (ADR-204) (#5527)
- docs(adr): point ADR-056 quarantine addressing at ADR-200 Amendment 1 (#5521)
- docs(adr): propose restore and inversion-limit amendments to ADR-101 and ADR-102 (#5520)
- docs(adr): propose khive apps on the base (ADR-203) (#5516)
- docs(adr): propose read-only pack validation pipeline (#5400)
- docs: require governing ADRs for verb contract changes (#5361)
Tests
- test(runtime): resolve route acceptance references (#5641)
- test(db): separate bootstrap and contention deadlines (#5636)
- test(kg): compare full guarded event insert statements (#5634)
- test(email): record screening outcomes for six outreach replies (#5515)
- test(brain): group help and event value test concerns (#5513)
- test(fold): group checkpoint and objective test concerns (#5511)
- test(retrieval): group executor and query variant concerns (#5506)
- test(git): group remote and dedup test concerns (#5504)
- test(db): split event-store test concerns (#5503)
- test(runtime): isolate demand-retirement worker assertions (#5438)
- test(db): fix the walpin heartbeat boundary clock (#5432)
- test(knowledge): instrument inline ANN runtime responsiveness (#5261)
Benchmarks
- bench(channel): cover receipt verification and allocation bounds (#5686)
- bench(bm25): cover reset, cache guards and tokenization (#5682)
- bench(quant): cover affine distances and codec throughput (#5680)
Refactoring
- refactor(runtime): split route_census.rs into submodules (#5613)
- refactor(runtime): split events_split.rs into submodules (#5611)
- refactor(email): split channel.rs into submodules (#5610)
- refactor(brain): split handlers.rs into submodules (#5609)
- refactor(git): split ingest.rs into submodules (#5608)
- refactor(db): split stores/graph.rs into submodules (#5607)
- refactor(memory): split ann.rs into state, bridge, loaded-index, warm, watermark, fresh-tail and checkpoint modules (#5554)
- refactor(runtime): split daemon.rs into dispatch, connection, run loop, boot guard and process-file modules (#5531)
- refactor(knowledge): split vamana.rs by concern and move search reranking out (#5530)
- refactor(mcp): move daemon recovery into daemon/recovery.rs (#5529)
- refactor(db): group S3 blob value tests by concern (#5512)
- refactor(query): group parser tests by concern (#5510)
- refactor(telegram): group channel and wire value tests (#5509)
- refactor(brain-core): group state value tests by concern (#5508)
- refactor(storage): group accessor and error classification tests (#5507)
- refactor(schedule): share repeated recurrence parameter definitions (#5502)
- refactor(gtd): share repeated lifecycle parameter definitions (#5501)
- refactor(comm): share repeated parameter definitions (#5500)
- refactor(knowledge): share repeated verb parameter definitions (#5499)
- refactor(query): share ASCII digit-run scanning (#5498)
- refactor(telemetry): share verb parameter definitions (#5497)
- refactor(session): share string-parts extraction (#5496)
- refactor(blob): share range validation and part decode errors (#5495)
- refactor(fusion): validate borrowed weighted RRF parameters (#5494)
- refactor(merge): share object-property value selection (#5493)
- refactor(wire): share handshake sequence error construction (#5492)
- refactor(request): share quoted-string owned-prefix construction (#5491)
- refactor(channel-email): group backoff and unsubscribe value tests (#5490)
- refactor(repo-showcase): share model bounds and ratio validation (#5489)
- refactor(telegram): share Bot API response body handling (#5488)
- refactor(vcs): lowercase snapshot IDs in place (#5487)
- refactor(graph-diff): use a single entry lookup for parsed records (#5486)
- refactor(rule-evaluator): share lazy NDJSON parsing for ID collectors (#5485)
- refactor(text): reuse script character counts without collecting (#5484)
- refactor(knowledge): group handler and compose member value tests (#5483)
- refactor(db): group ordinary graph query tests (#5482)
- refactor(memory): share calibrated relevance normalization (#5481)
- refactor(runtime): delegate objective selection results directly (#5479)
- refactor(db): group ordinary entity and note record tests (#5478)
- refactor(runtime): group catalog metadata and help description tests (#5476)
- refactor(memory): group configuration serialization and positive ranking tests (#5475)
- refactor(hnsw): group dimension and metric contract tests (#5473)
- refactor(runtime): organize presentation tests by concern (#5472)
- refactor(db): group ordinary text and agent store tests (#5471)
- refactor(gate): separate actor and value contract tests (#5470)
- refactor(fold): split selector tests by concern (#5469)
- refactor(channel): split adapter contract tests by concern (#5468)
- refactor(kkernel): separate ranking and showcase CLI test concerns (#5467)
- refactor(types): split general entity-type tests by concern (#5465)
- refactor(merge): split three-way merge tests by concern (#5464)
- refactor(quant): split codec tests by concern (#5463)
- refactor(bm25): split unit tests by concern (#5462)
- refactor(repo-showcase): split export contract tests by concern (#5461)
- refactor(wire-protocol): split codec tests by concern (#5460)
- refactor(telemetry): split integration tests by concern (#5458)
- refactor(vcs-adapters): split JSON adapter tests by concern (#5457)
- refactor(charter): split general schema admission tests by concern (#5456)
- refactor(git): split cache and source tests by concern (#5455)
- refactor(blob): split staged upload tests by concern (#5454)
- refactor(brain): split general profile tests by concern (#5453)
- refactor(runtime): split general integration tests by concern (#5452)
- refactor(kkernel): split CLI validation and supervisor tests by concern (#5451)
- refactor(knowledge): split general integration tests by concern (#5450)
- refactor(kg): split message graph scope tests by concern (#5449)
- refactor(memory): split general integration tests by concern (#5447)
- refactor(mcp): split integration and attachment replay tests by concern (#5446)
- refactor(rule-evaluator): split evaluation and tier tests by concern (#5445)
- refactor(blob): split integration tests by concern (#5444)
- refactor(session): split mirror and integration tests by concern (#5443)
- refactor(request): group parser corpus tests by concern (#5441)
- refactor(git): group acceptance and development tests by concern (#5440)
- refactor(schedule): group integration tests by concern (#5439)
- refactor(fs): group bounded walker tests by concern (#5434)
- refactor(query): group SQL compiler tests by concern (#5433)
- refactor(comm): group delivery and idempotency tests by concern (#5431)
- refactor(types): group relation certificate tests by concern (#5430)
- refactor(storage): group vector contract tests by concern (#5429)
- refactor(retrieval): split materialization tests by concern (#5427)
- refactor(vcs): partition hash tests by concern (#5423)
- refactor(schedule): guard cancellation with note revisions (#5329)
- refactor(kg): reuse guarded event bindings (#5328)
- refactor(kkernel): use grouped counts for nullable entity census (#5327)
- refactor(runtime): share pack relation collection (#5280)
- refactor(runtime): consolidate identity and edge reads (#5260)
- refactor(code): split source ingest into focused modules (#5231)
- refactor(brain): share persistence and decay helpers (#5226)
- refactor(knowledge): share import and prefix helpers (#5222)
- refactor(score): share vector similarity and normalization (#5146)
- refactor(git): consolidate typed entity row selectors (#5139)
- refactor(runtime): share secure filesystem operations (#5138)
- refactor(validation): adopt the shared edge-weight predicate (#5109)
- refactor(mcp): extract daemon self-heal transport (#5064)
- refactor(mcp): extract Telegram polling and outbound loops (#5028)
- refactor(web): extract fetch and extraction unit tests (#4465)
Build, CI and release
- chore(release): 0.14.0 (#5728)
- ci(bench): run the dependents closure once per merge train (#5703)
- ci: scope pull-request test runs to the changed crates and their dependents (#5638)
- test(ci): turn off git auto-maintenance in fixture repositories (#5625)
- ci: run split and docs pull requests on the Linux shards only (#5604)
- ci: classify main pushes from main's history only (#5602)
- ci: record benchmark trend points nightly and per release instead of per merge (#5542)
- ci: cancel a superseded main push run so a merge burst leaves one run (#5532)
- ci: integration lane for crate-source pull requests from the automation branch prefix (#5505)
Full list of changes: v0.13.0...v0.14.0