Watch
1
0
Fork
You've already forked souveraine
0

shell: "already registered" is a transient, not a verdict

A scene reload re-runs SessiondBridge while the outgoing connection is still
open, so the reload's shell_ready races its own predecessor's EOF and sessiond
refuses it — correctly, since the lease is genuinely held. The bug was the
shell then giving up for good: it read the refusal as "another shell owns the
lease, we are not the authority", cleared nothing, and left registerRetry
idle. A second later that EOF landed, shell_alive dropped, and sessiond spent
the rest of the session believing there was no shell — while a live one sat on
a connected socket.

Observed 2026-07-29: refused 09:14:35, predecessor closed 09:16:36, and
`{"op":"status"}` reported shell_alive=false for 90 minutes afterwards.

Now the refusal sets needsRegistration and lets the 5s retry run. If the lease
really is another live shell's, each retry is refused again for free — and we
take it the moment that shell dies. Verified on hardware: retrying (1) ->
registered -> locked_ack sent, sessiond back to phase=released.
This commit is contained in:
Fimeg 2026-07-29 10:43:07 -04:00
commit 45fbbea400

View file

@ -33,8 +33,13 @@ Singleton {
// so reconnect cannot read it directly to decide whether to re-register.
property bool wasRegistered: false
// We owe the authority a registration that has not landed yet set when a
// handshake times out, cleared once one is answered. Drives registerRetry.
// handshake times out or is refused because the lease is still held,
// cleared once one is answered. Drives registerRetry.
property bool needsRegistration: false
// Consecutive "already registered" refusals. Only for log cadence the
// retry itself is unconditional, because the common cause is our own
// outgoing connection not having hit EOF yet.
property int refusalStreak: 0
// sessiond held the session lock when we registered; we owe it a lock
// and a locked_ack.
property bool oweLock: false
@ -218,21 +223,46 @@ Singleton {
if (reply.ok) {
root.registered = true;
root.needsRegistration = false;
root.refusalStreak = 0;
root.oweLock = reply.must_lock === true;
console.log("[sessiond-bridge] registered, must_lock=" + root.oweLock);
cb(root.oweLock);
} else {
// One refusal is benign and means we are not the
// authority at all: another live shell already holds
// the lease, so we owe it no lock. Anything else is a
// refusal we do not understand, and an authority that
// refused us for unknown reasons is not grounds to
// assume the session is open.
const notAuthority =
// "already registered" means the lease is held right
// now. It does NOT mean it is held by someone else,
// and treating it as a verdict was a real bug: a scene
// RELOAD re-runs this file while the outgoing
// connection is still open, so the reload's shell_ready
// races its own predecessor's EOF and is refused. The
// old code then stopped retrying and when that EOF
// landed a second later it cleared shell_alive, leaving
// sessiond believing there was no shell at all, for the
// life of the session. Observed 2026-07-29 09:14:35:
// refused, old socket closed 09:16:36, and the daemon
// reported shell_alive=false with a live shell on the
// other end of a connected socket.
//
// So it is a TRANSIENT. Keep registering. If the lease
// really is another live shell's, every retry is
// refused again and costs nothing and the moment that
// shell dies we are the one that should hold it.
const leaseHeld =
String(reply.reason || "").indexOf("already registered") !== -1;
console.warn("[sessiond-bridge] shell_ready refused: " + reply.reason
+ (notAuthority ? "" : " — assuming locked"));
cb(!notAuthority);
if (leaseHeld) {
root.needsRegistration = true;
root.refusalStreak += 1;
// Loud once, then once a minute: a lease that never
// frees is a real problem, but 12 lines a minute is
// how a real problem gets scrolled past.
if (root.refusalStreak === 1 || root.refusalStreak % 12 === 0)
console.warn("[sessiond-bridge] shell_ready refused: "
+ reply.reason + " — lease still held, retrying ("
+ root.refusalStreak + ")");
} else {
console.warn("[sessiond-bridge] shell_ready refused: "
+ reply.reason + " — assuming locked");
}
cb(!leaseHeld);
}
}
}