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.

Structs§

PostCommitEffectsReport
Everything one committed unit’s post-commit pass produced. A failing effect never discards the outcomes of the effects that completed, so callers can still disclose their model failures and truncation advisories.
PostCommitEmbeddingOutcome
Metadata produced by a reindex effect whose fail-closed stages succeeded.
ReindexModelFailure
An eligible-model failure after the note and its lexical index committed.

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.
ReindexModelStage
The eligible-model stage that prevented a note’s vector refresh.

Functions§

apply_post_commit_effects
Run every deferred PostCommitEffect after a committed atomic unit.
apply_post_commit_effects_with_failures
Failure-preserving form of super::apply_post_commit_effects_with_report. Runs every effect, collecting the outcomes of those that completed and the error of each that did not, instead of replacing the outcomes with the first failure.
apply_post_commit_effects_with_report
Embedding-reporting form of apply_post_commit_effects. Re-fetches each target’s now-committed row outside any transaction and reuses the existing reindex_entity/reindex_note (FTS + embedding, same as the non-atomic path) for exact parity. Returns the typed embedding outcome for each reindex effect so callers can preserve truncation advisories and partial model failures instead of discarding them after commit. Model failures remain best-effort; lexical indexing and excluded-model cleanup errors propagate. When any effect fails, the other effects’ outcomes are dropped with the returned error; apply_post_commit_effects_with_failures keeps both.
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). Task notes must pass the GTD pack hook before this or prepare_op("update", ..); neither runs it.
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.
prepare_update_from_note_snapshot
Build an atomic update plan from the exact note snapshot already supplied to a pack update hook. Persistence is guarded by that snapshot’s revision and deletion marker, so hook normalization cannot race a second read. The caller must first run the registry normalizer/validator against this snapshot. This shared canonical/atomic seam prepares all patch fields with the owning kind’s property policy (the value VerbRegistry::prepare_note_update_policy returned for this snapshot), then derives and attaches the owner’s typed graph effects. It returns the projected note and one atomic plan, preserving the caller’s operation index.
validate_note_update_expected_kind
Enforce a caller’s explicit update-kind discriminator against a resolved note before any pack hook can inspect or normalize the request. Canonical KG dispatch performs this mismatch check before its hook; the atomic adapter calls this same helper to preserve that error ordering.