ADR-0180 §1.5.4 + CLAUDE.md work-sequencing item 5 require these four
properties green on main before any core-rs/src/vault.rs change. They are
also the foundation ADR-0181 PR-5 (audio Delta-CRDT wiring) rides on.
T-1 set-equality of vault writes under shuffled ingest (+ idempotent
re-ingest at the content-addressed layer)
T-2 trace-hash invariance to vault order, + recall result-set invariance
to insertion order (the genuinely-failable half)
T-3 versor_apply non-commutativity (negative guard)
T-4 ProjectionHead.project purity across calls and threads
Findings (docs/audit/ADR-0180-t1-t4-findings.md):
- compute_trace_hash folds only vault_hits (a count), NOT vault contents, so
ADR-0180 §1.5.3's "re-sort vault state in content-addressed order" is
currently vacuous at the trace-hash layer; the live order-invariance
obligation is at recall() (result-set + count). Recommend amending §1.5.3.
- equal-score recall ties are index-sensitive; the Merge Kernel needs a
content-addressed tiebreak (mirrors ADR-0181 §2.2 merge key). Recommend
amending §2.2.
- append is genuinely semilattice-eligible; versor_apply is non-commutative.
7 passed; smoke suite green. No runtime/core mutation — tests + audit only.
89 lines
4.6 KiB
Markdown
89 lines
4.6 KiB
Markdown
# ADR-0180 §1.5.4 — T-1…T-4 Foundation: Findings
|
|
|
|
**Date:** 2026-05-29
|
|
**Branch:** `adr-0180-crdt-t1-t4-foundation`
|
|
**Tests:** `tests/test_adr_0180_crdt_foundation.py`
|
|
**Scope:** the Python-side pre-refactor obligations that must be green on `main`
|
|
before any `core-rs/src/vault.rs` change (CLAUDE.md work-sequencing item 5; ADR-0180 §1.5.4).
|
|
Also the foundation ADR-0181 PR-5 (audio Delta-CRDT wiring) rides on.
|
|
|
|
## Status
|
|
|
|
All four obligations are now covered and green (7 tests, all passing). Below
|
|
are the substantive findings discovered while grounding them against the
|
|
actual substrate, not the abstract baseline ADR-0180 §1.5 assumed.
|
|
|
|
## Finding 1 (load-bearing) — `compute_trace_hash` does not fold vault contents
|
|
|
|
ADR-0180 §1.5.3 point 2 worried that "the trace-hash reduction must consume
|
|
vault state in a content-addressed order … not in wall-clock arrival order"
|
|
and that §4.3 "cannot hold under [a time-driven flush] policy unless the
|
|
*hashing* step re-sorts."
|
|
|
|
**Actual code** (`core/cognition/trace.py:27`): `compute_trace_hash` folds
|
|
`vault_hits` — an **int count** — plus a serialized prefix of upstream turn
|
|
fields. It does **not** fold vault *contents* at all.
|
|
|
|
**Consequence:** the §1.5.3 "re-sort vault state in content-addressed order"
|
|
obligation is currently **vacuous at the trace-hash layer** — there is nothing
|
|
order-sensitive about vault contents in the payload to re-sort, because contents
|
|
are not in the payload. The CRDT merge may reorder the vault deque freely and
|
|
`compute_trace_hash` is unaffected, *provided* the recalled result *count*
|
|
(`vault_hits`) is order-invariant.
|
|
|
|
This shifts where the real obligation lives:
|
|
|
|
- It is **not** at `compute_trace_hash` today (T-2a confirms count-stability).
|
|
- It **is** at `recall()` — the count and content of recall results must be
|
|
order-invariant under a reordered deque. T-2b (`recall_result_set_invariant
|
|
_to_insertion_order`) pins this for distinct-score entries and is the
|
|
genuinely-failable half of T-2.
|
|
|
|
The §1.5.3 re-sort obligation becomes live only if/when vault contents (not just
|
|
a count) enter the trace-hash payload. **Recommendation:** ADR-0180 §1.5.3
|
|
should be amended to say the content-addressed-sort requirement applies to the
|
|
*recall result set* and to any *future* contents-bearing hash, not to today's
|
|
count-based `compute_trace_hash`.
|
|
|
|
## Finding 2 (edge) — equal-score recall ties are index-sensitive
|
|
|
|
`vault_recall` breaks score ties by ascending index (`vault/store.py`). Index
|
|
is assigned by storage order, so two entries with *exactly equal* CGA inner
|
|
scores can surface in an order that depends on insertion order. For distinct
|
|
scores (the common case, and what T-2b asserts) recall is order-invariant.
|
|
|
|
**Consequence for the CRDT merge:** the merge must content-address tie-scored
|
|
entries (e.g. sort by versor bytes) before assigning deque indices, or the
|
|
sub-50ms reorder window (ADR-0180 §3.2) could change which of two equal-score
|
|
entries a recall returns. This is exactly the role ADR-0181 §2.2's
|
|
`(canonical, ir, projection)` merge key plays for audio — it gives a total,
|
|
content-addressed order independent of arrival. **Recommendation:** ADR-0180's
|
|
Merge Kernel spec (§2.2) should adopt a content-addressed tiebreak for the
|
|
general path, mirroring ADR-0181 §2.2.
|
|
|
|
## Finding 3 (confirmed) — append is genuinely semilattice-eligible
|
|
|
|
T-1 confirms `VaultStore.store` is set-equal under any write permutation
|
|
(append never dedups/drops/order-mutates), and re-ingest is set-stable at the
|
|
content-addressed layer. This validates ADR-0180 §1.5.2 row 5 ("vault/store
|
|
write … commutative, associative, idempotent — semilattice-eligible") against
|
|
the real implementation. Note the deque itself appends duplicates (length
|
|
grows on re-ingest); idempotence holds at the content-addressed layer the CRDT
|
|
merge dedups on, not at the raw deque.
|
|
|
|
## Finding 4 (confirmed) — `versor_apply` is non-commutative; barrier is justified
|
|
|
|
T-3 confirms the sandwich `V·F·rev(V)` does not commute. This is the load
|
|
under ADR-0181 §2.1: in-chunk audio composition is a serialization barrier
|
|
*because* this product is order-sensitive, and only the order-invariant
|
|
`AudioCompilationUnit` crosses into the sharded merge layer. If a refactor ever
|
|
makes `versor_apply` commutative, T-3 fails loudly before the substrate can
|
|
wrongly shard it.
|
|
|
|
## Net
|
|
|
|
- T-1, T-3, T-4 hold against the real code as ADR-0180 §1.5.4 assumed.
|
|
- T-2 holds, but the obligation moved: the order-invariance that matters today
|
|
lives at `recall()` (result-set + count), not at `compute_trace_hash` (which
|
|
is count-only). Two small amendments to ADR-0180 §1.5.3 and §2.2 are
|
|
recommended above. Neither blocks the substrate; both sharpen it.
|