docs(decisions): D-192 — drop PROTOCOL_VERSION lockstep handshake

Records the decision to remove the per-snapshot version field and the
PROTOCOL_VERSION constants on both server and client. Rationale: in our
subprocess deployment the client and server always ship together, so the
mismatch guard has only ever caught dev-time forgetfulness — and even a
future networked path is better served by a one-time connection-protocol
handshake than per-snapshot stamping. Implementation tracked in #868.
This commit is contained in:
2026-04-21 09:48:36 +02:00
parent 8cd5405427
commit 3a074cb3fd
+11 -1
View File
@@ -749,6 +749,16 @@ Technical foundation decisions that constrain implementation: engine, client-ser
- **Dissent:** None.
- **Cross-reference:** [D-166](architecture.md#d-166) (development cascade — Phase 3), [D-036](content.md#d-036) (Sova as canonical setting), [D-093](content.md#d-093-sova-transit-district--spatial-layout-and-district-topology) (Sova spatial layout), [D-094](#d-094) (district hierarchy), [D-095](content.md#d-095) (Horizon stations), [D-170](#d-170) (HUD visibility/implant apps), [D-169](#d-169) (implant component library), [D-181](economics.md#d-181-signal-vocabulary) (signal vocabulary/visibility ladder), [D-174](economics.md#d-174-shadow-economy-layer) (shadow economy intensity), [D-175](economics.md#d-175-corporation-taxonomy-and-prerequisite) (corporation taxonomy), [D-138](content.md#d-138-llm-re-voicing-pipeline-for-npc-voice) (Gemma 2 voice pipeline)
### D-192: Drop PROTOCOL_VERSION lockstep handshake
- **Decision:** Remove the `version` field from the snapshot envelope, the `PROTOCOL_VERSION` constants on both server (`server/src/bridge/types.rs`) and client (`client/scripts/protocol/protocol.gd`), and the version-mismatch guard in `Protocol.decode_snapshot()`. Genuine schema mismatches surface as MessagePack decode errors or missing-field errors at the consumer; that signal is sufficient for our deployment model.
- **Rationale:** The version constants were designed for a network deployment where client and server can ship out of sync. Our actual deployment is a subprocess: the Godot client launches the Rust server it was built with. They are *always* in sync at runtime — the version check has never caught a real mismatch in the field, only dev-time forgetfulness. The cost has been measurable: every protocol-shaping sprint requires bumping two constants in lockstep, and we accumulated tautological tests asserting `PROTOCOL_VERSION == N` (deleted in sprint 36 — see ticket from this D-record). Removing the handshake makes the per-sprint cost zero. **Reversibility:** When/if networked multiplayer arrives (no firm date — see [D-005](#d-005-architecture-godot-client--rust-server-via-subprocess)), the natural fit is a one-time handshake at connection time (a single client-version vs. server-version exchange in the connection protocol), not a per-snapshot version stamp. So even the multiplayer path doesn't argue for keeping the per-snapshot field — that field would be doubly redundant once a connection-time check exists. The design space hasn't been narrowed.
- **What we lose:** A single eager, human-readable error at connect time ("client v22 ↔ server v23"). A genuine dev-time schema drift will now surface as a downstream decode/missing-field error, possibly seconds into a session rather than at handshake.
- **What we keep:** All field-presence and roundtrip tests in `test_protocol_bridge.gd`, `test_signal_sprint24.gd`, etc. — these cover the *behavior* the version constant was meant to gate. Decode failure in `Messagepack.decode()` still rejects malformed payloads.
- **Raised by:** Jeroen, sprint-36 client triage. Triggered by stale `test_protocol_version_is_19` assertions failing across two suites after the v23 bump, requiring mechanical edits in both places to "fix."
- **Dissent:** None.
- **Cross-reference:** [D-005](#d-005-architecture-godot-client--rust-server-via-subprocess) (subprocess model — always co-shipped).
---
*53 decisions. Last updated: 2026-04-15 (D-191 §8 amendment — markers.json canonical format is pixel space `[row, col]` arrays against a `512 × 256` grid, following the D-094 amendment pattern; lat/lon is a display-time derivation)*
*54 decisions. Last updated: 2026-04-21 (D-192 — drop PROTOCOL_VERSION lockstep handshake, sprint 36 client triage)*