M3 cross-node elasticity proposal planner¶
raft::cross_node_elasticity is the policy-only planning layer for cross-node
graph/shard elasticity. It is deliberately separate from the placement catalog and
the online reshard actuator: a planner run produces proposals, while the existing
policy-gated placement/reshard owner remains the only component allowed to mutate
authority.
Inputs and admission¶
Each shard contributes a typed, bounded observation containing resident bytes and nodes, read/write rates, queue depth, fsync p99, CPU, fan-out, delta-stream estimate, placement state, followers, and placement epoch. Each node contributes observed load, hard per-axis limits, network throughput, object-tier headroom, and availability.
Pressure and target admission use all eight axes with fixed versioned weights. A node
must fit the projected shard in every axis and must remain inside queue, fsync, and
fan-out SLO limits. A proposal is rejected with a typed InsufficientCapacity,
SloRisk, BudgetExceeded, NoSafeTarget, CooldownActive, or
HysteresisNotCrossed reason when the corresponding bound is not met. The planner
does not infer capacity from resident-node count alone.
The input, proposal count, follower list, graph identifiers, copy window, network bytes, and budget are explicitly bounded. Controllers with larger inventories should submit deterministic windows rather than materialize an unbounded per-million-shard plan.
Restart and no-loss identity¶
Every move derives a stable move_id, snapshot ID, delta-stream ID, and fenced-cutover
ID from graph, shard, source, target, placement epoch, and move kind. A
MoveCheckpoint carries the phase, snapshot epoch, delta cursor, copied bytes, and
applied-delta count. Replanning an active checkpoint resumes the same identity; a
different target or placement epoch cannot overwrite it. The fence ID is surfaced as
the proposal's no-loss/deduplication token. No proposal is a completion receipt.
Closed-loop handoff¶
The intended control loop is:
- Collect bounded observations from engine/node telemetry.
- Run
CrossNodeElasticityPlanner::planon a canonical input ordering. - Persist proposals and abort evidence under the existing action policy.
- Let the placement/reshard owner execute snapshot → delta catch-up → fenced cutover, checkpointing progress durably.
- Re-read placement and telemetry, then plan again after cooldown/hysteresis.
Cold placement is represented explicitly. A read-demanded cold shard may receive a
Hydrate proposal whose cost includes object-tier bytes; an already hydrating,
snapshotting, delta-catching-up, or fenced shard is never duplicated by a fresh
proposal.