Skip to content

Limitations

Read this before implementing. Every gap here is known; none is a discovered defect, and listing them is cheaper for everyone than letting a reader find them by writing code.

1. The gap that blocks production: no conformance corpus

Section titled “1. The gap that blocks production: no conformance corpus”

There is no conformance corpus yet. Until golden input-to-output vectors exist — canonical CBOR encodings, COSE signatures over synthetic keys, HLC sequences, materializer scenarios — two independent implementations cannot demonstrate agreement, and “conforming” is a claim nobody can check.

A predecessor protocol has a corpus, but it is not transferable: its expected values pin content addresses computed under a different canonical encoding, a different hash, a retired identifier and an unauthenticated event model, so every vector is wrong for SSP/1 by construction. The SSP/1 corpus must be generated fresh, and SHOULD be generated from the specification prose by an independent tool rather than extracted from the implementation under test.

Until it exists, implementers SHOULD treat cross-implementation testing as their own responsibility and SHOULD publish disagreements.

2. Security properties SSP/1 does not provide

Section titled “2. Security properties SSP/1 does not provide”

Removing a node stops it receiving future data. It does not and cannot reach back and unlearn what the node already read. Any product language implying otherwise is wrong.

operation: "purge" is reserved and unimplemented. Deletion is logical: a tombstone hides a row from queries and clears its column values, but the event log retains the history required for resurrection rebuild to work.

An implementation MUST fail closed on a purge request rather than pretend it succeeded. Where erasure is a legal requirement, the mechanism that satisfies it is key destruction at a layer above this one, not a protocol operation here.

2.3. No revocation announcement on the wire

Section titled “2.3. No revocation announcement on the wire”

A removal is a local trust-store change plus, where SOP/1 is deployed, a group membership operation. SSP/1 defines no record announcing a revocation to peers.

So a peer learns that a node was removed only when it independently receives the policy change. Until then it may continue accepting events from a node the authority has removed. The records channel makes this cheap to close in a future revision — a chained revocation record is the obvious shape — but it is not closed in this one, and implementations SHOULD minimize the window by their own means.

2.4. Metadata is not protected by this layer

Section titled “2.4. Metadata is not protected by this layer”

SSP/1 defines message semantics, not transport confidentiality. A mailbox operator sees payload sizes, timing, and which site_id is talking to which. Where that matters, the transport binding must address it; nothing on this page does.

2.5. A compromised authorized node is fully trusted

Section titled “2.5. A compromised authorized node is fully trusted”

Every node in a mesh can author events for any table within its scope. There is no intra-mesh privilege separation for mutable state: a node authorized to write a table can write anything to it. Per-event signatures make authorship attributable, not constrained.

These were considered and cut rather than overlooked.

Excluded Why
Batch bundle format A predecessor pinned a compressed columnar bundle whose identifier is a hash of its bytes, but pinned no writer settings, compression level, row-group size or encoding rules. Two conforming senders therefore cannot produce the same identifier, which makes a content-addressed bundle unimplementable as specified.
PAKE-based pairing A predecessor offered a password-authenticated key exchange with no ciphersuite: no group, no seeds, no message encoding, no key schedule. The short-authentication-string and QR authenticators in identity cover the same use case with fully specified constructions.
Custom fleet-key transport envelope A predecessor sealed relay payloads under a shared symmetric mesh key. Where SOP/1 is deployed, MLS supersedes that design, and republishing it here would put two competing transport-security mechanisms in one protocol family. SSP/1 specifies the mailbox contract instead and leaves confidentiality to the binding.
Legacy plaintext relay payloads A predecessor’s first epoch carried plaintext over transport security only. SSP/1 has one profile and no legacy mode.

Three gaps this page originally listed as production blockers have been closed by converging SSP/1 onto the family’s COSE/CBOR substrate, and are recorded here so the spec’s evolution is visible rather than silent:

Former gap Closed by
Trust resumption after first pairing The default binding profile: transport binding records signed by the identity key, and a hard-fail resumption rule with no prompt-on-mismatch
Pairing message encoding A deterministic CBOR offer encoding and a normative ceremony state machine
Role layer had no wire representation Chained role assignment records over the shared chained-record schema

The same convergence removed an entire failure class: event_id is now derived from the received bytes rather than transmitted, so a transmitted-versus-recomputed identifier mismatch can no longer occur.

5. Notes for anyone comparing against a predecessor

Section titled “5. Notes for anyone comparing against a predecessor”

SSP/1 draws on an earlier, deployed mesh synchronization protocol. It is not wire-compatible with it, and the differences are deliberate:

Change Reason
Deterministic CBOR ([RFC 8949]) instead of canonical JSON The predecessor pinned one language runtime’s float formatting, which had already produced divergent content addresses between a reference implementation and a port. CBOR also keeps the integer/float distinction that JSON canonicalization schemes collapse.
COSE_Sign1 for every durable record The predecessor used hand-assembled signature pre-images with separator bytes and length prefixes; COSE removes the bespoke framing and its injectivity hazards.
Events are signed The predecessor specified verification but never defined a signature construction, so events applied unauthenticated.
event_id is derived, not transmitted The predecessor transmitted a content address whose pre-image excluded encoding tags, so two events differing only in a tag collided and idempotent apply silently discarded one.
One identifier (site_id), carried once in the protected kid The predecessor carried two identifiers, one already retired, and duplicated the sender field between envelope and event.
One hash (BLAKE3, over exact signed bytes) The predecessor mixed hash families across a hand-built pre-image; SSP/1 shares SOP/1’s single convention and hash namespace.
In-band ssp_version; content types version signed records The predecessor delegated versioning entirely to a transport identifier.
One profile The predecessor threaded a deployment-epoch axis through most of its sections; that is a migration concern, not a protocol axis.