Problem
UpdateConfig atomically swaps a PrecomputeConfig immediately, but it preserves the in-flight window for every same-scope update. Rotation later serializes that old state using whatever config is active at flush time.
This can mix physical-plan generations:
- a sketch created with old family/parameters can be labeled as the new
SketchType/AggID;
- the old series map can be looked up and emitted with new
AggregateBy/resource-key semantics;
- old observations can be emitted with new encoding, delta policy, metric name, temporality, sampling, or window size;
- the snapshot cache can use keys/bases from a different generation.
Only a scope flip resets state. The comment explicitly says other changes leave the window untouched.
Code:
In addition, cfgCopy := *chosen is shallow: slices and SketchParams remain aliased to caller-owned data, so the object behind the atomic pointer is not actually immutable.
MVP impact
The control channel stages plan versions, but the runtime does not preserve generation ownership of accumulated state. Activation can therefore produce frames whose plan lineage disagrees with the bytes inside them, defeating staged activation and BackendPlan/SID binding.
Acceptance criteria
- An active window is owned by an immutable
(plan_id, plan_version, aggregation/materialization identity) and is serialized only with that generation's config.
- Activation policy at a boundary is explicit: drain old generation, begin new generation, or reject an unsafe mid-window activation; never relabel old state.
- Family, sketch parameters, grouping/key shape, window semantics, sampling, encoding/delta base, and SID-affecting changes cannot hot-swap in place.
- Deep-copy/freeze all slice/map fields accepted from callers.
- Frame sequencing starts a new lineage and full checkpoint for the new generation.
- Add transition tests for every semantics-bearing field and a concurrent
UpdateConfig/Observe/Tick race test.
Problem
UpdateConfigatomically swaps aPrecomputeConfigimmediately, but it preserves the in-flight window for every same-scope update. Rotation later serializes that old state using whatever config is active at flush time.This can mix physical-plan generations:
SketchType/AggID;AggregateBy/resource-key semantics;Only a scope flip resets state. The comment explicitly says other changes leave the window untouched.
Code:
UpdateConfigfinishRotatereads the newly active configserializeSeriesderives identity/encoding from that configIn addition,
cfgCopy := *chosenis shallow: slices andSketchParamsremain aliased to caller-owned data, so the object behind the atomic pointer is not actually immutable.MVP impact
The control channel stages plan versions, but the runtime does not preserve generation ownership of accumulated state. Activation can therefore produce frames whose plan lineage disagrees with the bytes inside them, defeating staged activation and BackendPlan/SID binding.
Acceptance criteria
(plan_id, plan_version, aggregation/materialization identity)and is serialized only with that generation's config.UpdateConfig/Observe/Tick race test.