Today — OxidePhysicalCodec payloads carry a magic prefix and const VERSION: u8 = 1 (crates/oxidelake-planner/src/codec.rs:25, checked at :236-241), then a postcard encoding of GpuNode (:28-72). postcard is not self-describing: a field added or reordered in GpuNode without bumping VERSION decodes silently into wrong parameters. predict joins the UDF list only when the feature is on (crates/oxidelake-compute/src/udf.rs:233-237): an executor built without it accepts a plan the client planned with it and fails at execution time.
Why it is worth fixing — rolling upgrades and mixed-feature fleets are ordinary in production; today they fail late or, worse, wrong.
Fix — derive a compile-time schema fingerprint (hash of CARGO_PKG_VERSION + the enabled feature set, or a const computed from a canonical GpuNode encoding) into the payload header; the worker logs and refuses registration with a scheduler whose fingerprint differs; a codec test snapshots the canonical encoding of every GpuNode variant (insta) so a change to GpuNode without a VERSION bump fails CI.
Done when — the insta snapshot exists; a worker built with --features predict refuses a scheduler built without it, tested with two binaries in tests/cli.rs.
Today —
OxidePhysicalCodecpayloads carry a magic prefix andconst VERSION: u8 = 1(crates/oxidelake-planner/src/codec.rs:25, checked at:236-241), then apostcardencoding ofGpuNode(:28-72). postcard is not self-describing: a field added or reordered inGpuNodewithout bumpingVERSIONdecodes silently into wrong parameters.predictjoins the UDF list only when the feature is on (crates/oxidelake-compute/src/udf.rs:233-237): an executor built without it accepts a plan the client planned with it and fails at execution time.Why it is worth fixing — rolling upgrades and mixed-feature fleets are ordinary in production; today they fail late or, worse, wrong.
Fix — derive a compile-time schema fingerprint (hash of
CARGO_PKG_VERSION+ the enabled feature set, or aconstcomputed from a canonicalGpuNodeencoding) into the payload header; the worker logs and refuses registration with a scheduler whose fingerprint differs; a codec test snapshots the canonical encoding of everyGpuNodevariant (insta) so a change toGpuNodewithout aVERSIONbump fails CI.Done when — the insta snapshot exists; a worker built with
--features predictrefuses a scheduler built without it, tested with two binaries intests/cli.rs.