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§
- Atomic
Delete Kind - Caller-supplied delete-kind expectation, resolved via the canonical
resolve_kind_specat the kkernel--atomicseam.khive-runtimemust not depend onkhive-pack-kg(packs depend on the runtime, not the other way around), so this is a plain substrate-level shape rather thankhive_pack_kg::handlers::KindSpecitself: the kkernel seam does the pack-awareresolve_kind_specresolution (which needs aVerbRegistry, unreachable from this crate) and passes down only whatprepare_deleteneeds to enforce the mismatch check. - Atomic
Update Kind - Caller-supplied update-kind expectation, resolved via the canonical
resolve_kind_specat the kkernel--atomicseam: the same patternAtomicDeleteKinduses. Without this check,update(kind="document", id=<concept>)would be canonicallyNotFoundbut the atomic path would ignore the explicit kind and mutate the resolved entity anyway.khive-runtimemust not depend onkhive-pack-kg, so this is a plain substrate-level shape rather thankhive_pack_kg::handlers::KindSpecitself: the kkernel seam does the pack-aware resolution and passes down only whatprepare_updateneeds to enforce the mismatch check.
Functions§
- apply_
post_ commit_ effects - Run every deferred
PostCommitEffectafter a committed atomic unit, outside any transaction. Re-fetches each target’s now-committed row and reuses the existingreindex_entity/reindex_note(FTS + embedding, same as the non-atomic path) for exact parity. - prepare_
add_ entity - Build the prepared plan for an
AddEntityproposal change. The entity row and FTS document are committed together; vector indexing is deferred until after commit because embedding may suspend.kindmust already be canonicalized by the caller because pack-aware resolution requires aVerbRegistry. - prepare_
add_ note - Build the prepared plan for an
AddNoteproposal change. Mirrorsprepare_add_entity’s shape and the samekind-already-canonicalized split.annotatesis out of scope: the proposalNoteDraftthis backs carries no annotates targets, unlikeKhiveRuntime::create_note’s general-purpose signature. - prepare_
delete expected_kind:Nonewhen the caller omittedkind(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, mirroringhandle_delete’sentity.kind != *expected/note.kind != *expectedchecks.- prepare_
op - Build the prepared
AtomicOpPlanfor one KG-substrate admissible op (update,delete,link,merge). Returns a loudRuntimeErrorforpropose/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:Nonewhen the caller omittedkind(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, mirroringhandle_update’sentity.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: nullclear operation is preserved instead of being collapsed by raw verb deserialization.