Repository navigation
docs(ccb): establish the CCB framework and object registry; finding 7 stays open - #686
Merged
Merged
Conversation
… stays open Finding 7 of the Rev 15 conformance delta is NOT closed by this document, and it now says so in its own header. What lands here is the framework, the namespace, and a complete gap inventory. Rev 15's commitments do not become independently derivable until the blocked classes are resolved, which is the work §7 schedules. The document is normative and encoder-free: no Rust, no reference encoder, no golden vectors. Its single reviewable question is whether the bytes are uniquely specified. Whether an implementation emits them is answered separately, so that a reference encoder cannot define the protocol by accident. The framework fixes what Req 3.1 requires but Rev 15 never supplies: a blob envelope of u16_be class and u16_be schema version, primitive encodings with digest32 distinct from bytes so a redundant length prefix cannot diverge, explicit presence markers that are always emitted, counted sets ordered by element encoding with duplicates invalid rather than collapsed, sorted maps, and nested objects inline by value rather than by digest. Sub-object-by-digest is rejected in the text, not just avoided. A digest is only well defined once its preimage is, so inserting policies by digest would move the same hole one layer down. Discriminants and field numbers come from one namespace table and are immutable once shipped: numbers are never recycled, fields never renumbered, changed semantics take a new schema version or a new class, and retired classes are burned. Without that rule the registry becomes the next source of the ambiguity it exists to close. Nineteen live classes. Five are fully specified, four are partial, ten carry only a class assignment. The ten are stated as blocked with the exact missing decision for each, rather than being given invented field tables. storage_set_id is absorbed exactly as it ships, including two deliberate deviations from the framework: no envelope, because the preimage begins with the domain tag and 0x00 separator that dsm_domain_hasher emits, and bare length-prefixed member ids with no element object class. Every deployed vault's signed anchor already commits an id under that construction. The class is frozen and marked must-not-be-cleaned-up. Class 0x0003 was briefly assigned to a StorageMemberId object before that was resolved, and is burned rather than reused — the immutability rule applied to the registry's own drafting. §7 schedules the remainder as three semantic amendments rather than one omnibus: DLV state and policy first because it unblocks Anchor V2, then routing and commitment, then settlement and evidence. It records that the beta policy family stays intentionally narrow — constant-product market execution and owner-local full close — and that the breadth of the existing Rust FulfillmentMechanism enum is not evidence that its variants belong in a Rev 15 P_M. A prerequisite is recorded inside the third amendment: A_B carries ordinary DSM successor material, and the repository's CanonicalEncode trait calls itself the single source of truth for canonical encodings while requiring only deterministic bytes per implementation. That is not a cross-implementation byte schema, so ordinary DSM successor CCB must be opened as a Core prerequisite and referenced, never restated ad hoc inside SoFi. A three-tier rule governs every field in every amendment: transcribe where Rev 15 already fixes the logical fields, absorb as shipped only where compatibility is itself protocol-significant, and design normatively where the spec only names a concept. In that third tier Rust is evidence, not authority. Called canonical cross-implementation commitment encoding throughout. DSM has no global consensus layer and the other term would import a model the protocol does not have.
cryptskii
force-pushed
the
docs/rev15-ccb-object-registry
branch
from
August 21, 2026 07:55
93ca5f9 to
d2c56d0
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Finding 7 is NOT closed by this PR, and the document says so in its own header. What lands here is the framework, the namespace, and a complete gap inventory. Rev 15's commitments do not become independently derivable until the blocked classes are resolved — that is the work §7 schedules as three separate amendments.
Merging it as a framework is deliberate: holding it open until all ten designs are solved would turn a clean, reviewable framework into an unreviewable protocol omnibus.
Normative and encoder-free by design — no Rust, no reference encoder, no golden vectors. The single reviewable question is are these bytes uniquely specified? Whether an implementation emits them is the next question, answered separately, so a reference encoder cannot define the protocol by accident.
docs/papers/ccb-object-registry.md, one file.Framework (§2) — complete, not blocked
Fixes what Req 3.1 requires and Rev 15 never supplies:
u16_be(class) ‖ u16_be(schema_version) ‖ fields…, ascending declared field number, not self-describing.digest32is deliberately distinct frombytes, because a 32-byte digest emitted asbytescarries a redundant length prefix a second implementation might reasonably omit. That is precisely the Req 3.2 divergence class.{"ab","c"}vs{"a","bc"}).Sub-object-by-digest is rejected in the text, not merely avoided: a digest is only well-defined once its preimage is, so inserting policies by digest moves the same hole one layer down.
Namespace immutability (§2.7)
One table, not ad hoc per section. Once an
(object_class, schema_version)ships, its discriminant and every field number are frozen — numbers never recycled, fields never renumbered, changed semantics take a new version or class, retired classes burned. Without this the registry becomes the next source of the ambiguity it closes.Honest status (§4)
Nineteen live classes:
0x0002,0x0004,0x0005,0x000B,0x00130x0006,0x000E,0x000F,0x0011The ten are blocked because Rev 15 names them without enumerating their contents —
P_Mis "the bounded market-fulfillment policy" and nothing more. §6 states the exact missing decision for each rather than inventing a field table. Writing one would settle protocol in this document exactly as writing an encoder first would settle it in Rust.The framework and namespace are not blocked on §6 and can be implemented against for the five specified objects immediately.
storage_set_idabsorbed as-shippedAdopted exactly, with two deliberate deviations recorded rather than hidden: no envelope, because the preimage begins with the domain tag and
0x00separator thatdsm_domain_hasheremits (verified in source); and bare length-prefixed member ids with no element object class. Every deployed vault's signed anchor already commits an id under this construction, so the class is frozen and marked must not be "cleaned up". A futureStorageSetV2may adopt the envelope under a new number.Class
0x0003was briefly assigned to aStorageMemberIdobject before §5.2 established that member ids are bare bytes. It is burned, not reused — the immutability rule applied to the registry's own drafting.What follows, recorded in §7
Three semantic amendments, not one omnibus, ordered by dependency:
VaultStateV2,P_M,B_M,P_R,Φ, finishingM. First, because it is what unblocks Anchor V2. The beta family stays intentionally narrow: constant-product market execution and owner-local full close. The breadth of the existing RustFulfillmentMechanismenum is not evidence its variants belong in a Rev 15P_M.Route,RouteSet,X,TradeDigest. One dependency cluster; an accidental transport field must not become canonical merely because it exists in protobuf.DlvProofMaterial,ConsumedDlvTransition,SettlementBundle,TraderAcceptance.A_Bderives from Rev 15, not from the bespokepost_rootreceipt it replaces.Then production encoder → independent conformance encoder/parser → golden vectors.
A prerequisite is recorded inside amendment 3.
A_Bcarries ordinary DSM successor material(C_T^+, σ_T^+). The repo'sCanonicalEncodemodule calls itself "Single source of truth for all canonical encodings" while the trait requires only "deterministic, unambiguous byte representation" — per-implementation determinism, not a cross-implementation schema (verified incommon/canonical_encoding.rs). If ordinary DSM successor CCB is not normatively specified elsewhere, it opens as a Core canonical-successor encoding prerequisite and SoFi references it rather than restating it.A three-tier rule governs every field: transcribe where Rev 15 fixes the logical fields, absorb as shipped only where compatibility is itself protocol-significant (the deployed
storage_set_id), design normatively where the spec only names a concept — and in that tier Rust is evidence, not authority.Anchor V2 stays blocked until
0x0001is unblocked:h_n = c_{n-1}is not computable withoutCCB(VaultStateV2), which is blocked transitively onP_M,P_RandΦ.Terminology
Canonical cross-implementation commitment encoding throughout. DSM has no global consensus layer; the only
consensusstring in the file is the sentence rejecting the term.