Normative · Conformance module
SOVM-SYNC-RT — realtime push mode
Abstract
Section titled “Abstract”SSP/1 calls realtime mode optional in its own abstract and never says what optional means. There is no name for the omission, no obligation attached to it, and no way for a peer to tell a node that cannot hold a live subscription from one that can and has chosen not to. This document supplies the missing half.
It is deliberately the smallest module SOVM/1 will ever define, and that is
why it was written first. SOVM-SYNC-RT requires no new mechanism at all: the
declaration point, the mutual-establishment rule, the fail-closed refusal and the
correctness backstop are all already in SSP/1, published and frozen. What was
missing was a boundary, a name, and exactly one obligation — the obligation to
answer the handshake honestly — which section 5
shows is the only place where the omission can hurt anyone.
If a module this cheap cannot be expressed without editing the layer it belongs to, none of the harder ones can either. That is the proof this document exists to carry.
The requirement keywords and the encoding rules are the specification’s conventions; shared vocabulary is terminology.
1. Module basis
Section titled “1. Module basis”Every mechanism SOVM-SYNC-RT needs is already reserved in SSP/1, which is what makes
it a module rather than a change.
| What the module needs | Where SSP/1 already provides it |
|---|---|
| A declaration point | supports_realtime in the capability handshake |
| Mutual establishment | §33: realtime operates only when both peers advertised it |
| A refusal path for a node that did not | The fail-closed inventory: an unsolicited push without mutual supports_realtime is rejected, not dropped |
| A correctness backstop | §33.1: realtime is a latency optimization, never a correctness mechanism, and a realtime node runs its batch cycle anyway |
| A conformance clause that does not require it | Registry §55.1: eight items, none of which names realtime |
The last row is the one worth pausing on. Realtime is absent from the core clause, so a node without it arguably conforms today. That is not the same as being permitted to omit it, and the difference between those two states is the whole content of this document. When this page was written the omission was merely unmentioned — nobody had written it down, so it carried no obligations because nobody had stated any. Registry §55.2 has since written it down, stating both halves of the module’s clause, and with GR1 closed the omission is now permitted on the terms that clause states.
2. What the module comprises
Section titled “2. What the module comprises”SOVM-SYNC-RT comprises realtime mode — the
behaviour of holding a live subscription and pushing sync bodies over it —
specifically:
- the push behaviour described in the preamble of messages §33, excluding the receiver obligation quoted in §2.1;
- §33.1 batch remains the correctness backstop, as it applies to a node operating in realtime mode;
- §33.2 coalescing;
- §33.3 what realtime mode reveals;
- §33.4 scope of the mode;
- the requirement in transport §24 that a binding claiming realtime mode MUST additionally carry unsolicited one-way bodies.
2.1. The boundary against SOVM-SYNC
Section titled “2.1. The boundary against SOVM-SYNC”Three things that sit visually inside the module’s sections are not part of
the module, and a node that omits SOVM-SYNC-RT implements all three. Stating the
exclusions is more load-bearing than stating the inclusions, because each of
these would otherwise be swept from tier 1 into tier 2 by the accident of where
it is printed.
The refusal is not modular. Messages §33’s sentence that a receiver MUST reject an
unsolicited body on a session where the capability was not mutually established
is a row of the fail-closed inventory,
and the inventory is tier 1 in its
entirety.
It is precisely the behaviour an omitting node needs most, so it belongs to
SOVM-SYNC. Reject, not drop: the omitting node
surfaces the protocol error rather than absorbing it.
The handshake member is not modular; the ability to answer it true is.
Every node emits supports_realtime and every node parses a peer’s, in both
directions, whatever it implements. What SOVM-SYNC-RT governs is whether a node is
entitled to set it true. This distinction is not pedantry — a module defined as
“the member” would license an omitting node to leave the member out, and the
receiver’s fail-closed rule has nothing to act on when the member is absent.
The enumeration value is not modular either. realtime is a registered
transport mode. A node that omits the module
still knows the value, and must not treat it as unregistered — the fail-closed
rule for unregistered values is for values SOVM/1 never defined, not for
capabilities a peer has and this node does not.
This is the same cut SOVM-SEQ makes when it keeps
the member-side obligation to route Commits through the sequencer in
SOVM-OBJ while making only the capacity to serve
the role optional. What is optional is the work; what protects everyone else from
its absence never is.
3. Conformance
Section titled “3. Conformance”The requirements below bind an implementation that states its module set.
Registry §55.1 item 8 requires every
implementation to state one; what section 6 still withholds
is the entitlement to state one that leaves SOVM-SYNC-RT out.
3.1. A node that claims SOVM-SYNC-RT
Section titled “3.1. A node that claims SOVM-SYNC-RT”- It MUST implement §33 in full, including
§33.1’s periodic
batch cycle. An implementation whose only delivery path is push MUST NOT claim
SOVM-SYNC-RT; messages §33.1 is explicit that such an implementation has taken on an exactly-once obligation the transport cannot meet and will not converge. - It MUST advertise
supports_realtime: trueonly on a session whose binding can in fact carry unsolicited one-way bodies (transport §24). The claim is a property of the session, not a static property of the build: the same implementation reached over a binding that cannot hold a live connection, or over the mailbox — which §33.4 puts outside realtime mode entirely — advertisesfalsethere and is not in breach. - It MUST apply a pushed body through the same apply chokepoint as a solicited one. §33 already requires this and it is restated here because it is what makes claim 2 safe to rely on.
3.2. A node that omits SOVM-SYNC-RT
Section titled “3.2. A node that omits SOVM-SYNC-RT”- It MUST advertise
supports_realtime: falsein every capability handshake it sends. This is the module’s one new obligation and the reason the document exists; section 5 is the argument for it. - It MUST NOT send an unsolicited sync body on any session. This is already
required of it by §33 — a sender MUST NOT
push to a peer that did not advertise — and it holds symmetrically here:
having advertised
falseitself, mutual establishment is unreachable in either direction. - It MUST still emit and parse the
supports_realtimemember, MUST still reject an unsolicited body per the fail-closed inventory, and MUST still recogniserealtimeas a registered transport mode. None of the three is relaxed by the omission (§2.1). - Every session it takes part in therefore runs in batch mode, and that is the whole of the difference. No delivery semantics change: at-least-once delivery, idempotent apply, cursors, applied watermarks and convergence are identical. The cost is latency, and it falls on the two peers in the session.
3.3. What omission does not license
Section titled “3.3. What omission does not license”An omitting node has declined one delivery path. It has not acquired a lighter version of anything else, and in particular it holds the fail-closed inventory whole, the COSE profile unchanged, and every scope obligation. It also gains no relief from the batch cycle: batch was never the fallback for realtime, it was always the mechanism, and §33.1 says as much from the other direction.
There is no degraded realtime. A node either holds live subscriptions or it does not; there is no third state in which it holds them unreliably and says so. That absence is deliberate — a partial claim is the shape a downgrade takes.
4. Why tier 2
Section titled “4. Why tier 2”The tier test
admits a capability to tier 2 only if omitting it cannot weaken a security or
policy guarantee for a participant other than the node omitting it. Run
SOVM-SYNC-RT through it.
Stripping supports_realtime on-path — which an attacker can do, because the
handshake is unsigned and precedes authentication — degrades one session to
batch. Delivery semantics, cursors, idempotent apply and convergence are
unchanged, because §33.1
already requires the batch cycle to run underneath. The cost is latency, and it
is borne by the two peers in that session and by nobody else. That is a
legitimate local trade, and it is what the handshake is for.
SOVM-SYNC-RT is currently SOVM/1’s only tier-2 module. The tier exists for
capabilities shaped like this one, and the profiles
index is the record of how few of them there
are.
5. The hazard is the false claim, not the omission
Section titled “5. The hazard is the false claim, not the omission”The interesting failure in a negotiated capability is never the node that says
false. It is the node that says true and cannot deliver, and SSP/1 as first
published did not forbid it. Messages §33 now
does; this section records why it must.
Read the handshake and the original text of
messages §33 together. It constrained the
sender — it MUST NOT push to a peer that did not advertise. The fail-closed inventory
constrained the receiver — it MUST reject an unsolicited body where the
capability was not mutually established. Neither constrained a node that
advertises true without implementing the receiving side. supports_realtime
is documented as whether the sender can hold a live subscription, which
describes what the member means without, on its own, obliging the sender to
answer truthfully.
The consequence is not cosmetic, because §33 ties the durable cursor to the push:
A sender advances its durable cursor only on a successful push, solicited or not. A push that fails, or whose outcome the sender never observes, is re-offered by the batch path.
A node that advertised true and cannot receive has two behaviours available and
both are bad:
- It rejects the body. The fail-closed rule’s stated ground — that the capability was not mutually established — is false here, since the node established it itself. The peer sees a protocol error it cannot attribute, on a session it negotiated correctly. The mesh converges, by batch, but with a permanent error signal pointing at the wrong cause.
- It accepts and discards. The push succeeded as far as the sender can observe, so the sender advances its durable cursor. Messages §33.1’s backstop re-offers from that cursor, so the discarded events are not re-offered. Convergence fails, silently, and the batch path that was supposed to be the backstop is the thing carrying the loss.
The second is the whole reason §3.2’s first requirement is a MUST. It costs an implementation nothing — a node that omits the module hard-codes one boolean — and it converts the second behaviour from reachable to out of conformance.
Two things this argument does not claim. It is not a downgrade attack: an
on-path attacker who flips the bit the other way, true to false, only slows
the session, which is section 4’s point and the reason tier 2 is
correct. And it does not make honesty enforceable — a handshake member cannot be
made trustworthy by a rule, since the channel is unsigned. What the rule buys is
that the failure becomes a conformance defect with a name, detectable by a corpus
(GR3) rather than only in production by a mesh that has
already lost events.
6. Decision gates
Section titled “6. Decision gates”Three gates. GR1 is closed; GR2 and GR3 are open. They are not the same kind of gate as the blob extension’s, and the difference is worth naming rather than papering over: GB1–GB3 are empirical, because that extension defines a wire format that has to be measured. A conformance module defines no bytes, so its first gate is editorial and only the last two can be demonstrated.
GR1 normative adoption CLOSED (a) CLOSED: SSP/1 states the conformance clause as core plus the modules an implementation claims, naming SOVM-SYNC-RT (b) CLOSED: SSP/1 carries section 3.2's honest-advertisement requirement in the handshake section and the fail-closed inventory Both conjuncts hold: this document binds through SSP/1 itself, which is what the gate existed to ensure.
GR2 interoperability, both directions a claiming node and an omitting node converge over the same event corpus; the omitting node's sessions carry no unsolicited body in either direction; the claiming node's durable cursor never advances past an event its peer did not apply
GR3 false-claim detection a node advertising supports_realtime: true that discards pushed bodies is caught by the corpus, and the divergence is attributed to the false claim rather than to the batch path that surfaced it| Gate | State | Verdict |
|---|---|---|
| GR1 normative adoption | closed | verdict |
| GR2 interoperability, both directions | open | target |
| GR3 false-claim detection | open | target |
GR1 is the load-bearing one. This document is not an amendment and cannot become one, so what GR1 asks for had to be stated elsewhere, and its two conjuncts landed in different places.
The first is closed. Registry §55 states
conformance as core plus the modules an implementation claims, and
§55.2 names SOVM-SYNC-RT with both halves of
its clause. That is SSP/1 itself supplying exactly what the gate asks for.
The second is likewise carried by SSP/1 itself. §3.2’s honest-advertisement requirement does not live only on this page: messages §33 binds the sender’s advertisement in the handshake section, and the fail-closed inventory carries its two rows — a reader of SSP/1 meets the obligation where the capability is specified. Registry §55 is what lets an implementation act on §55.2’s clause.
GR3 depends on a conformance corpus. SSP/1’s now carries cases, but
none of them are SOVM-SYNC-RT’s:
they pin the change event’s bytes and the state a receiver materializes from
them, neither of which realtime mode changes, and
the fail-closed inventory including this
module’s two rows — but those execute under SOVM-SYNC, because the inventory is
tier 1 entire, so SOVM-SYNC-RT’s own partition remains empty. The harness that
would run this module’s vectors is partitioned by module and treats a claimed
module with zero executed vectors as an error rather than a pass
(Registry §55.4). That
is the machinery GR3 needs and not the evidence GR3 asks for: an empty partition
that fails loudly is still empty. A module claim nothing can test is a label, and
this document should not be read as claiming otherwise.
7. What this document does not do
Section titled “7. What this document does not do”- It does not amend SSP/1. Realtime mode’s normative text stays exactly where it is. This page points at sections; the sections keep their sentences.
- It is not what makes realtime optional. Registry §55.2 is. With GR1 closed, omission is permitted on the terms that clause states — this page remains the boundary drawn around the capability, not the permission slip.
- It does not define the tier-3 declaration.
SOVM-SYNC-RTis tier 2 and is reachable over a channel that already exists, which is the only reason it could be written before that slot is filled. Every tier-3 module named in the profiles index still waits on it. - It does not define a second protocol. A realtime push is a sync-exchange body over a held connection. There is no realtime message, no realtime cursor and no realtime state.
- It does not cover the object plane. Where SOP/1 shares the same held connection (§33.4), that traffic is SOP/1 control-plane messaging and is unaffected by whether this module is claimed.
- It does not set a policy on timing exposure.
§33.3 records that pushing at
production time is a timestamp on the wire and recommends a fixed flush cadence
where that matters. That trade stays a deployment policy, and omitting
SOVM-SYNC-RTis not a supported way to buy it — a node wanting timing cover configures the cadence rather than declining the module.