Commit: 2f26d91 · Finding: ARCH-04
Problem
crates/state/src/materialize.rs has three catch-all arms with inconsistent behaviour:
| Line |
Arm |
Effect on unknown EventKind |
materialize.rs:39 |
_ => panic!("genesis event must be CreateServer") |
Hard panic |
materialize.rs:99 |
_ => {} |
Silent no-op |
materialize.rs:167 |
_ => {} |
Silent no-op |
materialize.rs:300 |
_ => None (in required_permission) |
No permission check |
Adding a new EventKind variant will compile, apply cleanly to zero state on every peer, and silently diverge across peers that have different versions. Existing #201 tracks the required_permission arm; this issue is broader — three arms with three different policies in the same determinism-critical file.
The genesis-check policy diverges too: crates/state/src/dag.rs:140 returns Err(InsertError::NotGenesis) for the same condition that materialize.rs:39 panics on.
Fix
- Replace every
_ => arm in materialize.rs with an exhaustive match so new variants produce a compile error.
- Align the genesis-check policy: either both
dag.rs and materialize.rs return an error, or both panic — pick one.
- Consider adding
#[non_exhaustive] + #[deny(non_exhaustive_omitted_patterns)] on EventKind to force the compiler to flag missing arms at the crate boundary.
Supersedes/refines #201 — close #201 once this lands.
Obvious? No — touches every mutation handler and requires care to avoid breakage. Not auto-PR'able as a single batch.
Commit:
2f26d91· Finding:ARCH-04Problem
crates/state/src/materialize.rshas three catch-all arms with inconsistent behaviour:EventKindmaterialize.rs:39_ => panic!("genesis event must be CreateServer")materialize.rs:99_ => {}materialize.rs:167_ => {}materialize.rs:300_ => None(inrequired_permission)Adding a new
EventKindvariant will compile, apply cleanly to zero state on every peer, and silently diverge across peers that have different versions. Existing #201 tracks therequired_permissionarm; this issue is broader — three arms with three different policies in the same determinism-critical file.The genesis-check policy diverges too:
crates/state/src/dag.rs:140returnsErr(InsertError::NotGenesis)for the same condition thatmaterialize.rs:39panics on.Fix
_ =>arm inmaterialize.rswith an exhaustive match so new variants produce a compile error.dag.rsandmaterialize.rsreturn an error, or both panic — pick one.#[non_exhaustive]+#[deny(non_exhaustive_omitted_patterns)]onEventKindto force the compiler to flag missing arms at the crate boundary.Supersedes/refines #201 — close #201 once this lands.
Obvious? No — touches every mutation handler and requires care to avoid breakage. Not auto-PR'able as a single batch.