Raised as N1 in the round-6 review of #774 (#766). Not a defect today — the premise is true as of this writing, verified twice — but it is load-bearing prose with nothing underneath it, and its decay would be silent.
The premise
Exactly one fine steering worker (LocalPlanner) is constructed per client process.
Verified mechanically, by the reviewer and independently by me:
LocalPlanner::spawn is reached only via Walker::new;
- the sole production
Walker::new is in ActionLoop::new;
- the sole production
ActionLoop::new is in run_login_flow, inside the Ok(..) arm of the retry loop, which unconditionally return Ok(()) after run_gameplay_phase — and the slots are moved into it, so a second pass round that loop would not compile;
run_login_flow itself is called once, from ServerModel::run.
An unrelated comment in login.rs reaches the same conclusion for a different field ("no code path re-enters login after gameplay today").
Why it matters
NavStatus.local_planner_dead is latched and worker-scoped. The agent-facing documentation calls it session-scoped, and that name is defended as accurate precisely because the two spans coincide under this premise. At least four sentences rest on it directly:
| where |
sentence |
crates/eqoxide-ipc/src/lib.rs (field doc) |
"…exactly one fine worker exists per process and 'latched forever' and 'latched for this worker' coincide." |
crates/eqoxide-ipc/src/lib.rs (field doc) |
"…which is why the agent-facing docs call the field session-scoped." |
crates/eqoxide-http/src/observe.rs |
"…it reads as session-scoped from outside only because exactly one fine worker is built per process." |
docs/http-api.md |
"…exactly one fine worker is built per client process, so from out here the two are the same span." |
Several more ("this clear is a no-op in production", "on today's single-Walker process") depend on it more weakly.
Why it decays silently
There is no guard, no test and no E0027-style net over the single production Walker::new. The claim exists only as prose. The day an in-process relogin lands — which is the exact shape #774 hardened Walker::new against — those four sentences become false, the agent-facing name becomes wrong, and nothing in the tree goes red.
The obvious candidate is not one. a_new_walker_does_not_inherit_a_previous_workers_death_766 (eqoxide-nav) constructs a second Walker deliberately, over a deliberately dirty row. It cannot be the thing that fails when a second Walker appears in production, because building a second one is its whole method.
Suggested shape
The repo already uses source-scanning guards for premises of this kind (steering.rs's citation scan, slot.rs's two scans, action_loop.rs's include_str! of docs/http-api.md). The natural form here:
a scan asserting exactly one non-#[cfg(test)] Walker::new( call site in the tree, whose failure message names the four sentences above and says "the session-scoped name is now wrong; revisit them".
Two design notes for whoever picks this up:
- Scanning must exclude
#[cfg(test)] regions, or the B9 test's own construction defeats it on day one.
- Per the
guard reach lesson, whoever writes it should run it and show it going red on a planted second call site, not derive its reach by reading — a source scanner that silently stops short of its corpus looks identical to a passing one.
#774 is closed on this: it correctly declines to widen scope, and its round-6 decision to keep the "for the rest of the session" consequence statements rests on this premise being true today, which it is. This issue exists so the premise does not evaporate when it stops being true.
Raised as N1 in the round-6 review of #774 (#766). Not a defect today — the premise is true as of this writing, verified twice — but it is load-bearing prose with nothing underneath it, and its decay would be silent.
The premise
Exactly one fine steering worker (
LocalPlanner) is constructed per client process.Verified mechanically, by the reviewer and independently by me:
LocalPlanner::spawnis reached only viaWalker::new;Walker::newis inActionLoop::new;ActionLoop::newis inrun_login_flow, inside theOk(..)arm of the retry loop, which unconditionallyreturn Ok(())afterrun_gameplay_phase— and the slots are moved into it, so a second pass round that loop would not compile;run_login_flowitself is called once, fromServerModel::run.An unrelated comment in
login.rsreaches the same conclusion for a different field ("no code path re-enters login after gameplay today").Why it matters
NavStatus.local_planner_deadis latched and worker-scoped. The agent-facing documentation calls it session-scoped, and that name is defended as accurate precisely because the two spans coincide under this premise. At least four sentences rest on it directly:crates/eqoxide-ipc/src/lib.rs(field doc)crates/eqoxide-ipc/src/lib.rs(field doc)crates/eqoxide-http/src/observe.rsdocs/http-api.mdSeveral more ("this clear is a no-op in production", "on today's single-
Walkerprocess") depend on it more weakly.Why it decays silently
There is no guard, no test and no
E0027-style net over the single productionWalker::new. The claim exists only as prose. The day an in-process relogin lands — which is the exact shape #774 hardenedWalker::newagainst — those four sentences become false, the agent-facing name becomes wrong, and nothing in the tree goes red.The obvious candidate is not one.
a_new_walker_does_not_inherit_a_previous_workers_death_766(eqoxide-nav) constructs a secondWalkerdeliberately, over a deliberately dirty row. It cannot be the thing that fails when a secondWalkerappears in production, because building a second one is its whole method.Suggested shape
The repo already uses source-scanning guards for premises of this kind (
steering.rs's citation scan,slot.rs's two scans,action_loop.rs'sinclude_str!ofdocs/http-api.md). The natural form here:Two design notes for whoever picks this up:
#[cfg(test)]regions, or the B9 test's own construction defeats it on day one.guard reachlesson, whoever writes it should run it and show it going red on a planted second call site, not derive its reach by reading — a source scanner that silently stops short of its corpus looks identical to a passing one.Not for #774
#774 is closed on this: it correctly declines to widen scope, and its round-6 decision to keep the "for the rest of the session" consequence statements rests on this premise being true today, which it is. This issue exists so the premise does not evaporate when it stops being true.