khive-vcs
KG versioning — content-addressed snapshot hashing and NDJSON-to-SQLite sync.
Git-native v1: KG state lives as sorted NDJSON files (entities.ndjson, edges.ndjson)
in a git repository. This crate provides the canonical hash that identifies a snapshot's
content, the sync routine that rebuilds a queryable SQLite database from those NDJSON
files, and remote-archive fetch with hash-pin verification. Branching, history, and push/pull
are git's job — there is no custom khive remote protocol.
Features
- Canonical SHA-256 snapshot hashing — deterministic, order-independent content hash
over entities and edges (
SnapshotId, prefixedsha256:<hex64>) - NDJSON-to-SQLite sync — atomic rebuild of a working database from NDJSON sources
- Remote archive fetch — sparse
git cloneof a remote KG archive with SHA-256 pin verification, fail-closed on mismatch - Validated wire types —
SnapshotIdand itsDeserializeimpl reject anything that isn't exactlysha256:+ 64 lower-case hex characters
Usage
use KgArchive;
use snapshot_id_for_archive;
Rebuilding a working database from NDJSON sources (used by kkernel sync):
use Path;
async
run_sync reads .khive/kg/{entities,edges}.ndjson under repo_root, validates every
edge relation before touching disk, builds the new database in a .tmp sibling file, and
renames it over db_path only on success — a crash or parse error leaves the previous
database intact. run_sync_remote(repo_root, &RemoteConfig, repin) fetches a remote KG
archive (sparse, depth-1 clone), verifies its content hash against RemoteConfig::pin
when set, and populates .khive/kg/remotes/<name>/ with a meta.json recording the
resolved commit and hash.
Semantics
SnapshotId::from_hash/from_prefixedare the only ways to construct one outsidesnapshot_id_for_archive; both reject anything but 64 lower-case hex characters.canonical_jsonsorts entities by UUID, edges by(source, target, relation), tags lexicographically, and object keys recursively — two archives differing only in insertion order hash identically; two differing inentity_typeor edge weight do not.VcsStatetracksnamespace,current_branch, andlast_committed_id— there is nodirtyflag; uncommitted changes are computed fresh via a DB-vs-NDJSON diff, not cached.KG_V1_COVERAGErecords that v1 snapshots cover entities and edges only; notes are excluded pending a note pack that defines versioned export/import/redaction/merge.
Where this sits
khive-vcs depends on khive-runtime, khive-storage, and khive-types, and is a
regular workspace member and published crate — not forward-deployed. kkernel consumes
it directly for the sync, kg status, and kg fetch subcommands.
khive-merge is the forward-deployed v2 semantic
merge layer that will consume khive-vcs's snapshot ancestry once ADR-039's LCA-walk
integration lands; today's merge path is git's own line-merge over sorted NDJSON.
Governed by ADR-010 (versioning strategy) and ADR-020 (git-native implementation).
License
Apache-2.0.