Skip to content

feat(ccb): the VaultStateV2 encoder, checked by an implementation that shares no code - #690

Merged
cryptskii merged 1 commit into
docs/rev15-release-policy-and-vault-statefrom
feat/ccb-vault-state-encoder
Aug 21, 2026
Merged

cryptskii merged 1 commit into
docs/rev15-release-policy-and-vault-statefrom
feat/ccb-vault-state-encoder

Conversation

@cryptskii

Copy link
Copy Markdown
Collaborator

Stacked on #689. Base is docs/rev15-release-policy-and-vault-state; merge that first.

Step 2+3+4 of the registry's ordering, in one PR because the encoder and its independent check are only meaningful together. Anchor V2 is the next PR, deliberately separate.

Scope: the closure, and nothing else

0x0001, 0x0002, 0x0004, 0x0005, 0x0007, 0x0009, 0x000A — exactly what c_n depends on.

TradeIntent, ReferenceWindow, B_M and M are not encoded despite being specified, because they are not in the closure. The five blocked routing/settlement classes get no placeholder encoders at all — that would be the encoder-defines-the-protocol failure the ordering exists to prevent, and it keeps 2b/2c free of churn here.

No decoder on the production side

CCB is not self-describing. A decoder written beside the encoder would share its assumptions and prove nothing, so parsing lives only in the independent implementation.

The independent check

tests/ccb_conformance.rs is an integration test, so the pub(crate) writers are unreachable by construction. It rebuilds every byte from the registry text in a different shape — explicit concatenation rather than a shared push buffer — so a transcription slip cannot be common to both.

It also parses CCB(V_n) back into fifteen fields, which is the only thing that demonstrates the bytes are uniquely readable.

The boundary that matters

Field 14 nests StorageSet in its frozen envelope-less layout; field 15 is a bare u32. If a generic "nested = envelope" helper ever wrapped S, the bytes would stay perfectly deterministic and stop being normative.

The parser asserts it consumes exactly its input with nothing trailing, that q reads as 4, and that splicing an envelope in front of S is detectable rather than silent.

Mutation-tested

Mutation Result
wrap S in the generic envelope 4 of 7 red, including the boundary test written for it
skip the absent-optional marker 3 of 7 red
restored 7 green

Refuse, don't repair

Per Req 3.2 — an unordered or equal token pair is rejected rather than swapped, a duplicate set element rejected rather than collapsed, fee_bps ≥ 10_000 rejected. Silently repairing any of them maps two distinct logical inputs onto one byte string.

Vectors

Genesis, market successor, terminal close, plus a populated encumbrance set — the last so the nested element encoding and its §2.4 ordering are exercised rather than left at an empty set, which is where a second implementation is most likely to differ. Insertion order is proven not to survive into the bytes.

storage_set_id is checked unchanged when reached through this module, since every deployed vault's anchor already commits one.

Local gate

  • cargo fmt --all -- --check clean
  • cargo clippy --all-targets -- -D warnings clean
  • cargo test -p dsm --lib — 1644 passed, 0 failed
  • cargo test -p dsm --test ccb_conformance — 7 passed, 0 failed

…t shares no code

Implements docs/papers/ccb-object-registry.md for exactly the transitive
encoding closure of VaultStateV2 — 0x0001, 0x0002, 0x0004, 0x0005, 0x0007,
0x0009, 0x000A — and nothing else. The routing and settlement classes are
absent on purpose: they are still blocked in the registry, and a placeholder
encoder for a class whose field table does not exist would be the
encoder-defines-the-protocol failure the ordering exists to prevent. Encoding
only the closure also leaves 2b and 2c room to land without churning this code.

The registry is the authority and this module implements it, not the reverse.
c_n = H(DSM/vault-state || CCB(V_n)) and h_0 = H(DSM/vault-state-parent/
genesis/v2 || vault_id) get their domain tags; h_n = c_{n-1} follows.

There is deliberately no decoder here. CCB is not self-describing, so a decoder
written beside the encoder would share its assumptions and prove nothing.

tests/ccb_conformance.rs is the independent side. It is an integration test, so
the pub(crate) writers are unreachable by construction, and it rebuilds every
byte from the registry text using a different shape — explicit concatenation
rather than a shared push buffer — so a transcription slip cannot be common to
both. It also PARSES CCB(V_n) back into fifteen fields, which is the only thing
that demonstrates the bytes are uniquely readable.

That parser exists for one boundary in particular. Field 14 nests StorageSet in
its frozen envelope-less layout and field 15 is a bare u32. If a generic
"nested object gets an envelope" helper ever wrapped S, the bytes would remain
perfectly deterministic and stop being normative. The test asserts the reader
consumes exactly its input with nothing trailing, that q reads as 4, and that
splicing an envelope in front of S is detectable rather than silent.

Both guards are mutation-tested. Wrapping S in the generic envelope turns 4 of
7 red, including the boundary test written for it. Skipping the absent-optional
marker turns 3 of 7 red. Restored, all 7 green.

Validity conditions refuse rather than repair, per Req 3.2: an unordered or
equal token pair is rejected instead of swapped, a duplicate set element is
rejected instead of collapsed, and fee_bps at or above the denominator is
rejected. Silently repairing any of them would map two distinct logical inputs
onto one byte string.

Vectors cover genesis, a market successor and the terminal close, and a
populated encumbrance set — the last so the nested element encoding and its
ordering are exercised rather than left at an empty set, which is where a
second implementation is most likely to differ. Insertion order is proven not
to survive into the bytes.

The storage_set_id construction is checked to be unchanged by reaching it
through this module, since every deployed vault's anchor already commits one.

Local gate: fmt clean, clippy --all-targets -D warnings clean, cargo test -p dsm
--lib 1644 passed, conformance 7 passed.
@cryptskii
cryptskii merged commit 0646830 into docs/rev15-release-policy-and-vault-state Aug 21, 2026
16 checks passed
@cryptskii
cryptskii deleted the feat/ccb-vault-state-encoder branch August 21, 2026 23:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant