Bring the docs/zig/** decision package and README 'Native Substrate Direction' section into main, and record ADR-0196 (Accepted) as the binding ratification. The doctrine is explicitly NOT a wholesale Zig rewrite. It establishes a ring architecture (Python = semantic source of truth; Rust = incumbent algebra backend; Zig = Ring 1 native-substrate candidate only) and the G0-G8 adoption gate ladder. Zig may enter only by clearing gates against a locked reference contract; default-by-availability is forbidden. ADR-0196 forward-references ADR-0180 as the first G1 instantiation (the CRDT contract lock / ZC-0 slice). No Zig code is authorized.
6.5 KiB
Zig Guidance — Delta-CRDT Substrate
Status: doctrine / prototype candidate
Component: Delta-CRDT arena, delta, join, merge kernel, content-addressed ordering
Primary governing ADR: ADR-0180
This is the strongest near-term Zig candidate in CORE.
The CRDT substrate is not semantic cognition. It is the mechanical substrate for concurrent modality write accumulation: thread-local arenas emit canonical deltas, and an explicitly mounted merge kernel folds those deltas into a global Vault-visible state without making final recall approximate or arrival-order dependent.
Why this component is suitable for Zig
The CRDT substrate wants properties Zig is good at providing:
- explicit allocator ownership;
- small native surface area;
- deterministic byte-level ordering;
- stable C ABI;
- edge-native build story;
- predictable memory layout;
- no garbage collector;
- no hidden runtime;
- precise caller-owned buffer contracts.
This is not a broad language preference. It is a substrate fit.
Existing contract to preserve
ADR-0180 states that the semilattice claim holds only at the vault/store layer, not at versor_apply, not at field/propagate, and not at trace reduction. The CRDT substrate must shard write accumulation only.
Required law:
ProjectionHead.project pure signal projection
versor_apply non-commutative, do not shard unless serialized
field propagation not a CRDT merge
vault/store.write semilattice-eligible write accumulation
recall result ordering content-addressed, not arrival-addressed
The existing Rust substrate already implements the conceptual shape:
ArenaEntry { versor: [f32; 32], provenance: Vec<u8> }
Delta { entries: sorted/deduped ArenaEntry list }
LocalArena { thread-local write cache }
merge_kernel(deltas) -> canonical Delta
Zig may challenge this substrate only by preserving the same laws.
What should be in Zig
A Zig CRDT lane should include:
core-zig/src/crdt/entry.zig
core-zig/src/crdt/arena.zig
core-zig/src/crdt/delta.zig
core-zig/src/crdt/merge.zig
core-zig/src/crdt/hash.zig
core-zig/src/crdt/ffi.zig
include/core_crdt.h
ArenaEntry
Should represent one content-addressed write:
versor: [32]f32
provenance: []const u8
The content key is:
raw IEEE-754 f32 bits of all 32 components
+ provenance bytes
The substrate must not compare floats numerically for canonical ordering. It must compare bytes/bits to avoid platform-dependent NaN, -0.0, and +0.0 behavior.
LocalArena
Should be thread-local and share-nothing.
Allowed:
push local entries
snapshot to Delta
clear/drain if explicitly requested by owner
report pending count
Forbidden:
write global Vault
spawn hidden merge thread
normalize entries
repair bad versors
infer epistemic status
call object-store/S3/cloud code
Delta
A Delta must be canonical:
entries sorted by content key
byte-identical duplicates removed
stable independent of insertion order
merge_kernel
The merge kernel must be explicit, not hidden.
Required behavior:
input: list of Deltas
output: one canonical Delta containing their union
law: permutation-invariant
law: duplicate-delta idempotent
law: content-addressed ordering only
Minimum C ABI sketch
typedef struct CoreCrdtArena CoreCrdtArena;
typedef struct CoreCrdtDelta CoreCrdtDelta;
typedef struct CoreCrdtError {
int code;
char message[256];
} CoreCrdtError;
CoreCrdtArena* core_crdt_arena_new(void);
void core_crdt_arena_free(CoreCrdtArena* arena);
int core_crdt_arena_push(
CoreCrdtArena* arena,
const float versor[32],
const unsigned char* provenance,
unsigned long provenance_len,
CoreCrdtError* err
);
int core_crdt_arena_snapshot(
const CoreCrdtArena* arena,
CoreCrdtDelta** out_delta,
CoreCrdtError* err
);
void core_crdt_delta_free(CoreCrdtDelta* delta);
int core_crdt_delta_join(
const CoreCrdtDelta* a,
const CoreCrdtDelta* b,
CoreCrdtDelta** out_delta,
CoreCrdtError* err
);
int core_crdt_merge_kernel(
const CoreCrdtDelta* const* deltas,
unsigned long delta_count,
CoreCrdtDelta** out_delta,
CoreCrdtError* err
);
int core_crdt_delta_hash(
const CoreCrdtDelta* delta,
unsigned char out_sha256[32],
CoreCrdtError* err
);
This is illustrative, not final. The final ABI must be ratified before implementation is considered supported.
What must stay out of Zig
The CRDT substrate must not own:
- epistemic status promotion;
- review decisions;
- teaching proposal admission;
- pack ratification;
- semantic normalization;
- recall scoring policy beyond canonical store order;
- object-store sync;
- hidden background execution;
- modality compilation semantics, except when called as a separate compiler component.
The CRDT substrate is storage-order law, not cognition.
Required proof obligations
C-1 — Commutativity
join(a, b) == join(b, a)
C-2 — Associativity
join(join(a, b), c) == join(a, join(b, c))
C-3 — Idempotence
join(a, a) == a
C-4 — Permutation invariance
merge_kernel([d1, d2, d3]) == merge_kernel(any_permutation([d1, d2, d3]))
C-5 — Duplicate re-ingest is no-op
merge(existing, already_seen_delta) == existing
C-6 — Recall order invariance
Equal-score recall must not depend on wall-clock arrival. The canonical merged order must be content-addressed so tie breaks are replay-stable.
C-7 — No hidden global mutation
Tests must prove that pushing to an arena never mutates the global Vault. Only explicit merge publication may alter the global visible state.
Migration sequence
- Keep Rust implementation as incumbent.
- Add Python tests that pin CRDT laws against the current behavior.
- Add Zig prototype behind
CORE_CRDT_BACKEND=zig. - Compare Zig against Rust/Python reference on canonical fixtures.
- Add benchmark only after parity passes.
- Promote only if Zig wins on ABI, deployment, memory, or performance.
Promotion criteria
Zig should become the preferred CRDT substrate only if it demonstrates:
- equal or stronger deterministic law coverage;
- simpler C ABI for modality compilers and edge runtime;
- explicit allocation lifecycle that is easier to audit than the incumbent;
- no loss in exact recall behavior;
- observable merge state;
- clean failure when absent or stale.
Until then, Zig remains a prototype lane, not a replacement.