Normative · Part
Constants, COSE profile and extension policy
49. Protocol version
Section titled “49. Protocol version”| Field | Value |
|---|---|
ssp_version (message envelopes) |
1 |
Signed records do not carry ssp_version; they are versioned by their protected
content type, which the signature covers.
50. The SSP/1 COSE profile
Section titled “50. The SSP/1 COSE profile”Every durable signed structure in SSP/1 is a COSE_Sign1 under
the substrate signature profile. This page restates
none of it — a restatement is exactly the copy that can drift, and the
substrate part is the single home both layers bind to. A standalone SSP/1
implementer reads one substrate page and acquires no obligation to implement
any part of the object plane.
What belongs here is only SSP/1’s instantiation of the profile:
- SSP/1 signs
COSE_Sign1records only. It defines no encryption records, because it seals nothing: confidentiality is the transport binding’s responsibility. external_aadon every SSP/1 record is the verifier’s own 16-bytemesh_id— mesh binding without transmission, the narrowest instance of the context principle. The object plane binds richer per-record context; SSP/1 records need only the mesh.
Where this page or any SSP/1 page appears to state a rule about signatures, it is stating a consequence for an SSP/1 structure, never an independent rule. Where the two appear to conflict, the substrate governs.
51. Registered content types
Section titled “51. Registered content types”Durable records are distinguished by protected content type. One content type, one payload schema, one purpose.
| Content type | Record | Defined in |
|---|---|---|
sovm/ssp-event-v1 |
Change event | data model |
sovm/ssp-vouch-v1 |
Vouch certificate | identity |
sovm/ssp-role-v1 |
Role assignment (chained) | scope |
sovm/ssp-custodian-v1 |
Custodian designation (chained) | scope |
sovm/ssp-capability-v1 |
Capability requirement (chained) | scope |
sovm/ssp-modules-v1 |
Per-node module set (chained) | scope |
sovm/ssp-binding-v1 |
Transport binding | transport |
sovm/ssp-eventkey-v1 |
Event-signing subkey | data model |
sovm/ssp-succession-v1 |
Identity succession | identity |
Admission and removal authorization records use the chained-record schema shared
with the object plane; where SOP/1 is deployed the definition of
sovm/sop-authorization-v1 (SOP/1 section
5.7) applies unchanged.
The record takes this profile, and the sop prefix names the layer its
normative home sits in, not the profile it is signed under.
52. Raw domain-separation labels
Section titled “52. Raw domain-separation labels”The dividing principle: durable records use COSE content types; transient in-ceremony transcript signatures use raw labels. A transcript signature never outlives its ceremony and is never stored or forwarded, so wrapping it in a COSE envelope would add structure with nothing to protect.
| Label | Used in |
|---|---|
sovm-mesh-id-v1 |
mesh_id derivation |
sovm-mesh-pair-v1 |
Pairing transcript |
HKDF info strings, scoped by their input key rather than globally:
info |
Used in |
|---|---|
pair-session |
Pairing session key |
pair-sas |
SAS derivation |
53. Enumerations
Section titled “53. Enumerations”| Space | Values | Reserved |
|---|---|---|
operation |
upsert, delete |
purge |
Pairing method |
qr, sas, vouch |
— |
| Policy layer | system, role, user |
— |
| Policy effect | allow, deny |
— |
| Transport mode | batch, realtime |
— |
There are no encoding, hash or signature tag enumerations: those axes are versioned by content type, and the hash convention is fixed – BLAKE3 over exact signed bytes, SOVM/1’s single hash namespace.
54. Extension policy
Section titled “54. Extension policy”A new record or a changed payload schema ships as a new content type version
(sovm/ssp-event-v2). Because the content type is a protected header, a receiver
that does not know it fails closed on the signature path, never by guessing.
Adding a member to a message envelope requires a new ssp_version. There is no
ignore-unknown-members rule.
Adding a value to an enumeration requires a new revision of this document. A receiver encountering an unknown value MUST fail closed for that item.
New raw labels MUST be registered here before use. An unregistered label is a latent cross-protocol signature-confusion risk that no automated check can find, since nothing knows to look for it.
Changing any value in this registry is a wire change. It is never a revision of an existing version.
55. Conformance
Section titled “55. Conformance”Conformance is core, plus the modules you claim. An implementation states a set of conformance modules and is held to the core clause below plus one clause per module in that set. It is not held to the clauses of modules it did not claim, and it does not get to be silent about them: a module is claimed or it is not, and both are statements.
55.1. The core clause
Section titled “55.1. The core clause”Every implementation claiming SSP/1 conformance, whatever else it claims, MUST:
- implement every fail-closed behaviour in the inventory;
- implement the substrate signature profile with no extensions;
- document its floor partition;
- document its implementation-chosen limits;
- document its key custody posture per platform;
- state which transport binding it uses and what that binding provides;
- state which limitations it has closed locally, if any, and how;
- state its module set — every module it claims, from the profiles index, by identifier.
The floor of every module set is SOVM-BASE —
the substrate, root identity and the host-interface obligations — and it is
tier 1: no revision may reclassify any part of it. On top of the floor an
implementation MUST claim at least one whole layer:
SOVM-SYNC, whose clause is the SSP/1 pages,
or SOVM-OBJ, whose clause is the SOP/1 pages,
or both. Claiming SOVM-OBJ without SOVM-SYNC is the host-only profile:
the implementation supplies the host interface from
elsewhere and is a conforming object-plane host — the substitutability the
specification index defends, stated as a claim a harness can execute rather than as
a document boundary.
Item 8 is deliberately an obligation on every implementation rather than only on the ones that omit something: a module set nobody states is a module set nobody can check, and the hazard is the false claim, not the omission.
55.2. The module clauses
Section titled “55.2. The module clauses”One clause per module, and each says both halves: what claiming it obliges and what omitting it obliges. A module with only the first half would be a feature list; the second half is what makes a narrower implementation checkable rather than merely smaller.
An implementation MUST NOT claim a module it does not implement. A claim is the only thing a reader has, so a false one is worse than a narrower set honestly stated: the narrower set is checkable and the false claim is not. Section 55.4 is where that obligation becomes testable rather than merely asserted.
| Module | Claiming it means | Omitting it means |
|---|---|---|
SOVM-SYNC |
Implement the SSP/1 pages in full | Supply the host interface from elsewhere and claim SOVM-OBJ — the host-only profile of section 55.1 |
SOVM-OBJ |
Implement the SOP/1 pages in full, including the base fail-closed rules | Run without an object plane; fail closed on every object-plane content type, object kind and format identifier |
SOVM-SYNC-RT |
Implement realtime mode in full, and answer supports_realtime in the handshake true only where that is true |
Answer supports_realtime: false — answered, not withheld — and run every session in batch mode |
SOVM-BLOB |
Implement the blob extension in full, including its decision gates’ obligations | Fail closed on the blob object kind and the SOP-BLOB-1 object format, per the fail-closed rule in section 54 |
SOVM-IROH |
Implement the iroh binding in full — every row of transport §24 met as that page states | Run another live binding satisfying transport §24, or run mailbox-only; transport §23 requires at least one transport role either way |
Each omittable module here has a mechanism that carries the omission. They differ in whether the omission is permitted yet, and that difference is not a technicality.
SOVM-BLOB is omittable today. An extension is not a capability inside a
specification, so the nothing-lands-in-place rule does not reach it: omission
was always the default state and adoption is the act.
Its carrying mechanism is the existing unknown-value rule, which an
implementation that never adopted the extension already satisfies.
SOVM-SYNC-RT is omittable on exactly the terms its row states. Both conjuncts
of gate GR1 are discharged: the row
above names the module and says what claiming and omitting it oblige, and
§3.2’s
honest-advertisement obligation is carried where a reader who never opens the
module page still finds it — in
the handshake section and in
the fail-closed inventory.
Its carrying mechanism is not in question: the capability handshake, which
SSP/1 already requires a receiver to enforce.
SOVM-IROH is omittable today, on transport’s own terms. A specific
binding was never mandatory:
transport §23
requires a mesh to run at least one transport role, not this one. Its
carrying mechanism is the core clause’s item 6 — every
implementation states which binding it uses and what that binding provides —
so an omission is visible as a different statement rather than as silence.
55.3. What a mesh may require
Section titled “55.3. What a mesh may require”SOVM-SEQ, SOVM-DEL
and SOVM-HIST are tier 3: the mesh states which of
them its members must implement, and the statement is enforced. An
implementation MAY omit any of the three and still conform. What it cannot do
is join a mesh — or, where the requirement is per-domain, a domain — that
requires one it omits: it is refused at admission, not admitted degraded.
| Module | Omitting it means |
|---|---|
SOVM-DEL |
Fail closed on the delete object kind; MUST NOT accept an APPEND_DELETE table; refused admission to any APPEND_DELETE domain |
SOVM-SEQ |
Cannot hold the sequencer role; no participation in sequenced domains |
SOVM-HIST |
Current-epoch domain keys only; every admission it performs is FORWARD_ONLY |
Two carriers hold that statement, and which one a mesh uses follows from whether it has an MLS control group to put it in. The tier is defined by the four properties a carrier must have, not by either mechanism.
| Carrier | Where the requirement lives | Checked |
|---|---|---|
| Capability declaration | Authenticated MLS group state, where SOP/1 is deployed | At admission and at every membership-security transition that touches the leaf, by the same library that enforces membership |
| Capability requirement chain | A per-mesh chained record, needing no group state | At admission, at sender-side policy, and per event at the apply chokepoint |
A mesh carrying both is subject to both, and a member must cover the union. The second carrier is enforced by each peer independently rather than by the membership library, which is a real weakening relative to the first — bounded to a partition around a misbehaving peer rather than a mesh-wide downgrade, and stated in full where the mechanism is. A mesh that has an MLS control group should use the first.
Under the second carrier a member’s own claim is not documentation but a signed module-set record, which is what section 55.1 item 8 states as an obligation and what section 55.2’s false-claim rule governs.
The append-only mesh is therefore a real, conformant profile — and so is a
mesh that requires deletion of every member. Two honest limits travel with
that sentence. The first: neither carrier attests behaviour. A declaration is
re-checked at every membership-security transition that touches the leaf and a
requirement chain at every record delivery, so on both carriers a degraded
node’s claim is attributable — but on neither is the degradation detected, since
what is re-checked is the claim and not the conduct behind it. The open gate on
the profiles index says what that costs. The second:
within an
APPEND_DELETE domain the
§14.4 tombstone obligation
remains invariant for every admitted node regardless.
SOVM-SYNC-RT does not belong on this list:
it is tier 2, per-session, and
section 55.2 states the terms on which it may be
omitted. A tier-2 capability MUST NOT appear in a mesh’s requirement, on
either carrier.
55.4. The corpus
Section titled “55.4. The corpus”The conformance corpus is partitioned by the same module identifiers, so an implementation runs the cases of the modules it claimed. Two properties of that harness are load-bearing for this clause, and they point in opposite directions:
- a case whose module was not claimed is reported as skipped, never silently dropped, so a narrower claim visibly tests less rather than invisibly testing less;
- claiming a module the corpus executes zero cases for is an error, not a pass, so a claim nothing checked cannot be mistaken for a claim that held.
Neither property depends on which modules are omittable today. The harness implements the partition; section 55.2 and section 55.3 decide what may be put through it.
SSP/1’s own coverage reaches the wire format, the fail-closed refusals, and the state a receiver materializes from the event sets the corpus names, and stops there. See limitations.
55.5. An unregistered identifier is not a claim
Section titled “55.5. An unregistered identifier is not a claim”A module identifier that the registry does not register is not a conformance claim. A verifier presented with one MUST reject the claim, rather than ignore the identifier and evaluate the remainder of the set. Ignoring it is precisely the failure the registry exists to prevent: an unregistered module and a module the verifier happens not to check are otherwise the same thing.
Section 55.1 obliges an implementation to state its module set and to be honest about it; this clause is what the reader of such a set does with an identifier it does not recognise. That is a verifier obligation rather than an implementation one, which is why it stands apart.