Found auditing the 0.17.39 → 0.18.2 wire delta before deploying. Inert today — nothing is broken and no action is needed for the current fleet. Filing because the hazard arrives with the first consumer that uses the flag, and by then the ordering is fixed.
What changed
5567732d ("mason: implement drain triad protocol") allocated envelope bit 7:
pub const FLAG_SUBSCRIPTION: u8 = 0b1000_0000;
Before that commit, bit 7 was a reserved-bit tripwire. The decoder's own doc comment at 5567732d~1:
/// A reserved flag bit (6-7) is set.
ReservedFlagBits { flags: u8 },
So any decoder built before this allocation rejects a frame carrying bit 7, rather than ignoring the bit it doesn't know.
Why it is inert right now
FLAG_SUBSCRIPTION appears zero times in crates/subc-core/src. The daemon never sets it — the doc comment describes it as client-declared ("a request credit the client explicitly declares as a held-open subscription"). A module therefore never receives it from the daemon, and no client currently speaks 0.21.0.
Live census on this box after deploying 0.18.2 — all four modules healthy, all behind the allocation:
MODULE WIRE daemon: 0.21.0
aft 0.13.0
claustrum 0.19.0
insula 0.19.1
magic-context 0.19.1
The ordering hazard
The first client built against 0.21.0 that sets FLAG_SUBSCRIPTION on a request routed to a module still on ≤0.20.0 will have that frame rejected by the module, not refused by the daemon. The splice is opaque by design: it rewrites channel and epoch and forwards the flags byte as-is, so it will faithfully deliver a bit the destination is built to treat as a protocol violation.
The failure surfaces at the far end, in a module whose author never opted into anything, as a decode error on a frame the daemon considered well-formed.
This is the same shape DAEMON_ORIGIN needed on bit 6, and it was handled there in two phases — #6 / #61: every decoder accepts the bit (Phase 1) before anything emits it (Phase 2), with a fleet census to confirm Phase 1 had actually landed everywhere. Phase 1 for bit 6 shipped as its own PR precisely so the emission change could not outrun it.
I can't find the equivalent for bit 7. Three possibilities and I can't distinguish them from the outside:
- The tolerance phase shipped somewhere I didn't find — in which case, point me at it and I'll close this.
- It's deliberate, because
FLAG_SUBSCRIPTION is only ever set on a connection whose negotiated version already proves bit-7 tolerance. If so, that invariant is worth stating at the constant, since the next reader will reach for the DAEMON_ORIGIN precedent and expect a phase.
- It was missed — in which case a Phase 1 (decoders accept bit 7, nothing emits) wants to land, and reach the fleet, before any subscribing client ships.
Why bit 7 is the last one
Bits 0–7 are now fully allocated: binary, priority (1–2), last, admission (4–5), DAEMON_ORIGIN, FLAG_SUBSCRIPTION. There is no reserved space left in the flags byte, so this is the final time this particular ordering question can be asked — and the first frame type that needs a new flag will need a different mechanism entirely.
No action needed today; the fleet is healthy and I'd rather ask early than find out from a module's decode error.
Found auditing the 0.17.39 → 0.18.2 wire delta before deploying. Inert today — nothing is broken and no action is needed for the current fleet. Filing because the hazard arrives with the first consumer that uses the flag, and by then the ordering is fixed.
What changed
5567732d("mason: implement drain triad protocol") allocated envelope bit 7:Before that commit, bit 7 was a reserved-bit tripwire. The decoder's own doc comment at
5567732d~1:So any decoder built before this allocation rejects a frame carrying bit 7, rather than ignoring the bit it doesn't know.
Why it is inert right now
FLAG_SUBSCRIPTIONappears zero times incrates/subc-core/src. The daemon never sets it — the doc comment describes it as client-declared ("a request credit the client explicitly declares as a held-open subscription"). A module therefore never receives it from the daemon, and no client currently speaks 0.21.0.Live census on this box after deploying 0.18.2 — all four modules healthy, all behind the allocation:
The ordering hazard
The first client built against 0.21.0 that sets
FLAG_SUBSCRIPTIONon a request routed to a module still on ≤0.20.0 will have that frame rejected by the module, not refused by the daemon. The splice is opaque by design: it rewrites channel and epoch and forwards the flags byte as-is, so it will faithfully deliver a bit the destination is built to treat as a protocol violation.The failure surfaces at the far end, in a module whose author never opted into anything, as a decode error on a frame the daemon considered well-formed.
This is the same shape
DAEMON_ORIGINneeded on bit 6, and it was handled there in two phases — #6 / #61: every decoder accepts the bit (Phase 1) before anything emits it (Phase 2), with a fleet census to confirm Phase 1 had actually landed everywhere. Phase 1 for bit 6 shipped as its own PR precisely so the emission change could not outrun it.I can't find the equivalent for bit 7. Three possibilities and I can't distinguish them from the outside:
FLAG_SUBSCRIPTIONis only ever set on a connection whose negotiated version already proves bit-7 tolerance. If so, that invariant is worth stating at the constant, since the next reader will reach for the DAEMON_ORIGIN precedent and expect a phase.Why bit 7 is the last one
Bits 0–7 are now fully allocated: binary, priority (1–2), last, admission (4–5),
DAEMON_ORIGIN,FLAG_SUBSCRIPTION. There is no reserved space left in the flags byte, so this is the final time this particular ordering question can be asked — and the first frame type that needs a new flag will need a different mechanism entirely.No action needed today; the fleet is healthy and I'd rather ask early than find out from a module's decode error.