Skip to main content

Module atomic_prepare

Module atomic_prepare 

Source
Expand description

ADR-099: the per-verb async prepare pass for the KG-substrate v1 admissible verbs (update, delete, link, merge), plus prepare_add_entity/prepare_add_note for the ADR-046 proposal changeset AddEntity/AddNote arms. Each prepare_* function reads current state (async, outside any transaction) and returns a plain-data crate::atomic_runner::AtomicOpPlan (crate::atomic_plan) for the synchronous commit pass (crate::atomic_runner::run_atomic_unit) to apply.

gtd.transition/gtd.complete prepare is deliberately not here (lives in kkernel instead), and propose/review/withdraw/merge are on the v1 admissible list but have no working prepare implementation in this module (prepare_governance_unimplemented fails loudly rather than silently no-opping; prepare_merge is unreachable through --atomic and kept only for its own tests and as defense in depth). See docs/api/atomic_prepare.md#scope-what-is-excluded-and-why for why each of these is excluded and what would be required to admit them.

Enums§

AtomicDeleteKind
Caller-supplied delete-kind expectation, resolved via the canonical resolve_kind_spec at the kkernel --atomic seam. khive-runtime must not depend on khive-pack-kg (packs depend on the runtime, not the other way around), so this is a plain substrate-level shape rather than khive_pack_kg::handlers::KindSpec itself: the kkernel seam does the pack-aware resolve_kind_spec resolution (which needs a VerbRegistry, unreachable from this crate) and passes down only what prepare_delete needs to enforce the mismatch check.
AtomicUpdateKind
Caller-supplied update-kind expectation, resolved via the canonical resolve_kind_spec at the kkernel --atomic seam: the same pattern AtomicDeleteKind uses. Without this check, update(kind="document", id=<concept>) would be canonically NotFound but the atomic path would ignore the explicit kind and mutate the resolved entity anyway. khive-runtime must not depend on khive-pack-kg, so this is a plain substrate-level shape rather than khive_pack_kg::handlers::KindSpec itself: the kkernel seam does the pack-aware resolution and passes down only what prepare_update needs to enforce the mismatch check.

Functions§

apply_post_commit_effects
Run every deferred PostCommitEffect after a committed atomic unit, outside any transaction. Re-fetches each target’s now-committed row and reuses the existing reindex_entity/reindex_note (FTS + embedding, same as the non-atomic path) for exact parity.
prepare_add_entity
Build the prepared plan for an AddEntity proposal change. The entity row and FTS document are committed together; vector indexing is deferred until after commit because embedding may suspend. kind must already be canonicalized by the caller because pack-aware resolution requires a VerbRegistry.
prepare_add_note
Build the prepared plan for an AddNote proposal change. Mirrors prepare_add_entity’s shape and the same kind-already-canonicalized split. annotates is out of scope: the proposal NoteDraft this backs carries no annotates targets, unlike KhiveRuntime::create_note’s general-purpose signature.
prepare_delete
expected_kind: None when the caller omitted kind (no check, parity with canonical’s own optional discriminator); Some(_) enforces an exact-parity mismatch check against the resolved record’s actual substrate/specific kind, mirroring handle_delete’s entity.kind != *expected / note.kind != *expected checks.
prepare_op
Build the prepared AtomicOpPlan for one KG-substrate admissible op (update, delete, link, merge). Returns a loud RuntimeError for propose/review/withdraw (known scope gap, see module doc) and any other verb (the CLI boundary must reject those before calling this — a verb reaching here is either KG-substrate-admissible or a bug upstream).
prepare_update
expected_kind: None when the caller omitted kind (no check, parity with canonical’s own optional discriminator); Some(_) enforces an exact-parity mismatch check against the resolved record’s actual substrate/specific kind, mirroring handle_update’s entity.kind != *k / note kind checks (update.rs:200-201, :229-234).
prepare_update_entity_plan
Build an entity update plan from a typed patch. Proposal changesets use this entry point so their explicit description: null clear operation is preserved instead of being collapsed by raw verb deserialization.