From d0c2e7d6e170de91792d19772fcdd20e13c7548c Mon Sep 17 00:00:00 2001 From: wtclaude Date: Mon, 31 Aug 2026 19:19:48 -0500 Subject: [PATCH] feat(sidecar): protocol 5 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PROTOCOL_VERSION 4 -> 5, and nothing else. That is the whole change, and it is worth saying why. Protocol 5 adds fields to house.decay and vendor.listing and one new kind, account.login.result — and the sidecar needs no code for any of it. Every frame is persisted whole, the board tables index only the columns they already had, and there is no kind allowlist, so the new fields ride inside the stored JSON and the new kind lands in `events` like any other. No store migration this time, unlike v4. v4 needed one because it added a column to a board table that already existed; nothing here does. A bump that touches one constant is the EXPECTED cost of an additive protocol version in a dumb forwarder — the sidecar defines no schema for a frame's contents, so it needs no change when they grow. v4 was the exception. The doc comment records the three enrichments and why they were bumped together: a protocol bump costs a sidecar release, a republished bundle and an operator update on every shard, so a field left out costs a whole second round of that rather than a follow-up commit. Verified against the real shard: GET /health reports "protocol": 5, and all three enrichments arrived through the generic forward path — the decay schedule (with estimatedCollapse present only on the IDOC frame), the vendor fee block, and both outcomes of account.login.result. cargo fmt --check clean, clippy -D warnings clean, 39 tests passing. Docs: RunicGateway/docs link/v5.md. Co-Authored-By: Claude --- sidecar/src/main.rs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/sidecar/src/main.rs b/sidecar/src/main.rs index 347869f..bfaaaa4 100644 --- a/sidecar/src/main.rs +++ b/sidecar/src/main.rs @@ -52,7 +52,27 @@ use tracing_subscriber::EnvFilter; /// kinds are new, `GET /guilds` grows a `roster` key, and nothing existing changed shape. This is the /// first bump that also needed a **store migration** (`guilds.members`), because it is the first to /// add a column to a table that already exists rather than a whole new table; see `store::migrate`. -pub const PROTOCOL_VERSION: u32 = 4; +/// +/// v5 (Protocol 5): three enrichments that are additive in the same way again, bumped together +/// rather than one at a time because a protocol bump is not cheap here — it costs a sidecar +/// release, a republished bundle and an operator update on every shard, so a field left out costs +/// a whole second round of that rather than a follow-up commit. They are: +/// +/// * `house.decay` gains `ownerName` and a decay SCHEDULE — `nextStage`, `decayPeriodSec`, +/// `dynamicDecay`, and `estimatedCollapse` only where it is exactly knowable (at IDOC under +/// dynamic decay; at any stage under static decay, which has no randomness to wait out). +/// * `vendor.listing` gains `ownerAcct` — without which the frame names an owner nobody can +/// resolve to a person — and a `fees` object carrying the charge, the funds, the pay interval +/// and the resolved `dismissalAt`. +/// * `account.login.result` is a NEW kind: the verdict of a login, which the pre-existing +/// `account.login.attempt` structurally cannot carry (its EventSink fires before the auth +/// decision is made). +/// +/// **No store migration this time**, unlike v4. Every frame is persisted whole and the board tables +/// index only the columns they already had, so the new fields ride inside the stored JSON and the +/// new kind lands in `events` like any other. That is the dumb-forwarder property doing its job: +/// the sidecar defines no schema for a frame's contents and so needs no change when they grow. +pub const PROTOCOL_VERSION: u32 = 5; // Not `#[tokio::main]`: on Windows the SCM dispatcher takes over this thread and starts the runtime // itself, on its own thread, once the service actually begins. The runtime is built by whichever -- 2.49.1