Liveness gates presence: route challenge and topology refresh only for a running incarnation #7

Merged
eureka merged 3 commits from hands/liveness-gates-presence into main 2026-11-14 04:28:07 +00:00
Owner

Cut spec idunn-reincarnation:cut_spec:cut-liveness-gates-presence.r1.

Cause

supervise_one_admitted_generation ran route challenge (supervise_admitted_route) and topology refresh (refresh_admitted_topology) for every admitted generation before workload.observe had said whether its incarnation was alive. A dead or parked incarnation was re-proved every tick. On Yggdrasil that was exactly 100 lines per 2 minutes each of the ghostlight write-lease line and the ghostlight/raven-muninn topology line, both targets stopped and lifecycle-braked. The pre-challenge write-lease ensure! bailed before record_failed_challenge, so nothing backed off either (route-continuity-cut F8 recorded it and it was never decided).

Change (src/control_plane.rs)

  • Deleted the two pre-liveness match blocks and the pre-challenge observe_exact verdict in supervise_admitted_route (lease driver is still built for the closure's post-proof check; lease health is decided once, in the liveness branch).
  • Re-inserted both calls inside if observation.is_some(), after the incident close, route then topology, with a doc comment naming F8. Bare eprintln! became report_once keyed route-supervision:<target> / topology:<target>, with clear_fault on Ok(_).
  • provisioning::replace_lifecycle_brake is now pub(crate) so a test can engage the brake; the routed fixture's lifecycle brake store points into the test world (same Missing behaviour as before otherwise).

Tests

  • a_parked_routed_target_is_not_route_supervised (negative, 100 ticks, stateful, dead, lease empty, brake engaged, route drifted: no reload/program, envelope byte-identical, no transaction, no route fault key)
  • a_dead_generation_does_not_take_odin_correlations (negative: neither a newer binding nor a non-binding reading is taken or reported)
  • a_running_generation_with_a_non_binding_correlation_is_reported_once (said once, cleared on withdrawal, adopted on a binding reading)
  • a_dead_unit_is_restarted_without_a_route_challenge (rewrite of a_failed_challenge_and_a_dead_unit_in_one_tick_do_not_lose_a_cas)

Mutation checks: moving the calls back before liveness fails the first, second and fourth; bare eprintln! instead of report_once fails the third; dropping clear_fault on Ok(false) fails the third.

Full lib suite as root in a bwrap sandbox: 695 passed, 3 failed. two_stop_then_start_transactions_never_both_enter_starting passes solo (load flake); the two host_actuator tests (ufw ... Bad port '0') fail identically on main 7eae1c4.

What this gives up

  • Route repair on a dead unit stops: a dead incarnation's route is no longer restored or re-proved; restart (continuity) re-routes through its own transaction.
  • A dead generation's route record freezes: status shows the last route record as it stood, display-only, until the incarnation runs again or a new generation is admitted.
  • Topology adoption and route challenge on a running generation now happen one tick after liveness is seen, not before it.
  • A supervision rejection that writes nothing is said once while it lasts (bare per-tick prints become report_once), so a recurring identical line is no longer a heartbeat.
  • HostUnobservable now also skips route and topology for that tick.

Brakes still gate mutation only (raven-muninn-brake-and-stop untouched).

🤖 Generated with Claude Code

Cut spec `idunn-reincarnation:cut_spec:cut-liveness-gates-presence.r1`. ## Cause `supervise_one_admitted_generation` ran route challenge (`supervise_admitted_route`) and topology refresh (`refresh_admitted_topology`) for every admitted generation before `workload.observe` had said whether its incarnation was alive. A dead or parked incarnation was re-proved every tick. On Yggdrasil that was exactly 100 lines per 2 minutes each of the ghostlight write-lease line and the ghostlight/raven-muninn topology line, both targets stopped and lifecycle-braked. The pre-challenge write-lease `ensure!` bailed before `record_failed_challenge`, so nothing backed off either (route-continuity-cut F8 recorded it and it was never decided). ## Change (src/control_plane.rs) - Deleted the two pre-liveness match blocks and the pre-challenge `observe_exact` verdict in `supervise_admitted_route` (lease driver is still built for the closure's post-proof check; lease health is decided once, in the liveness branch). - Re-inserted both calls inside `if observation.is_some()`, after the incident close, route then topology, with a doc comment naming F8. Bare `eprintln!` became `report_once` keyed `route-supervision:<target>` / `topology:<target>`, with `clear_fault` on `Ok(_)`. - `provisioning::replace_lifecycle_brake` is now `pub(crate)` so a test can engage the brake; the routed fixture's lifecycle brake store points into the test world (same Missing behaviour as before otherwise). ## Tests - `a_parked_routed_target_is_not_route_supervised` (negative, 100 ticks, stateful, dead, lease empty, brake engaged, route drifted: no reload/program, envelope byte-identical, no transaction, no route fault key) - `a_dead_generation_does_not_take_odin_correlations` (negative: neither a newer binding nor a non-binding reading is taken or reported) - `a_running_generation_with_a_non_binding_correlation_is_reported_once` (said once, cleared on withdrawal, adopted on a binding reading) - `a_dead_unit_is_restarted_without_a_route_challenge` (rewrite of `a_failed_challenge_and_a_dead_unit_in_one_tick_do_not_lose_a_cas`) Mutation checks: moving the calls back before liveness fails the first, second and fourth; bare `eprintln!` instead of `report_once` fails the third; dropping `clear_fault` on `Ok(false)` fails the third. Full lib suite as root in a bwrap sandbox: 695 passed, 3 failed. `two_stop_then_start_transactions_never_both_enter_starting` passes solo (load flake); the two `host_actuator` tests (`ufw ... Bad port '0'`) fail identically on main 7eae1c4. ## What this gives up - Route repair on a dead unit stops: a dead incarnation's route is no longer restored or re-proved; restart (continuity) re-routes through its own transaction. - A dead generation's route record freezes: status shows the last route record as it stood, display-only, until the incarnation runs again or a new generation is admitted. - Topology adoption and route challenge on a running generation now happen one tick after liveness is seen, not before it. - A supervision rejection that writes nothing is said once while it lasts (bare per-tick prints become `report_once`), so a recurring identical line is no longer a heartbeat. - HostUnobservable now also skips route and topology for that tick. Brakes still gate mutation only (raven-muninn-brake-and-stop untouched). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Cut the pre-liveness route and topology supervision and the pre-challenge lease verdict; re-insert both calls after the running-branch incident close, with report_once and clear_fault per target. Rewrite the dead-unit test, add four tests, point the routed fixture's lifecycle brake store into the world.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Applies Soul findings to cut-liveness-gates-presence: report_once+clear_fault
for the remaining per-tick eprintln sites in supervise_one_admitted_generation,
status marks a past-due challenge, tests for the unreadable-fragment and
HostUnobservable paths, F8 marked resolved in route-continuity-cut.md.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Status says how overdue a route challenge is, not a cause it cannot see.
The dead-generation topology test engages the lifecycle brake so every tick
reaches the gate. New pins: observe/lease/demotion/stale-incarnation/projection
repair said once and cleared; a running target with an empty lease is not
route challenged.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
eureka merged commit 506df0a81f into main 2026-11-14 04:28:07 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
GameCult/Idunn!7
No description provided.