feat(mesh): typed fence-rejection taxonomy on MeshError

Adds NoActiveLease, OwnerMismatch, and FutureGeneration alongside
StaleGeneration so every fence-visible reject is a typed variant, never
a generic Transport(..) — Wren's chaos-gate ruling: live kill-9 /
partition / replay evidence must be unambiguous, and the harness
counters (mesh_fence_rejections_total{reason=...}) key off these.

Purely additive, non-serialized: the wire-level fence signal remains
GoodbyeReason::StaleGeneration in wire.rs — zero wire-shape change.
Field naming per Wren: NoActiveLease carries frame_owner_runtime_id
(the frame's *claimed* owner; no current owner exists by definition).
Consumed by the session-directory lane's validate_fenced_header().

Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
This commit is contained in:
npub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67d
2026-07-08 10:34:15 -04:00
co-authored by Tyler Longwell
parent 93bec73809
commit 446a5a0f46
+30
View File
@@ -74,6 +74,36 @@ pub enum MeshError {
frame_generation: u64,
known_generation: u64,
},
// The three variants below complete the fence-rejection taxonomy alongside
// `StaleGeneration` (Wren's chaos-gate ruling: every fence-visible reject
// is a typed variant, never a generic `Transport`, so live kill-9 /
// partition / replay evidence is unambiguous). Counter surface:
// `mesh_fence_rejections_total{reason=...}` with reasons
// `stale_generation` | `no_active_lease` | `owner_mismatch` |
// `future_generation`. None of these are serialized — the wire-level fence
// signal remains `GoodbyeReason::StaleGeneration`.
#[error("no active lease for session {session_id}: frame generation {frame_generation}, known generation {known_generation}, claimed owner {frame_owner_runtime_id}")]
NoActiveLease {
session_id: uuid::Uuid,
frame_generation: u64,
known_generation: u64,
/// The owner the *frame* claimed — there is no current owner by
/// definition when no live lease exists.
frame_owner_runtime_id: RuntimeId,
},
#[error("owner mismatch for session {session_id} generation {generation}: frame owner {frame_owner_runtime_id} != current owner {current_owner_runtime_id}")]
OwnerMismatch {
session_id: uuid::Uuid,
generation: u64,
frame_owner_runtime_id: RuntimeId,
current_owner_runtime_id: RuntimeId,
},
#[error("future generation for session {session_id}: frame {frame_generation} > known {known_generation}")]
FutureGeneration {
session_id: uuid::Uuid,
frame_generation: u64,
known_generation: u64,
},
#[error("mesh is disabled (BUZZ_MESH=off)")]
Disabled,
#[error("transport: {0}")]