PROTOCOL NOTES / 09
Wire reference
Field widths, control authority, and implemented constants.
Implemented software · Physical qualification pending
Start with the exact bytes
Unsigned binary integers use network byte order unless specified otherwise. Base64 uses the canonical unpadded URL-safe alphabet. JSON signatures cover exact body.dump() bytes. Unknown message types do not gain authority.
A 20-byte media header
Public synthetic fixture. Select a field to highlight its bytes; the complete explanation remains below.
| Field | Byte offsets | Meaning |
|---|---|---|
| Version | 0–0 | RWCP version 2. |
| Hop budget | 1–1 | Remaining forwarding budget; reduced across relays. |
| Age | 2–3 | Accumulated media age in milliseconds. |
| Ride tag | 4–11 | First eight SHA-256 bytes of the textual ride ID. |
| Hop sequence | 12–19 | Directional per-hop sequence used with authentication/replay handling. |
Public test-only values; payload demonstrates envelope layout, not a valid SRTP ciphertext
Discovery advertisement
| Offset | Bytes | Field |
|---|---|---|
| 0 | 1 | Version 2 |
| 1 | 8 | Ride tag |
| 9 | 32 | Raw public Ed25519 key |
| 41 | 1 | Root roster index; 255 denotes unassigned admission state |
| 42 | 1 | Path length |
| 43 | path length | Roster indexes from root to advertiser |
| p | 4 | Root pulse |
| p+4 | 4 | Advertisement serial |
| p+8 | 1 | Child capacity flag |
| p+9 | 2 | Cumulative cost, at most 12,000 |
| p+11 | 64 | Ed25519 signature of every preceding byte |
Control message catalogue
| Type | Additional body fields | Authorization and propagation |
|---|---|---|
join | name, key public PEM, token | Open admission, matching secret, signed source identity; relayed to organizer; at most 24 pending candidates |
roster | version:uint32, name, open:boolean, members[] | Organizer only, increasing version; fixed after seal/start; can reach pending links |
stream | stream descriptor below | Admitted source after seal; increasing source control seq; admitted active propagation/state sync only |
sync | None | Admitted sealed source requests descriptor re-publication; no microphone activation |
heartbeat | muted:boolean, active:boolean, root, pulse:uint32, path[], cost, optional media:{ssrc,nextIndex}, optional transmission | Admitted source, propagated; route refresh only if source is direct neighbor and shape valid |
source_status | transmission | Admitted sealed source; current SSRC and ordered source progress; propagated on active admitted edges |
feedback | reports[], links[] | Admitted receivers; source reports at most 11, link reports at most 16; propagated, advisory adaptation |
ping | stamp:uint64 monotonic ms, token:uint64 | Direct TLS neighbor only; signed, never flooded |
pong | ping:uint64 echoed stamp, token:uint64 | Direct neighbor only; must match one outstanding single-use ping; never flooded |
leave | None | Signed local admitted departure; propagated; marks source unavailable, does not remove/rekey roster or end others' sessions |
path_offer | root, path[], pulse:uint32, cost, revision:uint64, parentGeneration:uint64 | Direct admitted neighbor only; ordered fresh signed route; never flooded |
handoff_prepare | attempt:uint64, generation:uint64, revision:uint64 | Direct child asks candidate parent; tuple binds current offer, excludes known cycles; creates bounded lease |
handoff_ready | Same tuple | Candidate parent after bidirectional probes; child still needs its own proof |
handoff_activate | Same tuple, optional rollback:true | Child commits candidate; rollback requires newer generation on retained old active-child edge |
handoff_ack | Same tuple | Candidate confirms its active-child role; child publishes new path only after exact match |
handoff_abort | attempt, generation, optional revision, optional reason | Exact current tuple only; release candidate/preparation, not unrelated links |
handoff_retire | attempt, generation | Exact old active-child tuple; drain then scoped release |
An exact signed-body example
This public test vector demonstrates deterministic serialization. It is a synthetic ping, not a live ride token or captured user message.
{"ride":"000102030405060708090a0b0c0d0e0f","seq":7,"source":"56475aa75463474c0285df5dbf2bcab73da651358839e9b77481b2eab107708c","stamp":1234,"token":9,"type":"ping","v":2}Implemented constants
These values are extracted from the generated protocol reference at build time. Timer and acoustic defaults remain physically unqualified.
| Production name | C++ type | Value |
|---|---|---|
version | std::uint8_t | 2 |
invitationPrefix | char | "rideweave:v2:" |
discoveryPrefix | char | "rideweave-v2-" |
awareKeyLabel | char | "rideweave-aware-v2:" |
hopKeyLabel | char | "rideweave-hop-v2:" |
exporterLabel | char | "EXPORTER-RideWeave-hop-v2" |
controlPort | unsigned | 38471 |
maxControlBytes | std::size_t | 16384 |
maxQueuedControlBytes | std::size_t | 131072 |
maxMediaBytes | std::size_t | 1280 |
mediaHeaderBytes | std::size_t | 20 |
hopMacBytes | std::size_t | 16 |
maxMembers | unsigned | 12 |
initialHopBudget | unsigned | 12 |
mediaAgeMs | std::uint64_t | 180 |
mediaQueueMs | std::uint64_t | 40 |
ingressPackets | std::size_t | 12 |
egressPackets | std::size_t | 32 |
handshakeMs | std::uint64_t | 5000 |
pingIntervalMs | std::uint64_t | 1000 |
linkSuspectMs | std::uint64_t | 3000 |
linkDeadMs | std::uint64_t | 6000 |
linkRecoveryPongs | unsigned | 2 |
discoveryFreshMs | std::uint64_t | 6000 |
rootFreshMs | std::uint64_t | 4500 |
pathEstablishMs | std::uint64_t | 25000 |
handoffProbeMs | std::uint64_t | 1000 |
handoffProbeIntervalMs | std::uint64_t | 250 |
handoffProbeAttempts | unsigned | 3 |
handoffAckMs | std::uint64_t | 1000 |
handoffDrainMs | std::uint64_t | 500 |
preparationLeaseMs | std::uint64_t | 2000 |
probeBytes | std::size_t | 66 |
probeRequest | std::uint8_t | 128 |
probeReply | std::uint8_t | 129 |
parentBetterMs | std::uint64_t | 2000 |
parentHoldMs | std::uint64_t | 1500 |
routeCostMax | unsigned | 12000 |
adjacentCostMax | unsigned | 1000 |
adjacentCostMin | unsigned | 5 |
adjacentUnknownCost | unsigned | 50 |
adjacentLossCost | unsigned | 200 |
improvementNumerator | unsigned | 4 |
improvementDenominator | unsigned | 5 |
discoveryPruneMs | std::uint64_t | 15000 |
feedbackFreshMs | std::uint64_t | 3000 |
bitrateRecoveryMs | std::uint64_t | 10000 |
bitrateLow | int | 16000 |
bitrateInitial | int | 24000 |
bitrateHigh | int | 32000 |
lossSevere | double | 0.08 |
lossDegraded | double | 0.03 |
lossHealthy | double | 0.01 |
rttDegradedMs | unsigned | 120 |
rttSevereMs | unsigned | 250 |
jitterDegradedMs | unsigned | 100 |
jitterHealthyMs | unsigned | 80 |
jitterInitialMs | int | 60 |
jitterMinimumMs | int | 40 |
jitterMaximumMs | int | 120 |
receiverSilenceMs | std::uint64_t | 200 |
receiverReanchorMs | std::uint64_t | 250 |
maximumPlcFrames | unsigned | 3 |
sourceHintFreshMs | std::uint64_t | 3000 |
dtxStartupMs | std::uint64_t | 2000 |
dtxHangoverMs | std::uint64_t | 1000 |
dtxQuietMs | std::uint64_t | 1500 |
dtxAnalysisFreshMs | std::uint64_t | 20 |
dtxCallbackGapMs | std::uint64_t | 30 |
dtxTransitionWindowMs | std::uint64_t | 200 |
dtxAcousticFallbackMs | std::uint64_t | 10000 |
dtxRapidExitMs | std::uint64_t | 2000 |
dtxReversalWindowMs | std::uint64_t | 30000 |
dtxSessionReversals | unsigned | 3 |
dtxProbabilityMax | float | 0.05f |
dtxRawMaxDbfs | float | -45.0f |
dtxProcessedMaxDbfs | float | -55.0f |
dtxTransitionDb | float | 6.0f |
mediaReceiveBudget | unsigned | 16 |
mediaSendBudget | unsigned | 128 |
mediaMailboxPackets | std::size_t | 1024 |
controlDedupEntries | std::size_t | 4096 |
hopReplayWindow | std::uint64_t | 1024 |
Authority: Wire reference; generated constants; public test vectors. Public examples are synthetic. This guide is maintained against the private implementation; it does not imply access to its source.