<owl_messages>
<owl_message from="doyle" priority="high">Fix shape = gate-aligned on every point, no notes. Proceed.

SYNERGY FLAG: your (a) deadline path already does "detach + mark-gone → clear driven_by, unlatch ONLINE+CONTROLLED" — that IS W5's (REQ-HAZARD-DRIVEN-BY-SELFHEAL) mechanism for the lost-controller case. So W1 largely DELIVERS W5. When you get to W5, don't rebuild it — just confirm the reconcile loop ALSO clears driven_by for the non-deadline cases (controller vanished w/o tripping the write deadline, e.g. broker never attempts a write because the session is idle/quiet). Make the W1 deadline-clear and the W5 reconcile-clear share one unlatch path. I'll gate W5 as a thin confirm on top of W1.

Teeing the operator up for the part-2 byte now (they're in my session). Will relay rckeys.log hex straight to you. Ping me when the W1 fix is up.</owl_message>
</owl_messages>

[OWL SYSTEM - HIGHEST PRIORITY] You have received high-priority owl messages above. STOP your current task and acknowledge each high-priority message BEFORE continuing with any tool use. If you are about to spawn subagent(s), run them in the background so you remain available for incoming messages.


The file C:\Users\decid\Documents\projects\spt-core\crates\spt-daemon\src\broker.rs has been updated successfully. (file state is current in your context — no need to Read it back)

use std::collections::{HashMap, VecDeque};
use std::io;
use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::mpsc::{sync_channel, Receiver, SyncSender, TrySendError};
use std::sync::{Arc, Mutex};
use std::thread::{self, JoinHandle};

use std::collections::{HashMap, VecDeque};
use std::io;
use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
use std::sync::mpsc::{sync_channel, Receiver, SendTimeoutError, SyncSender, TrySendError};
use std::sync::{Arc, Mutex};
use std::thread::{self, JoinHandle};
use std::time::Duration;

-use std::sync::mpsc::{sync_channel, Receiver, SyncSender, TrySendError};

+use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};

+use std::sync::mpsc::{sync_channel, Receiver, SendTimeoutError, SyncSender, TrySendError};

use interprocess::local_socket::{prelude::*, SendHalf, Stream};

use spt_term::{Drain, PtySession, SessionSurface, SurfaceSize};


Ack.


Bash

$OWL send doyle <<'EOF'
ACK. Proceeding with the fix.

SYNERGY noted — the W1 deadline path's "detach + clear driven_by + unlatch ONLINE+CONTROLLED" is the lost-controller unlatch. I'll factor it into ONE shared unlatch helper (a single function both the W1 deadline-evict and the W5 reconcile-clear call) so W5 is a thin confirm: reconcile clears driven_by for the non-deadline case (controller vanished on an idle/quiet session where no write is ever attempted, so the deadline never trips). Won't rebuild it at W5.

Thanks for teeing up the operator — send the rckeys.log hex when you have it; I'll gate the W7 byte then. Will ping when the W1 fix is up for your gate.
EOF

Ack doyle synergy + proceed


➜ SENT:doyle


Now add the controller-sink consts, struct, and dedicated writer (the viewer_writer analog with authoritative cursor + gone-signal). Insert after `ViewerSink`.


Edit

struct ViewerSink {
    /// The bounded live-frame queue to this viewer's writer thread.
    tx: SyncSender<Envelope>,
    /// The viewer's IPC send half — kept ONLY for identity matching on detach
    /// (a dropped brain connection removes its viewer rows); never written here.
    send: SharedSend,
    /// The writer thread handle (held for ownership; it exits when `tx` drops or
    /// a socket write fails).
    _writer: JoinHandle<()>,
}

struct ViewerSink {
    /// The bounded live-frame queue to this viewer's writer thread.
    tx: SyncSender<Envelope>,
    /// The viewer's IPC send half — kept ONLY for identity matching on detach
    /// (a dropped brain connection removes its viewer rows); never written here.
    send: SharedSend,
    /// The writer thread handle (held for ownership; it exits when `tx` drops or
    /// a socket write fails).
    _writer: JoinHandle<()>,
}

/// The controller live-frame channel depth (frames). Deeper than a viewer's
/// queue because the controller is the AUTHORITATIVE view — it is never silently
/// evicted on overflow (W1 / REQ-HAZARD-INJECT-CONTROL-COEXIST); instead the
/// drain blocks on a bounded `send_timeout` and the controller is detached only
/// after [`CONTROLLER_WRITE_DEADLINE`] of a fully-stalled socket. Generous so a
/// momentary slow consumer never trips the deadline.
const CONTROLLER_CHANNEL_DEPTH: usize = 4096;

/// How long the drain tolerates a CONTROLLER whose socket has fully stalled (its
/// channel stays full) before declaring it gone, detaching it, and resuming
/// (W1). This BOUNDS the wedge: a backed-up controller can stall live output for
/// at most this long — never forever (the v0.12.x root) — and never blocks the
/// log lock (the send happens off-lock; see [`OutputLog::append`]). A live but
/// merely slow operator drains a slot before this elapses and is untouched.
const CONTROLLER_WRITE_DEADLINE: Duration = Duration::from_secs(5);

/// The interactive CONTROLLER's isolated sink (W1 / REQ-HAZARD-INJECT-CONTROL-COEXIST).
/// Symmetric with [`ViewerSink`] — a dedicated writer thread does the BLOCKING
/// socket write so a backed-up controller can never stall the session drain
/// thread (the v0.12.x wedge: the controller write was inline on the drain,
/// holding `Mutex<OutputLog>`). Unlike a viewer it is AUTHORITATIVE: its writer
/// advances `delivered_through` on each successful write, and it is never evicted
/// on a single full `try_send` — only after [`CONTROLLER_WRITE_DEADLINE`].
struct ControllerSink {
    /// The bounded live-frame queue to the controller's writer thread.
    tx: SyncSender<Envelope>,
    /// The controller's IPC send half — kept for identity matching on detach and
    /// for the `exit`-frame fan-out ([`OutputLog::all_sinks`]).
    send: SharedSend,
    /// The controller's identity: `Some(node)` = a remote operator, `None` =
    /// local (the brain's spawn-reader / resume). Ownership keys on this.
    by: Option<String>,
    /// Set by the writer thread when its socket write fails (dead operator) — a
    /// cheap liveness flag the drain can observe without joining the thread.
    gone: Arc<AtomicBool>,
    /// The writer thread handle (held for ownership; exits when `tx` drops, a
    /// socket write fails, or the deadline detaches it).
    _writer: JoinHandle<()>,
}


struct ViewerSink {
    /// The bounded live-frame queue to this viewer's writer thread.
    tx: SyncSender<Envelope>,
    /// The viewer's IPC send half — kept ONLY for identity matching on detach
    /// (a dropped brain connection removes its viewer rows); never written here.
    send: SharedSend,
    /// The writer thread handle (held for ownership; it exits when `tx` drops or
    /// a socket write fails).
    _writer: JoinHandle<()>,
}

/// The controller live-frame channel depth (frames). Deeper than a viewer's
/// queue because the controller is the AUTHORITATIVE view — it is never silently
/// evicted on overflow (W1 / REQ-HAZARD-INJECT-CONTROL-COEXIST); instead the
/// drain blocks on a bounded `send_timeout` and the controller is detached only
/// after [`CONTROLLER_WRITE_DEADLINE`] of a fully-stalled socket. Generous so a
/// momentary slow consumer never trips the deadline.
const CONTROLLER_CHANNEL_DEPTH: usize = 4096;

/// How long the drain tolerates a CONTROLLER whose socket has fully stalled (its
/// channel stays full) before declaring it gone, detaching it, and resuming
/// (W1). This BOUNDS the wedge: a backed-up controller can stall live output for
/// at most this long — never forever (the v0.12.x root) — and never blocks the
/// log lock (the send happens off-lock; see [`OutputLog::append`]). A live but
/// merely slow operator drains a slot before this elapses and is untouched.
const CONTROLLER_WRITE_DEADLINE: Duration = Duration::from_secs(5);

/// The interactive CONTROLLER's isolated sink (W1 / REQ-HAZARD-INJECT-CONTROL-COEXIST).
/// Symmetric with [`ViewerSink`] — a dedicated writer thread does the BLOCKING
/// socket write so a backed-up controller can never stall the session drain
/// thread (the v0.12.x wedge: the controller write was inline on the drain,
/// holding `Mutex<OutputLog>`). Unlike a viewer it is AUTHORITATIVE: its writer
/// advances `delivered_through` on each successful write, and it is never evicted
/// on a single full `try_send` — only after [`CONTROLLER_WRITE_DEADLINE`].
struct ControllerSink {
    /// The bounded live-frame queue to the controller's writer thread.
    tx: SyncSender<Envelope>,
    /// The controller's IPC send half — kept for identity matching on detach and
    /// for the `exit`-frame fan-out ([`OutputLog::all_sinks`]).
    send: SharedSend,
    /// The controller's identity: `Some(node)` = a remote operator, `None` =
    /// local (the brain's spawn-reader / resume). Ownership keys on this.
    by: Option<String>,
    /// Set by the writer thread when its socket write fails (dead operator) — a
    /// cheap liveness flag the drain can observe without joining the thread.
    gone: Arc<AtomicBool>,
    /// The writer thread handle (held for ownership; exits when `tx` drops, a
    /// socket write fails, or the deadline detaches it).
    _writer: JoinHandle<()>,
}

+/// The controller live-frame channel depth (frames). Deeper than a viewer's

+/// queue because the controller is the AUTHORITATIVE view — it is never silently

+/// evicted on overflow (W1 / REQ-HAZARD-INJECT-CONTROL-COEXIST); instead the

+/// drain blocks on a bounded `send_timeout` and the controller is detached only

+/// after [`CONTROLLER_WRITE_DEADLINE`] of a fully-stalled socket. Generous so a

+/// momentary slow consumer never trips the deadline.

+const CONTROLLER_CHANNEL_DEPTH: usize = 4096;

+/// How long the drain tolerates a CONTROLLER whose socket has fully stalled (its

+/// channel stays full) before declaring it gone, detaching it, and resuming

+/// (W1). This BOUNDS the wedge: a backed-up controller can stall live output for

+/// at most this long — never forever (the v0.12.x root) — and never blocks the

+/// log lock (the send happens off-lock; see [`OutputLog::append`]). A live but

+/// merely slow operator drains a slot before this elapses and is untouched.

+const CONTROLLER_WRITE_DEADLINE: Duration = Duration::from_secs(5);

+/// The interactive CONTROLLER's isolated sink (W1 / REQ-HAZARD-INJECT-CONTROL-COEXIST).

+/// Symmetric with [`ViewerSink`] — a dedicated writer thread does the BLOCKING

+/// socket write so a backed-up controller can never stall the session drain

+/// thread (the v0.12.x wedge: the controller write was inline on the drain,

+/// holding `Mutex<OutputLog>`). Unlike a viewer it is AUTHORITATIVE: its writer

+/// advances `delivered_through` on each successful write, and it is never evicted

+/// on a single full `try_send` — only after [`CONTROLLER_WRITE_DEADLINE`].

+    /// The bounded live-frame queue to the controller's writer thread.

+    /// The controller's IPC send half — kept for identity matching on detach and

+    /// for the `exit`-frame fan-out ([`OutputLog::all_sinks`]).

+    /// The controller's identity: `Some(node)` = a remote operator, `None` =

+    /// local (the brain's spawn-reader / resume). Ownership keys on this.

+    /// Set by the writer thread when its socket write fails (dead operator) — a

+    /// cheap liveness flag the drain can observe without joining the thread.

+    /// The writer thread handle (held for ownership; exits when `tx` drops, a

+    /// socket write fails, or the deadline detaches it).

/// A bounded, sequenced output log for one session — the gapless-resume buffer

/// AND the W2.5 controller/viewer fan-out hub (REQ-RCVIEW-1).


Update the `OutputLog` struct fields.


    /// The single interactive controller's IPC send (input + EXCLUSIVE resize;
    /// advances `delivered_through`). `None` ⇒ undriven (no controller).
    controller: Option<SharedSend>,
    /// The controller's identity: `Some(node)` = a remote operator, `None` =
    /// local (the daemon brain's spawn-reader / resume). Controller-ownership is
    /// keyed on this — a same-`by` re-subscribe silently re-takes (no
    /// `Displaced`, the gate-#7 self-kick guard); only a DIFFERENT remote's
    /// `Take` displaces. Paired with `controller` (both `Some` or both `None`).
    controller_by: Option<String>,
    /// The read-only viewers, keyed by a broker-minted viewer id.
    viewers: HashMap<u64, ViewerSink>,

    /// The single interactive controller's isolated sink (W1: a dedicated writer
    /// thread + bounded channel + authoritative cursor). `None` ⇒ undriven. The
    /// controller's identity (`Some(node)` remote / `None` local) lives in
    /// [`ControllerSink::by`] and keys ownership — a same-`by` re-subscribe
    /// silently re-takes (no `Displaced`, the gate-#7 self-kick guard); only a
    /// DIFFERENT remote's `Take` displaces.
    controller: Option<ControllerSink>,
    /// Monotonic controller generation. Bumped on every [`become_controller`];
    /// the drain's deadline-evict ([`mark_controller_gone`]) carries the epoch it
    /// observed and only detaches if it still matches — so a slow-controller
    /// timeout can never unseat a NEWER controller that attached meanwhile.
    controller_epoch: u64,
    /// The read-only viewers, keyed by a broker-minted viewer id.
    viewers: HashMap<u64, ViewerSink>,


    /// The single interactive controller's IPC send (input + EXCLUSIVE resize;
    /// advances `delivered_through`). `None` ⇒ undriven (no controller).
    controller: Option<SharedSend>,
    /// The controller's identity: `Some(node)` = a remote operator, `None` =
    /// local (the daemon brain's spawn-reader / resume). Controller-ownership is
    /// keyed on this — a same-`by` re-subscribe silently re-takes (no
    /// `Displaced`, the gate-#7 self-kick guard); only a DIFFERENT remote's
    /// `Take` displaces. Paired with `controller` (both `Some` or both `None`).
    controller_by: Option<String>,
    /// The read-only viewers, keyed by a broker-minted viewer id.
    viewers: HashMap<u64, ViewerSink>,

    /// The single interactive controller's isolated sink (W1: a dedicated writer
    /// thread + bounded channel + authoritative cursor). `None` ⇒ undriven. The
    /// controller's identity (`Some(node)` remote / `None` local) lives in
    /// [`ControllerSink::by`] and keys ownership — a same-`by` re-subscribe
    /// silently re-takes (no `Displaced`, the gate-#7 self-kick guard); only a
    /// DIFFERENT remote's `Take` displaces.
    controller: Option<ControllerSink>,
    /// Monotonic controller generation. Bumped on every [`become_controller`];
    /// the drain's deadline-evict ([`mark_controller_gone`]) carries the epoch it
    /// observed and only detaches if it still matches — so a slow-controller
    /// timeout can never unseat a NEWER controller that attached meanwhile.
    controller_epoch: u64,
    /// The read-only viewers, keyed by a broker-minted viewer id.
    viewers: HashMap<u64, ViewerSink>,

-    /// The single interactive controller's IPC send (input + EXCLUSIVE resize;

-    /// advances `delivered_through`). `None` ⇒ undriven (no controller).

-    /// The controller's identity: `Some(node)` = a remote operator, `None` =

-    /// local (the daemon brain's spawn-reader / resume). Controller-ownership is

-    /// keyed on this — a same-`by` re-subscribe silently re-takes (no

-    /// `Displaced`, the gate-#7 self-kick guard); only a DIFFERENT remote's

-    /// `Take` displaces. Paired with `controller` (both `Some` or both `None`).

+    /// The single interactive controller's isolated sink (W1: a dedicated writer

+    /// thread + bounded channel + authoritative cursor). `None` ⇒ undriven. The

+    /// controller's identity (`Some(node)` remote / `None` local) lives in

+    /// [`ControllerSink::by`] and keys ownership — a same-`by` re-subscribe

+    /// silently re-takes (no `Displaced`, the gate-#7 self-kick guard); only a

+    /// DIFFERENT remote's `Take` displaces.

+    controller: Option<ControllerSink>,

+    /// Monotonic controller generation. Bumped on every [`become_controller`];

+    /// the drain's deadline-evict ([`mark_controller_gone`]) carries the epoch it

+    /// observed and only detaches if it still matches — so a slow-controller

+    /// timeout can never unseat a NEWER controller that attached meanwhile.


    /// **Advanced only on a successful socket write** (`Ok`), and **monotonic**
    /// (never decreases) — see [`advanced_cursor`]. Both invariants are
    /// load-bearing for at-least-once output: advancing past a *failed* write to a
    /// dying-but-not-yet-detached controller would make resume skip that chunk
    /// forever (at-least-once → at-most-once); decreasing on a deliberate
    /// `attach(sub, 0)` rewind-replay would reset the resume point under a live
    /// reader.
    delivered_through: u64,
}

    /// **Advanced only on a successful socket write** (`Ok`), and **monotonic**
    /// (never decreases) — see [`advanced_cursor`]. Both invariants are
    /// load-bearing for at-least-once output: advancing past a *failed* write to a
    /// dying-but-not-yet-detached controller would make resume skip that chunk
    /// forever (at-least-once → at-most-once); decreasing on a deliberate
    /// `attach(sub, 0)` rewind-replay would reset the resume point under a live
    /// reader.
    ///
    /// W1: now an `Arc<AtomicU64>` shared with the controller's writer thread,
    /// which advances it (via [`advanced_cursor`], CAS-monotonic) as it writes —
    /// the cursor moved off the drain thread with the controller delivery itself.
    delivered_through: Arc<AtomicU64>,
}


    /// **Advanced only on a successful socket write** (`Ok`), and **monotonic**
    /// (never decreases) — see [`advanced_cursor`]. Both invariants are
    /// load-bearing for at-least-once output: advancing past a *failed* write to a
    /// dying-but-not-yet-detached controller would make resume skip that chunk
    /// forever (at-least-once → at-most-once); decreasing on a deliberate
    /// `attach(sub, 0)` rewind-replay would reset the resume point under a live
    /// reader.
    delivered_through: u64,
}

    /// **Advanced only on a successful socket write** (`Ok`), and **monotonic**
    /// (never decreases) — see [`advanced_cursor`]. Both invariants are
    /// load-bearing for at-least-once output: advancing past a *failed* write to a
    /// dying-but-not-yet-detached controller would make resume skip that chunk
    /// forever (at-least-once → at-most-once); decreasing on a deliberate
    /// `attach(sub, 0)` rewind-replay would reset the resume point under a live
    /// reader.
    ///
    /// W1: now an `Arc<AtomicU64>` shared with the controller's writer thread,
    /// which advances it (via [`advanced_cursor`], CAS-monotonic) as it writes —
    /// the cursor moved off the drain thread with the controller delivery itself.
    delivered_through: Arc<AtomicU64>,
}

+    /// W1: now an `Arc<AtomicU64>` shared with the controller's writer thread,

+    /// which advances it (via [`advanced_cursor`], CAS-monotonic) as it writes —

+    /// the cursor moved off the drain thread with the controller delivery itself.

/// The post-write resume cursor (pure — the D4-1 unit kernel, mirroring


Update `new()` for the new field types.


            ring: VecDeque::new(),
            cap_chunks,
            controller: None,
            controller_by: None,
            viewers: HashMap::new(),
            next_viewer_id: 0,
            endpoint,
            size,
            delivered_through: 0,
        }
    }

            ring: VecDeque::new(),
            cap_chunks,
            controller: None,
            controller_epoch: 0,
            viewers: HashMap::new(),
            next_viewer_id: 0,
            endpoint,
            size,
            delivered_through: Arc::new(AtomicU64::new(0)),
        }
    }


            ring: VecDeque::new(),
            cap_chunks,
            controller: None,
            controller_by: None,
            viewers: HashMap::new(),
            next_viewer_id: 0,
            endpoint,
            size,
            delivered_through: 0,
        }
    }

            ring: VecDeque::new(),
            cap_chunks,
            controller: None,
            controller_epoch: 0,
            viewers: HashMap::new(),
            next_viewer_id: 0,
            endpoint,
            size,
            delivered_through: Arc::new(AtomicU64::new(0)),
        }
    }

+            delivered_through: Arc::new(AtomicU64::new(0)),


Now rewrite `append` — fan viewers under the lock (unchanged), but hand the controller frame to a returned job for off-lock delivery. This removes the inline park entirely. Also drop the now-obsolete `park_debug` instrumentation (the inline controller write is gone).


    /// Append a freshly-produced output chunk: assign the next `seq`, retain it
    /// in the bounded ring, then FAN OUT — the controller on the authoritative
    /// blocking path (advancing the delivered cursor only on a successful write,
    /// D4-1), and each viewer via a `try_send` to its bounded queue, EVICTING any
    /// viewer whose queue overflows or whose writer has gone. The drain thread
    /// NEVER touches a viewer socket, so no viewer can stall it
    /// (REQ-HAZARD-VIEWER-ISOLATION). Called only from the session's drain thread.
    fn append(&mut self, bytes: &[u8]) {
        let seq = self.next_seq;
        self.next_seq += 1;
        self.ring.push_back((seq, bytes.to_vec()));
        while self.ring.len() > self.cap_chunks {
            self.ring.pop_front();
        }
        let frame = output_envelope(self.session_id, seq, bytes);
        // Controller: authoritative, blocking, advances the resume cursor.
        if let Some(sub) = &self.controller {
            // W1 park (a): this inline write_frame is held ON the drain thread
            // while `Mutex<OutputLog>` is locked — a backed-up controller socket
            // parks the drain here. The ENTER/EXIT bracket proves it.
            if park_debug() {
                eprintln!("APPEND_CTRL_ENTER sid={} seq={}", self.session_id, seq);
            }
            let write_ok = match sub.lock() {
                Ok(mut s) => write_frame(&mut *s, &frame).is_ok(),
                Err(_) => false,
            };
            if park_debug() {
                eprintln!(
                    "APPEND_CTRL_EXIT sid={} seq={} ok={}",
                    self.session_id, seq, write_ok
                );
            }
            self.delivered_through = advanced_cursor(self.delivered_through, seq, write_ok);
        }
        // Viewers: non-blocking fan-out; a full / disconnected queue = eviction.
        if !self.viewers.is_empty() {
            let mut evicted: Vec<u64> = Vec::new();
            for (vid, sink) in self.viewers.iter() {
                if viewer_send_evicts(&sink.tx.try_send(frame.clone())) {
                    evicted.push(*vid);
                }
            }
            if !evicted.is_empty() {
                for vid in evicted {
                    self.viewers.remove(&vid);
                }
                self.stamp_viewer_count();
            }
        }
    }

    /// Append a freshly-produced output chunk: assign the next `seq`, retain it
    /// in the bounded ring, FAN OUT to viewers (non-blocking `try_send`, evicting
    /// any overflowed/gone queue — REQ-HAZARD-VIEWER-ISOLATION), and HAND the
    /// controller frame back to the caller as a [`ControllerJob`] to deliver
    /// **off the log lock** (W1 / REQ-HAZARD-INJECT-CONTROL-COEXIST).
    ///
    /// W1: the controller write is no longer inline here. The drain used to call
    /// `write_frame(controller)` synchronously while holding `Mutex<OutputLog>`,
    /// so a backed-up controller socket parked the drain thread WITH THE LOCK HELD
    /// — wedging the whole session (every attach / `KIND_SESSIONS` that needs the
    /// log lock blocked). Now this returns the job and releases the lock; the
    /// drain does a bounded `send_timeout` into the controller's writer-thread
    /// channel ([`OutputLog::deliver_to_controller`]) lock-free. Called only from
    /// the session's single drain thread.
    #[must_use]
    fn append(&mut self, bytes: &[u8]) -> Option<ControllerJob> {
        let seq = self.next_seq;
        self.next_seq += 1;
        self.ring.push_back((seq, bytes.to_vec()));
        while self.ring.len() > self.cap_chunks {
            self.ring.pop_front();
        }
        let frame = output_envelope(self.session_id, seq, bytes);
        // Viewers: non-blocking fan-out; a full / disconnected queue = eviction.
        if !self.viewers.is_empty() {
            let mut evicted: Vec<u64> = Vec::new();
            for (vid, sink) in self.viewers.iter() {
                if viewer_send_evicts(&sink.tx.try_send(frame.clone())) {
                    evicted.push(*vid);
                }
            }
            if !evicted.is_empty() {
                for vid in evicted {
                    self.viewers.remove(&vid);
                }
                self.stamp_viewer_count();
            }
        }
        // Controller: hand the frame to the caller for an off-lock, bounded send
        // into the controller writer thread's channel (which does the blocking
        // socket write + advances the authoritative cursor). The drain never
        // blocks under the log lock again.
        self.controller.as_ref().map(|c| ControllerJob {
            tx: c.tx.clone(),
            frame,
            epoch: self.controller_epoch,
        })
    }


    /// Append a freshly-produced output chunk: assign the next `seq`, retain it
    /// in the bounded ring, then FAN OUT — the controller on the authoritative
    /// blocking path (advancing the delivered cursor only on a successful write,
    /// D4-1), and each viewer via a `try_send` to its bounded queue, EVICTING any
    /// viewer whose queue overflows or whose writer has gone. The drain thread
    /// NEVER touches a viewer socket, so no viewer can stall it
    /// (REQ-HAZARD-VIEWER-ISOLATION). Called only from the session's drain thread.
    fn append(&mut self, bytes: &[u8]) {
        let seq = self.next_seq;
        self.next_seq += 1;
        self.ring.push_back((seq, bytes.to_vec()));
        while self.ring.len() > self.cap_chunks {
            self.ring.pop_front();
        }
        let frame = output_envelope(self.session_id, seq, bytes);
        // Controller: authoritative, blocking, advances the resume cursor.
        if let Some(sub) = &self.controller {
            // W1 park (a): this inline write_frame is held ON the drain thread
            // while `Mutex<OutputLog>` is locked — a backed-up controller socket
            // parks the drain here. The ENTER/EXIT bracket proves it.
            if park_debug() {
                eprintln!("APPEND_CTRL_ENTER sid={} seq={}", self.session_id, seq);
            }
            let write_ok = match sub.lock() {
                Ok(mut s) => write_frame(&mut *s, &frame).is_ok(),
                Err(_) => false,
            };
            if park_debug() {
                eprintln!(
                    "APPEND_CTRL_EXIT sid={} seq={} ok={}",
                    self.session_id, seq, write_ok
                );
            }
            self.delivered_through = advanced_cursor(self.delivered_through, seq, write_ok);
        }
        // Viewers: non-blocking fan-out; a full / disconnected queue = eviction.
        if !self.viewers.is_empty() {
            let mut evicted: Vec<u64> = Vec::new();
            for (vid, sink) in self.viewers.iter() {
                if viewer_send_evicts(&sink.tx.try_send(frame.clone())) {
                    evicted.push(*vid);
                }
            }
            if !evicted.is_empty() {
                for vid in evicted {
                    self.viewers.remove(&vid);
                }
                self.stamp_viewer_count();
            }
        }
    }

    /// Append a freshly-produced output chunk: assign the next `seq`, retain it
    /// in the bounded ring, FAN OUT to viewers (non-blocking `try_send`, evicting
    /// any overflowed/gone queue — REQ-HAZARD-VIEWER-ISOLATION), and HAND the
    /// controller frame back to the caller as a [`ControllerJob`] to deliver
    /// **off the log lock** (W1 / REQ-HAZARD-INJECT-CONTROL-COEXIST).
    ///
    /// W1: the controller write is no longer inline here. The drain used to call
    /// `write_frame(controller)` synchronously while holding `Mutex<OutputLog>`,
    /// so a backed-up controller socket parked the drain thread WITH THE LOCK HELD
    /// — wedging the whole session (every attach / `KIND_SESSIONS` that needs the
    /// log lock blocked). Now this returns the job and releases the lock; the
    /// drain does a bounded `send_timeout` into the controller's writer-thread
    /// channel ([`OutputLog::deliver_to_controller`]) lock-free. Called only from
    /// the session's single drain thread.
    #[must_use]
    fn append(&mut self, bytes: &[u8]) -> Option<ControllerJob> {
        let seq = self.next_seq;
        self.next_seq += 1;
        self.ring.push_back((seq, bytes.to_vec()));
        while self.ring.len() > self.cap_chunks {
            self.ring.pop_front();
        }
        let frame = output_envelope(self.session_id, seq, bytes);
        // Viewers: non-blocking fan-out; a full / disconnected queue = eviction.
        if !self.viewers.is_empty() {
            let mut evicted: Vec<u64> = Vec::new();
            for (vid, sink) in self.viewers.iter() {
                if viewer_send_evicts(&sink.tx.try_send(frame.clone())) {
                    evicted.push(*vid);
                }
            }
            if !evicted.is_empty() {
                for vid in evicted {
                    self.viewers.remove(&vid);
                }
                self.stamp_viewer_count();
            }
        }
        // Controller: hand the frame to the caller for an off-lock, bounded send
        // into the controller writer thread's channel (which does the blocking
        // socket write + advances the authoritative cursor). The drain never
        // blocks under the log lock again.
        self.controller.as_ref().map(|c| ControllerJob {
            tx: c.tx.clone(),
            frame,
            epoch: self.controller_epoch,
        })
    }

-    /// in the bounded ring, then FAN OUT — the controller on the authoritative

-    /// blocking path (advancing the delivered cursor only on a successful write,

-    /// D4-1), and each viewer via a `try_send` to its bounded queue, EVICTING any

-    /// viewer whose queue overflows or whose writer has gone. The drain thread

-    /// NEVER touches a viewer socket, so no viewer can stall it

-    /// (REQ-HAZARD-VIEWER-ISOLATION). Called only from the session's drain thread.

-    fn append(&mut self, bytes: &[u8]) {

+    /// in the bounded ring, FAN OUT to viewers (non-blocking `try_send`, evicting

+    /// any overflowed/gone queue — REQ-HAZARD-VIEWER-ISOLATION), and HAND the

+    /// controller frame back to the caller as a [`ControllerJob`] to deliver

+    /// **off the log lock** (W1 / REQ-HAZARD-INJECT-CONTROL-COEXIST).

+    /// W1: the controller write is no longer inline here. The drain used to call

+    /// `write_frame(controller)` synchronously while holding `Mutex<OutputLog>`,

+    /// so a backed-up controller socket parked the drain thread WITH THE LOCK HELD

+    /// — wedging the whole session (every attach / `KIND_SESSIONS` that needs the

+    /// log lock blocked). Now this returns the job and releases the lock; the

+    /// drain does a bounded `send_timeout` into the controller's writer-thread

+    /// channel ([`OutputLog::deliver_to_controller`]) lock-free. Called only from

+    /// the session's single drain thread.

+    fn append(&mut self, bytes: &[u8]) -> Option<ControllerJob> {

-        // Controller: authoritative, blocking, advances the resume cursor.

-        if let Some(sub) = &self.controller {

-            // W1 park (a): this inline write_frame is held ON the drain thread

-            // while `Mutex<OutputLog>` is locked — a backed-up controller socket

-            // parks the drain here. The ENTER/EXIT bracket proves it.

-                eprintln!("APPEND_CTRL_ENTER sid={} seq={}", self.session_id, seq);

-            let write_ok = match sub.lock() {

-                Ok(mut s) => write_frame(&mut *s, &frame).is_ok(),

-                    "APPEND_CTRL_EXIT sid={} seq={} ok={}",

-                    self.session_id, seq, write_ok

-            self.delivered_through = advanced_cursor(self.delivered_through, seq, write_ok);

+        // Controller: hand the frame to the caller for an off-lock, bounded send

+        // into the controller writer thread's channel (which does the blocking

+        // socket write + advances the authoritative cursor). The drain never

+        // blocks under the log lock again.

+        self.controller.as_ref().map(|c| ControllerJob {

+            epoch: self.controller_epoch,

/// Become (or silently re-take) the interactive controller from `from_seq`.


Remove the now-unused `park_debug` helper.


const DEFAULT_LOG_CHUNKS: usize = 4096;

/// W1 (REQ-HAZARD-INJECT-CONTROL-COEXIST) repro instrumentation. When
/// `SPT_BROKER_DEBUG_PARK` is set, the drain-thread's inline controller write in
/// [`OutputLog::append`] brackets itself with `APPEND_CTRL_ENTER`/`_EXIT` lines
/// on stderr — so a real-fixture run can PROVE the park is the controller
/// `write_frame` (an ENTER with no matching EXIT = the drain thread parked there
/// holding `Mutex<OutputLog>`). Cached once; zero cost when unset.
fn park_debug() -> bool {
    use std::sync::OnceLock;
    static ON: OnceLock<bool> = OnceLock::new();
    *ON.get_or_init(|| std::env::var_os("SPT_BROKER_DEBUG_PARK").is_some())
}


const DEFAULT_LOG_CHUNKS: usize = 4096;

/// W1 (REQ-HAZARD-INJECT-CONTROL-COEXIST) repro instrumentation. When
/// `SPT_BROKER_DEBUG_PARK` is set, the drain-thread's inline controller write in
/// [`OutputLog::append`] brackets itself with `APPEND_CTRL_ENTER`/`_EXIT` lines
/// on stderr — so a real-fixture run can PROVE the park is the controller
/// `write_frame` (an ENTER with no matching EXIT = the drain thread parked there
/// holding `Mutex<OutputLog>`). Cached once; zero cost when unset.
fn park_debug() -> bool {
    use std::sync::OnceLock;
    static ON: OnceLock<bool> = OnceLock::new();
    *ON.get_or_init(|| std::env::var_os("SPT_BROKER_DEBUG_PARK").is_some())
}

/// disconnected session from buffering without limit.

-/// W1 (REQ-HAZARD-INJECT-CONTROL-COEXIST) repro instrumentation. When

-/// `SPT_BROKER_DEBUG_PARK` is set, the drain-thread's inline controller write in

-/// [`OutputLog::append`] brackets itself with `APPEND_CTRL_ENTER`/`_EXIT` lines

-/// on stderr — so a real-fixture run can PROVE the park is the controller

-/// `write_frame` (an ENTER with no matching EXIT = the drain thread parked there

-/// holding `Mutex<OutputLog>`). Cached once; zero cost when unset.

-    static ON: OnceLock<bool> = OnceLock::new();

-    *ON.get_or_init(|| std::env::var_os("SPT_BROKER_DEBUG_PARK").is_some())

/// The viewer-channel depth (frames). A bounded SPSC queue per viewer; when it

/// OVERFLOWS the viewer is evicted — the drain `try_send`s and never blocks

/// (REQ-HAZARD-VIEWER-ISOLATION). Generous enough to absorb a normal render


Now the larger pieces. Rewrite `become_controller` to spawn the dedicated writer thread (ring replay as the writer's initial batch, like `add_viewer`), and add the `controller_by()` accessor.


    /// Become (or silently re-take) the interactive controller from `from_seq`.
    /// Replays the ring to the new controller and advances the delivered cursor
    /// to the last-successfully-written seq + 1 (D4-1: never the unsent tail, and
    /// only ever forward). Stamps `driven_by` to the new controller's identity.
    fn become_controller(&mut self, sub: SharedSend, by: Option<String>, from_seq: u64) {
        self.controller = Some(Arc::clone(&sub));
        self.controller_by = by;
        let mut last_ok: Option<u64> = None;
        if let Ok(mut s) = sub.lock() {
            for (seq, bytes) in self.ring.iter().filter(|(s, _)| *s >= from_seq) {
                let frame = output_envelope(self.session_id, *seq, bytes);
                if write_frame(&mut *s, &frame).is_ok() {
                    last_ok = Some(*seq);
                } else {
                    break; // stop at the first failed write; cursor stays put
                }
            }
        }
        if let Some(seq) = last_ok {
            self.delivered_through = advanced_cursor(self.delivered_through, seq, true);
        }
        self.stamp_driven_by();
    }

    /// The current controller's identity (`Some(node)` remote / `None` local),
    /// or `None` when undriven. The `by`-keyed ownership logic in
    /// [`resolve_subscribe`] reads this.
    fn controller_by(&self) -> Option<&str> {
        self.controller.as_ref().and_then(|c| c.by.as_deref())
    }

    /// Become (or silently re-take) the interactive controller from `from_seq`.
    ///
    /// W1: the ring replay is now the INITIAL BATCH of a dedicated controller
    /// writer thread (symmetric with [`add_viewer`]) — it is no longer written
    /// inline under the log lock. The writer thread advances the authoritative
    /// `delivered_through` cursor as it writes (D4-1: only on a successful write,
    /// monotonic, never the unsent tail). Dropping any prior [`ControllerSink`]
    /// ends its writer; bumping `controller_epoch` makes a stale deadline-evict a
    /// no-op. Stamps `driven_by` to the new controller's identity.
    fn become_controller(&mut self, sub: SharedSend, by: Option<String>, from_seq: u64) {
        // Drop the prior controller sink first (its writer ends when tx drops),
        // and bump the generation so an in-flight deadline-evict for the old
        // controller can't unseat this one.
        self.controller = None;
        self.controller_epoch += 1;
        // Ring replay = the writer thread's initial batch (owned by the thread,
        // NOT pushed through the live channel — replay must never block the drain).
        let initial: Vec<(u64, Vec<u8>)> = self
            .ring
            .iter()
            .filter(|(s, _)| *s >= from_seq)
            .cloned()
            .collect();
        let (tx, rx) = sync_channel::<CtrlMsg>(CONTROLLER_CHANNEL_DEPTH);
        let gone = Arc::new(AtomicBool::new(false));
        let writer_send = Arc::clone(&sub);
        let dt = Arc::clone(&self.delivered_through);
        let w_gone = Arc::clone(&gone);
        let sid = self.session_id;
        let writer =
            thread::spawn(move || controller_writer(sid, writer_send, initial, rx, dt, w_gone));
        self.controller = Some(ControllerSink {
            tx,
            send: sub,
            by,
            gone,
            _writer: writer,
        });
        self.stamp_driven_by();
    }

    /// Detach the controller and UNLATCH the perch — the ONE unlatch path shared
    /// by W1's deadline-evict ([`mark_controller_gone`]), [`detach_if`], and (per
    /// the W1↔W5 synergy) W5's reconcile self-heal. Dropping the sink ends its
    /// writer thread; clearing the slot re-stamps `driven_by` to `None` (so an
    /// `ONLINE+CONTROLLED` latch cannot outlive a gone controller).
    fn clear_controller(&mut self) {
        if self.controller.take().is_some() {
            self.stamp_driven_by();
        }
    }

    /// Deadline-evict path (W1): the drain observed a fully-stalled controller and
    /// timed out its `send_timeout`. Detach it — but ONLY if it is still the same
    /// controller generation the drain saw (`epoch`), so a NEWER controller that
    /// attached during the stall is never unseated.
    fn mark_controller_gone(&mut self, epoch: u64) {
        if self.controller_epoch == epoch {
            self.clear_controller();
        }
    }


    /// Become (or silently re-take) the interactive controller from `from_seq`.
    /// Replays the ring to the new controller and advances the delivered cursor
    /// to the last-successfully-written seq + 1 (D4-1: never the unsent tail, and
    /// only ever forward). Stamps `driven_by` to the new controller's identity.
    fn become_controller(&mut self, sub: SharedSend, by: Option<String>, from_seq: u64) {
        self.controller = Some(Arc::clone(&sub));
        self.controller_by = by;
        let mut last_ok: Option<u64> = None;
        if let Ok(mut s) = sub.lock() {
            for (seq, bytes) in self.ring.iter().filter(|(s, _)| *s >= from_seq) {
                let frame = output_envelope(self.session_id, *seq, bytes);
                if write_frame(&mut *s, &frame).is_ok() {
                    last_ok = Some(*seq);
                } else {
                    break; // stop at the first failed write; cursor stays put
                }
            }
        }
        if let Some(seq) = last_ok {
            self.delivered_through = advanced_cursor(self.delivered_through, seq, true);
        }
        self.stamp_driven_by();
    }

    /// The current controller's identity (`Some(node)` remote / `None` local),
    /// or `None` when undriven. The `by`-keyed ownership logic in
    /// [`resolve_subscribe`] reads this.
    fn controller_by(&self) -> Option<&str> {
        self.controller.as_ref().and_then(|c| c.by.as_deref())
    }

    /// Become (or silently re-take) the interactive controller from `from_seq`.
    ///
    /// W1: the ring replay is now the INITIAL BATCH of a dedicated controller
    /// writer thread (symmetric with [`add_viewer`]) — it is no longer written
    /// inline under the log lock. The writer thread advances the authoritative
    /// `delivered_through` cursor as it writes (D4-1: only on a successful write,
    /// monotonic, never the unsent tail). Dropping any prior [`ControllerSink`]
    /// ends its writer; bumping `controller_epoch` makes a stale deadline-evict a
    /// no-op. Stamps `driven_by` to the new controller's identity.
    fn become_controller(&mut self, sub: SharedSend, by: Option<String>, from_seq: u64) {
        // Drop the prior controller sink first (its writer ends when tx drops),
        // and bump the generation so an in-flight deadline-evict for the old
        // controller can't unseat this one.
        self.controller = None;
        self.controller_epoch += 1;
        // Ring replay = the writer thread's initial batch (owned by the thread,
        // NOT pushed through the live channel — replay must never block the drain).
        let initial: Vec<(u64, Vec<u8>)> = self
            .ring
            .iter()
            .filter(|(s, _)| *s >= from_seq)
            .cloned()
            .collect();
        let (tx, rx) = sync_channel::<CtrlMsg>(CONTROLLER_CHANNEL_DEPTH);
        let gone = Arc::new(AtomicBool::new(false));
        let writer_send = Arc::clone(&sub);
        let dt = Arc::clone(&self.delivered_through);
        let w_gone = Arc::clone(&gone);
        let sid = self.session_id;
        let writer =
            thread::spawn(move || controller_writer(sid, writer_send, initial, rx, dt, w_gone));
        self.controller = Some(ControllerSink {
            tx,
            send: sub,
            by,
            gone,
            _writer: writer,
        });
        self.stamp_driven_by();
    }

    /// Detach the controller and UNLATCH the perch — the ONE unlatch path shared
    /// by W1's deadline-evict ([`mark_controller_gone`]), [`detach_if`], and (per
    /// the W1↔W5 synergy) W5's reconcile self-heal. Dropping the sink ends its
    /// writer thread; clearing the slot re-stamps `driven_by` to `None` (so an
    /// `ONLINE+CONTROLLED` latch cannot outlive a gone controller).
    fn clear_controller(&mut self) {
        if self.controller.take().is_some() {
            self.stamp_driven_by();
        }
    }

    /// Deadline-evict path (W1): the drain observed a fully-stalled controller and
    /// timed out its `send_timeout`. Detach it — but ONLY if it is still the same
    /// controller generation the drain saw (`epoch`), so a NEWER controller that
    /// attached during the stall is never unseated.
    fn mark_controller_gone(&mut self, epoch: u64) {
        if self.controller_epoch == epoch {
            self.clear_controller();
        }
    }

+    /// The current controller's identity (`Some(node)` remote / `None` local),

+    /// or `None` when undriven. The `by`-keyed ownership logic in

+    /// [`resolve_subscribe`] reads this.

+    fn controller_by(&self) -> Option<&str> {

+        self.controller.as_ref().and_then(|c| c.by.as_deref())

-    /// Replays the ring to the new controller and advances the delivered cursor

-    /// to the last-successfully-written seq + 1 (D4-1: never the unsent tail, and

-    /// only ever forward). Stamps `driven_by` to the new controller's identity.

+    /// W1: the ring replay is now the INITIAL BATCH of a dedicated controller

+    /// writer thread (symmetric with [`add_viewer`]) — it is no longer written

+    /// inline under the log lock. The writer thread advances the authoritative

+    /// `delivered_through` cursor as it writes (D4-1: only on a successful write,

+    /// monotonic, never the unsent tail). Dropping any prior [`ControllerSink`]

+    /// ends its writer; bumping `controller_epoch` makes a stale deadline-evict a

+    /// no-op. Stamps `driven_by` to the new controller's identity.

-        self.controller = Some(Arc::clone(&sub));

-        let mut last_ok: Option<u64> = None;

-        if let Ok(mut s) = sub.lock() {

-            for (seq, bytes) in self.ring.iter().filter(|(s, _)| *s >= from_seq) {

-                let frame = output_envelope(self.session_id, *seq, bytes);

-                if write_frame(&mut *s, &frame).is_ok() {

-                    last_ok = Some(*seq);

-                    break; // stop at the first failed write; cursor stays put

+        // Drop the prior controller sink first (its writer ends when tx drops),

+        // and bump the generation so an in-flight deadline-evict for the old

+        // controller can't unseat this one.

+        // Ring replay = the writer thread's initial batch (owned by the thread,

+        // NOT pushed through the live channel — replay must never block the drain).

+        let initial: Vec<(u64, Vec<u8>)> = self

+            .filter(|(s, _)| *s >= from_seq)

+        let (tx, rx) = sync_channel::<CtrlMsg>(CONTROLLER_CHANNEL_DEPTH);

+        let gone = Arc::new(AtomicBool::new(false));

+        let writer_send = Arc::clone(&sub);

+        let dt = Arc::clone(&self.delivered_through);

+        let w_gone = Arc::clone(&gone);

+            thread::spawn(move || controller_writer(sid, writer_send, initial, rx, dt, w_gone));

+        self.controller = Some(ControllerSink {

+    /// Detach the controller and UNLATCH the perch — the ONE unlatch path shared

+    /// by W1's deadline-evict ([`mark_controller_gone`]), [`detach_if`], and (per

+    /// the W1↔W5 synergy) W5's reconcile self-heal. Dropping the sink ends its

+    /// writer thread; clearing the slot re-stamps `driven_by` to `None` (so an

+    /// `ONLINE+CONTROLLED` latch cannot outlive a gone controller).

+        if self.controller.take().is_some() {

-            self.delivered_through = advanced_cursor(self.delivered_through, seq, true);

+    /// Deadline-evict path (W1): the drain observed a fully-stalled controller and

+    /// timed out its `send_timeout`. Detach it — but ONLY if it is still the same

+    /// controller generation the drain saw (`epoch`), so a NEWER controller that

+    /// attached during the stall is never unseated.

+    fn mark_controller_gone(&mut self, epoch: u64) {

+        if self.controller_epoch == epoch {

/// Add a read-only viewer: snapshot the ring from `from_seq` into the writer


Update `resolve_subscribe` for the new controller identity accessor + off-thread displaced notice.


        let same_identity = self.controller_by == by;
        if same_identity {

        let same_identity = self.controller_by() == by.as_deref();
        if same_identity {


        let same_identity = self.controller_by == by;
        if same_identity {

        let same_identity = self.controller_by() == by.as_deref();
        if same_identity {

-        let same_identity = self.controller_by == by;

+        let same_identity = self.controller_by() == by.as_deref();

// Same operator (or both local) re-serving — silent re-take. This is

// the gate-#7 path: a successor re-taking the slot after a brain


        if self.controller_by.is_none() {
            // A remote takes an UNDRIVEN session (only the local spawner held the
            // slot) — silent control, no loud displace (there is no remote driver
            // to notify).
            self.become_controller(sub, by, from_seq);
            return SubscribeOutcome::Controller;
        }
        // A DIFFERENT remote controls it.
        match intent {
            AttachIntent::Take => {
                // The ONLY loud-displace path: notify the incumbent, then take.
                if let Some(old) = &self.controller {
                    let frame = displaced_envelope(self.session_id, by.as_deref().unwrap_or(""));
                    if let Ok(mut s) = old.lock() {
                        let _ = write_frame(&mut *s, &frame);
                    }
                }
                self.become_controller(sub, by, from_seq);
                SubscribeOutcome::TookControl
            }
            _ => SubscribeOutcome::BusyControlled {
                by: self.controller_by.clone().unwrap_or_default(),
            },
        }

        if self.controller_by().is_none() {
            // A remote takes an UNDRIVEN session (only the local spawner held the
            // slot) — silent control, no loud displace (there is no remote driver
            // to notify).
            self.become_controller(sub, by, from_seq);
            return SubscribeOutcome::Controller;
        }
        // A DIFFERENT remote controls it.
        match intent {
            AttachIntent::Take => {
                // The ONLY loud-displace path: notify the incumbent, then take.
                // W1: route the Displaced notice through the OLD controller's
                // writer thread (best-effort, off the dispatch thread) — the
                // incumbent we're kicking may be exactly the wedged one, so an
                // inline write here would block the new attacher's dispatch.
                if let Some(old) = &self.controller {
                    let frame = displaced_envelope(self.session_id, by.as_deref().unwrap_or(""));
                    let _ = old.tx.try_send(CtrlMsg::Control(frame));
                }
                self.become_controller(sub, by, from_seq);
                SubscribeOutcome::TookControl
            }
            _ => SubscribeOutcome::BusyControlled {
                by: self.controller_by().unwrap_or_default().to_string(),
            },
        }


        if self.controller_by.is_none() {
            // A remote takes an UNDRIVEN session (only the local spawner held the
            // slot) — silent control, no loud displace (there is no remote driver
            // to notify).
            self.become_controller(sub, by, from_seq);
            return SubscribeOutcome::Controller;
        }
        // A DIFFERENT remote controls it.
        match intent {
            AttachIntent::Take => {
                // The ONLY loud-displace path: notify the incumbent, then take.
                if let Some(old) = &self.controller {
                    let frame = displaced_envelope(self.session_id, by.as_deref().unwrap_or(""));
                    if let Ok(mut s) = old.lock() {
                        let _ = write_frame(&mut *s, &frame);
                    }
                }
                self.become_controller(sub, by, from_seq);
                SubscribeOutcome::TookControl
            }
            _ => SubscribeOutcome::BusyControlled {
                by: self.controller_by.clone().unwrap_or_default(),
            },
        }

        if self.controller_by().is_none() {
            // A remote takes an UNDRIVEN session (only the local spawner held the
            // slot) — silent control, no loud displace (there is no remote driver
            // to notify).
            self.become_controller(sub, by, from_seq);
            return SubscribeOutcome::Controller;
        }
        // A DIFFERENT remote controls it.
        match intent {
            AttachIntent::Take => {
                // The ONLY loud-displace path: notify the incumbent, then take.
                // W1: route the Displaced notice through the OLD controller's
                // writer thread (best-effort, off the dispatch thread) — the
                // incumbent we're kicking may be exactly the wedged one, so an
                // inline write here would block the new attacher's dispatch.
                if let Some(old) = &self.controller {
                    let frame = displaced_envelope(self.session_id, by.as_deref().unwrap_or(""));
                    let _ = old.tx.try_send(CtrlMsg::Control(frame));
                }
                self.become_controller(sub, by, from_seq);
                SubscribeOutcome::TookControl
            }
            _ => SubscribeOutcome::BusyControlled {
                by: self.controller_by().unwrap_or_default().to_string(),
            },
        }

-        if self.controller_by.is_none() {

+        if self.controller_by().is_none() {

+                // W1: route the Displaced notice through the OLD controller's

+                // writer thread (best-effort, off the dispatch thread) — the

+                // incumbent we're kicking may be exactly the wedged one, so an

+                // inline write here would block the new attacher's dispatch.

-                    if let Ok(mut s) = old.lock() {

-                        let _ = write_frame(&mut *s, &frame);

+                    let _ = old.tx.try_send(CtrlMsg::Control(frame));

-                by: self.controller_by.clone().unwrap_or_default(),

+                by: self.controller_by().unwrap_or_default().to_string(),


Update `detach_if`, `all_sinks`, `stamp_driven_by`, `is_controller`, `delivered_through()`. Read current text.


450	            return SubscribeOutcome::Controller;
451	        }
452	        // A DIFFERENT remote controls it.
453	        match intent {
454	            AttachIntent::Take => {
455	                // The ONLY loud-displace path: notify the incumbent, then take.
456	                // W1: route the Displaced notice through the OLD controller's
457	                // writer thread (best-effort, off the dispatch thread) — the
458	                // incumbent we're kicking may be exactly the wedged one, so an
459	                // inline write here would block the new attacher's dispatch.
460	                if let Some(old) = &self.controller {
461	                    let frame = displaced_envelope(self.session_id, by.as_deref().unwrap_or(""));
462	                    let _ = old.tx.try_send(CtrlMsg::Control(frame));
463	                }
464	                self.become_controller(sub, by, from_seq);
465	                SubscribeOutcome::TookControl
466	            }
467	            _ => SubscribeOutcome::BusyControlled {
468	                by: self.controller_by().unwrap_or_default().to_string(),
469	            },
470	        }
471	    }
472
473	    /// Update the stored PTY size and push a `size` frame to every viewer (the
474	    /// letterbox feed). Called on a controller resize. Viewer pushes are
475	    /// non-blocking with eviction, like [`OutputLog::append`].
476	    fn set_size_and_notify(&mut self, rows: u16, cols: u16) {
477	        self.size = (rows, cols);
478	        if self.viewers.is_empty() {
479	            return;
480	        }
481	        let frame = size_envelope(self.session_id, rows, cols);
482	        let mut evicted: Vec<u64> = Vec::new();
483	        for (vid, sink) in self.viewers.iter() {
484	            if viewer_send_evicts(&sink.tx.try_send(frame.clone())) {
485	                evicted.push(*vid);
486	            }
487	        }
488	        if !evicted.is_empty() {
489	            for vid in evicted {
490	                self.viewers.remove(&vid);
491	            }
492	            self.stamp_viewer_count();
493	        }
494	    }
495
496	    /// Detach `sub` from whatever role it held: clear the controller slot iff it
497	    /// is the current controller (a no-op if a newer brain took over — a late
498	    /// disconnect can't unseat the live controller), and remove any viewer rows
499	    /// owned by `sub`. Leaves `delivered_through` intact (D4-1). Re-stamps
500	    /// `driven_by` / `viewer_count` when a role actually changed.
501	    fn detach_if(&mut self, sub: &SharedSend) {
502	        if let Some(cur) = &self.controller {
503	            if Arc::ptr_eq(cur, sub) {
504	                self.controller = None;
505	                self.controller_by = None;
506	                self.stamp_driven_by();
507	            }
508	        }
509	        let before = self.viewers.len();
510	        self.viewers.retain(|_, sink| !Arc::ptr_eq(&sink.send, sub));
511	        if self.viewers.len() != before {
512	            self.stamp_viewer_count();
513	        }
514	    }
515
516	    /// Every sink currently attached (controller + viewers) — the recipients of
517	    /// an `exit` frame.
518	    fn all_sinks(&self) -> Vec<SharedSend> {
519	        let mut v: Vec<SharedSend> = Vec::new();
520	        if let Some(c) = &self.controller {
521	            v.push(Arc::clone(c));
522	        }
523	        for sink in self.viewers.values() {
524	            v.push(Arc::clone(&sink.send));
525	        }
526	        v
527	    }
528
529	    /// Stamp the perch's `driven_by` to the current controller's identity (the
530	    /// broker is the single writer — resolves the clear-race). The remote-drive
531	    /// detection fact (REQ-REACH-1) moved here from `serve_attach` so a displaced
532	    /// operator's teardown can never wipe the new controller's marker.
533	    /// Best-effort: a session served without a perch (raw broker tests) has
534	    /// nowhere to record.
535	    // [impl->REQ-RCVIEW-1] [impl->REQ-REACH-1]
536	    fn stamp_driven_by(&self) {
537	        if self.endpoint.is_empty() {
538	            return;
539	        }
540	        let perch = resolve_perch_path(&self.endpoint, ParentHint::Infer);
541	        let _ = spt_store::info::set_driven_by(&perch, self.controller_by.as_deref());
542	    }
543
544	    /// Stamp the perch's `viewer_count` to the live viewer count (broker is the
545	    /// single writer). Best-effort, like [`OutputLog::stamp_driven_by`].
546	    // [impl->REQ-RCVIEW-1]
547	    fn stamp_viewer_count(&self) {
548	        if self.endpoint.is_empty() {
549	            return;
550	        }
551	        let perch = resolve_perch_path(&self.endpoint, ParentHint::Infer);
552	        let _ = spt_store::info::set_viewer_count(&perch, self.viewers.len() as u32);
553	    }
554
555	    /// Whether `sub` is the current controller (the resize-exclusivity check).
556	    fn is_controller(&self, sub: &SharedSend) -> bool {
557	        self.controller
558	            .as_ref()
559	            .is_some_and(|c| Arc::ptr_eq(c, sub))

            return SubscribeOutcome::Controller;
        }
        // A DIFFERENT remote controls it.
        match intent {
            AttachIntent::Take => {
                // The ONLY loud-displace path: notify the incumbent, then take.
                // W1: route the Displaced notice through the OLD controller's
                // writer thread (best-effort, off the dispatch thread) — the
                // incumbent we're kicking may be exactly the wedged one, so an
                // inline write here would block the new attacher's dispatch.
                if let Some(old) = &self.controller {
                    let frame = displaced_envelope(self.session_id, by.as_deref().unwrap_or(""));
                    let _ = old.tx.try_send(CtrlMsg::Control(frame));
                }
                self.become_controller(sub, by, from_seq);
                SubscribeOutcome::TookControl
            }
            _ => SubscribeOutcome::BusyControlled {
                by: self.controller_by().unwrap_or_default().to_string(),
            },
        }
    }

    /// Update the stored PTY size and push a `size` frame to every viewer (the
    /// letterbox feed). Called on a controller resize. Viewer pushes are
    /// non-blocking with eviction, like [`OutputLog::append`].
    fn set_size_and_notify(&mut self, rows: u16, cols: u16) {
        self.size = (rows, cols);
        if self.viewers.is_empty() {
            return;
        }
        let frame = size_envelope(self.session_id, rows, cols);
        let mut evicted: Vec<u64> = Vec::new();
        for (vid, sink) in self.viewers.iter() {
            if viewer_send_evicts(&sink.tx.try_send(frame.clone())) {
                evicted.push(*vid);
            }
        }
        if !evicted.is_empty() {
            for vid in evicted {
                self.viewers.remove(&vid);
            }
            self.stamp_viewer_count();
        }
    }

    /// Detach `sub` from whatever role it held: clear the controller slot iff it
    /// is the current controller (a no-op if a newer brain took over — a late
    /// disconnect can't unseat the live controller), and remove any viewer rows
    /// owned by `sub`. Leaves `delivered_through` intact (D4-1). Re-stamps
    /// `driven_by` / `viewer_count` when a role actually changed.
    fn detach_if(&mut self, sub: &SharedSend) {
        if let Some(cur) = &self.controller {
            if Arc::ptr_eq(cur, sub) {
                self.controller = None;
                self.controller_by = None;
                self.stamp_driven_by();
            }
        }
        let before = self.viewers.len();
        self.viewers.retain(|_, sink| !Arc::ptr_eq(&sink.send, sub));
        if self.viewers.len() != before {
            self.stamp_viewer_count();
        }
    }

    /// Every sink currently attached (controller + viewers) — the recipients of
    /// an `exit` frame.
    fn all_sinks(&self) -> Vec<SharedSend> {
        let mut v: Vec<SharedSend> = Vec::new();
        if let Some(c) = &self.controller {
            v.push(Arc::clone(c));
        }
        for sink in self.viewers.values() {
            v.push(Arc::clone(&sink.send));
        }
        v
    }

    /// Stamp the perch's `driven_by` to the current controller's identity (the
    /// broker is the single writer — resolves the clear-race). The remote-drive
    /// detection fact (REQ-REACH-1) moved here from `serve_attach` so a displaced
    /// operator's teardown can never wipe the new controller's marker.
    /// Best-effort: a session served without a perch (raw broker tests) has
    /// nowhere to record.
    // [impl->REQ-RCVIEW-1] [impl->REQ-REACH-1]
    fn stamp_driven_by(&self) {
        if self.endpoint.is_empty() {
            return;
        }
        let perch = resolve_perch_path(&self.endpoint, ParentHint::Infer);
        let _ = spt_store::info::set_driven_by(&perch, self.controller_by.as_deref());
    }

    /// Stamp the perch's `viewer_count` to the live viewer count (broker is the
    /// single writer). Best-effort, like [`OutputLog::stamp_driven_by`].
    // [impl->REQ-RCVIEW-1]
    fn stamp_viewer_count(&self) {
        if self.endpoint.is_empty() {
            return;
        }
        let perch = resolve_perch_path(&self.endpoint, ParentHint::Infer);
        let _ = spt_store::info::set_viewer_count(&perch, self.viewers.len() as u32);
    }

    /// Whether `sub` is the current controller (the resize-exclusivity check).
    fn is_controller(&self, sub: &SharedSend) -> bool {
        self.controller
            .as_ref()
            .is_some_and(|c| Arc::ptr_eq(c, sub))


    fn detach_if(&mut self, sub: &SharedSend) {
        if let Some(cur) = &self.controller {
            if Arc::ptr_eq(cur, sub) {
                self.controller = None;
                self.controller_by = None;
                self.stamp_driven_by();
            }
        }
        let before = self.viewers.len();

    fn detach_if(&mut self, sub: &SharedSend) {
        let is_ctrl = self
            .controller
            .as_ref()
            .is_some_and(|c| Arc::ptr_eq(&c.send, sub));
        if is_ctrl {
            self.clear_controller(); // drops the sink (ends its writer) + unlatches
        }
        let before = self.viewers.len();


    fn detach_if(&mut self, sub: &SharedSend) {
        if let Some(cur) = &self.controller {
            if Arc::ptr_eq(cur, sub) {
                self.controller = None;
                self.controller_by = None;
                self.stamp_driven_by();
            }
        }
        let before = self.viewers.len();

    fn detach_if(&mut self, sub: &SharedSend) {
        let is_ctrl = self
            .controller
            .as_ref()
            .is_some_and(|c| Arc::ptr_eq(&c.send, sub));
        if is_ctrl {
            self.clear_controller(); // drops the sink (ends its writer) + unlatches
        }
        let before = self.viewers.len();

/// owned by `sub`. Leaves `delivered_through` intact (D4-1). Re-stamps

/// `driven_by` / `viewer_count` when a role actually changed.

-        if let Some(cur) = &self.controller {

-                self.controller = None;

-                self.controller_by = None;

-                self.stamp_driven_by();

+            .is_some_and(|c| Arc::ptr_eq(&c.send, sub));

+            self.clear_controller(); // drops the sink (ends its writer) + unlatches

self.viewers.retain(|_, sink| !Arc::ptr_eq(&sink.send, sub));


        let mut v: Vec<SharedSend> = Vec::new();
        if let Some(c) = &self.controller {
            v.push(Arc::clone(c));
        }
        for sink in self.viewers.values() {

        let mut v: Vec<SharedSend> = Vec::new();
        if let Some(c) = &self.controller {
            v.push(Arc::clone(&c.send));
        }
        for sink in self.viewers.values() {


        let mut v: Vec<SharedSend> = Vec::new();
        if let Some(c) = &self.controller {
            v.push(Arc::clone(c));
        }
        for sink in self.viewers.values() {

        let mut v: Vec<SharedSend> = Vec::new();
        if let Some(c) = &self.controller {
            v.push(Arc::clone(&c.send));
        }
        for sink in self.viewers.values() {

fn all_sinks(&self) -> Vec<SharedSend> {

+            v.push(Arc::clone(&c.send));


        let perch = resolve_perch_path(&self.endpoint, ParentHint::Infer);
        let _ = spt_store::info::set_driven_by(&perch, self.controller_by.as_deref());
    }

        let perch = resolve_perch_path(&self.endpoint, ParentHint::Infer);
        let _ = spt_store::info::set_driven_by(&perch, self.controller_by());
    }


        let perch = resolve_perch_path(&self.endpoint, ParentHint::Infer);
        let _ = spt_store::info::set_driven_by(&perch, self.controller_by.as_deref());
    }

        let perch = resolve_perch_path(&self.endpoint, ParentHint::Infer);
        let _ = spt_store::info::set_driven_by(&perch, self.controller_by());
    }

-        let _ = spt_store::info::set_driven_by(&perch, self.controller_by.as_deref());

+        let _ = spt_store::info::set_driven_by(&perch, self.controller_by());

/// Stamp the perch's `viewer_count` to the live viewer count (broker is the


555	    /// Whether `sub` is the current controller (the resize-exclusivity check).
556	    fn is_controller(&self, sub: &SharedSend) -> bool {
557	        self.controller
558	            .as_ref()
559	            .is_some_and(|c| Arc::ptr_eq(c, sub))
560	    }
561
562	    /// The next seq a re-attaching controller still needs (the persisted resume
563	    /// cursor surfaced in `KIND_SESSIONS` → `resume_seq`).
564	    fn delivered_through(&self) -> u64 {
565	        self.delivered_through
566	    }
567	}
568
569	/// A viewer's dedicated writer thread (REQ-HAZARD-VIEWER-ISOLATION): write the
570	/// `initial` batch (size frame + ring replay) once, then drain live frames from
571	/// `rx` with a BLOCKING socket write each. A failed write (dead viewer) ends the
572	/// thread; the drain thread's next `try_send` then sees `Disconnected` and
573	/// evicts the row. The drain thread itself never blocks on this socket.
574	fn viewer_writer(send: SharedSend, initial: Vec<Envelope>, rx: Receiver<Envelope>) {
575	    for frame in &initial {
576	        let ok = match send.lock() {
577	            Ok(mut s) => write_frame(&mut *s, frame).is_ok(),
578	            Err(_) => false,
579	        };
580	        if !ok {
581	            return;
582	        }
583	    }
584	    while let Ok(frame) = rx.recv() {
585	        let ok = match send.lock() {
586	            Ok(mut s) => write_frame(&mut *s, &frame).is_ok(),
587	            Err(_) => false,
588	        };
589	        if !ok {
590	            return;
591	        }
592	    }
593	}
594
595	/// A child the broker hosts under a PTY — the §B-owned resources for one
596	/// session, plus its gapless-resume output log.
597	struct HostedSession {
598	    /// The PTY + child (PTY master/writer + spawned child process).
599	    session: Arc<PtySession>,
600	    /// The output drain pump (kept so teardown can stop it).
601	    #[allow(dead_code)] // held for ownership/teardown; not read directly
602	    drain: Drain,
603	    /// The sequenced, buffered output + current subscriber.
604	    log: Arc<Mutex<OutputLog>>,
605	    /// The owning endpoint (the spawn's label; empty = unlabeled). The
606	    /// inbound dispatcher's gate subject for remote-drive (D9-1).
607	    endpoint: String,
608	}
609
610	/// The broker process kernel. Owns the listening socket, the table of hosted
611	/// sessions, and the broker-owned idempotency anchor (B5); holds no logic state
612	/// (ADR-0004 §B). The [`EffectJournal`] is a §B resource — the durable
613	/// recovery anchor a brain crash must not lose, so it lives in the broker, not
614	/// the brain (Spike #6 constraint 1).
615	pub struct Broker {
616	    listener: LocalSocketTransport,
617	    sessions: Arc<Mutex<HashMap<u64, HostedSession>>>,
618	    next_id: AtomicU64,
619	    log_cap_chunks: usize,
620	    /// The exactly-once anchor for idempotent (`op_id`-carrying) effects.
621	    journal: Arc<EffectJournal>,
622	    /// The broker-owned net endpoint + live QUIC connections (D4a, ADR-0004 §B).
623	    /// Empty when bound without a network host (net-disabled / most tests) OR
624	    /// when net is still being brought up (REQ-DAEMON-9 boot-race self-heal):
625	    /// a `OnceLock` so the background net-retry can ATTACH the host after bind
626	    /// without a relock on the hot effect-dispatch read path (`.get()` is
627	    /// lock-free). Settable exactly once — the first host wins.
628	    net: std::sync::OnceLock<NetHost>,
629	    /// The broker→supervisor planned-restart signal (ADR-0018 D3-3): a

    /// Whether `sub` is the current controller (the resize-exclusivity check).
    fn is_controller(&self, sub: &SharedSend) -> bool {
        self.controller
            .as_ref()
            .is_some_and(|c| Arc::ptr_eq(c, sub))
    }

    /// The next seq a re-attaching controller still needs (the persisted resume
    /// cursor surfaced in `KIND_SESSIONS` → `resume_seq`).
    fn delivered_through(&self) -> u64 {
        self.delivered_through
    }
}

/// A viewer's dedicated writer thread (REQ-HAZARD-VIEWER-ISOLATION): write the
/// `initial` batch (size frame + ring replay) once, then drain live frames from
/// `rx` with a BLOCKING socket write each. A failed write (dead viewer) ends the
/// thread; the drain thread's next `try_send` then sees `Disconnected` and
/// evicts the row. The drain thread itself never blocks on this socket.
fn viewer_writer(send: SharedSend, initial: Vec<Envelope>, rx: Receiver<Envelope>) {
    for frame in &initial {
        let ok = match send.lock() {
            Ok(mut s) => write_frame(&mut *s, frame).is_ok(),
            Err(_) => false,
        };
        if !ok {
            return;
        }
    }
    while let Ok(frame) = rx.recv() {
        let ok = match send.lock() {
            Ok(mut s) => write_frame(&mut *s, &frame).is_ok(),
            Err(_) => false,
        };
        if !ok {
            return;
        }
    }
}

/// A child the broker hosts under a PTY — the §B-owned resources for one
/// session, plus its gapless-resume output log.
struct HostedSession {
    /// The PTY + child (PTY master/writer + spawned child process).
    session: Arc<PtySession>,
    /// The output drain pump (kept so teardown can stop it).
    #[allow(dead_code)] // held for ownership/teardown; not read directly
    drain: Drain,
    /// The sequenced, buffered output + current subscriber.
    log: Arc<Mutex<OutputLog>>,
    /// The owning endpoint (the spawn's label; empty = unlabeled). The
    /// inbound dispatcher's gate subject for remote-drive (D9-1).
    endpoint: String,
}

/// The broker process kernel. Owns the listening socket, the table of hosted
/// sessions, and the broker-owned idempotency anchor (B5); holds no logic state
/// (ADR-0004 §B). The [`EffectJournal`] is a §B resource — the durable
/// recovery anchor a brain crash must not lose, so it lives in the broker, not
/// the brain (Spike #6 constraint 1).
pub struct Broker {
    listener: LocalSocketTransport,
    sessions: Arc<Mutex<HashMap<u64, HostedSession>>>,
    next_id: AtomicU64,
    log_cap_chunks: usize,
    /// The exactly-once anchor for idempotent (`op_id`-carrying) effects.
    journal: Arc<EffectJournal>,
    /// The broker-owned net endpoint + live QUIC connections (D4a, ADR-0004 §B).
    /// Empty when bound without a network host (net-disabled / most tests) OR
    /// when net is still being brought up (REQ-DAEMON-9 boot-race self-heal):
    /// a `OnceLock` so the background net-retry can ATTACH the host after bind
    /// without a relock on the hot effect-dispatch read path (`.get()` is
    /// lock-free). Settable exactly once — the first host wins.
    net: std::sync::OnceLock<NetHost>,
    /// The broker→supervisor planned-restart signal (ADR-0018 D3-3): a


    /// Whether `sub` is the current controller (the resize-exclusivity check).
    fn is_controller(&self, sub: &SharedSend) -> bool {
        self.controller
            .as_ref()
            .is_some_and(|c| Arc::ptr_eq(c, sub))
    }

    /// The next seq a re-attaching controller still needs (the persisted resume
    /// cursor surfaced in `KIND_SESSIONS` → `resume_seq`).
    fn delivered_through(&self) -> u64 {
        self.delivered_through
    }
}

    /// Whether `sub` is the current controller (the resize-exclusivity check).
    fn is_controller(&self, sub: &SharedSend) -> bool {
        self.controller
            .as_ref()
            .is_some_and(|c| Arc::ptr_eq(&c.send, sub))
    }

    /// The next seq a re-attaching controller still needs (the persisted resume
    /// cursor surfaced in `KIND_SESSIONS` → `resume_seq`). W1: read from the
    /// atomic the controller writer thread advances.
    fn delivered_through(&self) -> u64 {
        self.delivered_through.load(Ordering::Acquire)
    }
}


    /// Whether `sub` is the current controller (the resize-exclusivity check).
    fn is_controller(&self, sub: &SharedSend) -> bool {
        self.controller
            .as_ref()
            .is_some_and(|c| Arc::ptr_eq(c, sub))
    }

    /// The next seq a re-attaching controller still needs (the persisted resume
    /// cursor surfaced in `KIND_SESSIONS` → `resume_seq`).
    fn delivered_through(&self) -> u64 {
        self.delivered_through
    }
}

    /// Whether `sub` is the current controller (the resize-exclusivity check).
    fn is_controller(&self, sub: &SharedSend) -> bool {
        self.controller
            .as_ref()
            .is_some_and(|c| Arc::ptr_eq(&c.send, sub))
    }

    /// The next seq a re-attaching controller still needs (the persisted resume
    /// cursor surfaced in `KIND_SESSIONS` → `resume_seq`). W1: read from the
    /// atomic the controller writer thread advances.
    fn delivered_through(&self) -> u64 {
        self.delivered_through.load(Ordering::Acquire)
    }
}

-            .is_some_and(|c| Arc::ptr_eq(c, sub))

+            .is_some_and(|c| Arc::ptr_eq(&c.send, sub))

-    /// cursor surfaced in `KIND_SESSIONS` → `resume_seq`).

+    /// cursor surfaced in `KIND_SESSIONS` → `resume_seq`). W1: read from the

+    /// atomic the controller writer thread advances.

+        self.delivered_through.load(Ordering::Acquire)


Now add the `CtrlMsg` enum, `ControllerJob`, `advance_delivered`, and `controller_writer` after `viewer_writer`.


    while let Ok(frame) = rx.recv() {
        let ok = match send.lock() {
            Ok(mut s) => write_frame(&mut *s, &frame).is_ok(),
            Err(_) => false,
        };
        if !ok {
            return;
        }
    }
}

/// A child the broker hosts under a PTY — the §B-owned resources for one

    while let Ok(frame) = rx.recv() {
        let ok = match send.lock() {
            Ok(mut s) => write_frame(&mut *s, &frame).is_ok(),
            Err(_) => false,
        };
        if !ok {
            return;
        }
    }
}

/// A message to the CONTROLLER writer thread (W1). `Output` carries a sequenced
/// chunk and advances the authoritative `delivered_through` on a successful
/// write; `Control` is an out-of-band notice (Displaced, …) that is written but
/// does NOT move the resume cursor.
enum CtrlMsg {
    Output(u64, Envelope),
    Control(Envelope),
}

/// One live-output delivery to the controller, handed back by
/// [`OutputLog::append`] so the drain can do the bounded send OFF the log lock
/// (W1 / REQ-HAZARD-INJECT-CONTROL-COEXIST). [`ControllerJob::deliver`] blocks at
/// most [`CONTROLLER_WRITE_DEADLINE`]; on a fully-stalled controller it returns
/// the `epoch` so the drain can detach exactly that generation.
struct ControllerJob {
    tx: SyncSender<CtrlMsg>,
    seq: u64,
    frame: Envelope,
    epoch: u64,
}

impl ControllerJob {
    /// Deliver into the controller's writer-thread channel with a bounded
    /// deadline. `Ok(())` = queued (the writer does the blocking socket write);
    /// `Err(epoch)` = the controller is fully stalled or gone and must be
    /// detached (the wedge is thereby BOUNDED, never permanent — the v0.12.x
    /// root). A live-but-slow controller drains a slot before the deadline and is
    /// untouched.
    fn deliver(self) -> Result<(), u64> {
        match self
            .tx
            .send_timeout(CtrlMsg::Output(self.seq, self.frame), CONTROLLER_WRITE_DEADLINE)
        {
            Ok(()) => Ok(()),
            Err(SendTimeoutError::Timeout(_)) | Err(SendTimeoutError::Disconnected(_)) => {
                Err(self.epoch)
            }
        }
    }
}

/// Advance the shared `delivered_through` cursor to `seq + 1`, monotonically
/// (D4-1, via [`advanced_cursor`]) and CAS-safe against a brief two-writer
/// overlap during a controller displace.
fn advance_delivered(dt: &AtomicU64, seq: u64) {
    let mut cur = dt.load(Ordering::Acquire);
    loop {
        let next = advanced_cursor(cur, seq, true);
        if next == cur {
            return;
        }
        match dt.compare_exchange_weak(cur, next, Ordering::AcqRel, Ordering::Acquire) {
            Ok(_) => return,
            Err(actual) => cur = actual,
        }
    }
}

/// The interactive CONTROLLER's dedicated writer thread (W1 /
/// REQ-HAZARD-INJECT-CONTROL-COEXIST) — the authoritative analog of
/// [`viewer_writer`]. Write the `initial` ring-replay batch (advancing the resume
/// cursor on each success), then drain live [`CtrlMsg`]s with a BLOCKING socket
/// write each — so a backed-up controller blocks ONLY this thread, never the
/// session drain (which used to write the controller inline under the log lock).
/// A failed write (dead operator) flips `gone` and ends the thread; the drain's
/// next bounded `send_timeout` then sees `Disconnected` and detaches the row.
/// `Output` advances `delivered_through`; `Control` (Displaced/…) does not.
fn controller_writer(
    sid: u64,
    send: SharedSend,
    initial: Vec<(u64, Vec<u8>)>,
    rx: Receiver<CtrlMsg>,
    delivered_through: Arc<AtomicU64>,
    gone: Arc<AtomicBool>,
) {
    for (seq, bytes) in &initial {
        let frame = output_envelope(sid, *seq, bytes);
        let ok = match send.lock() {
            Ok(mut s) => write_frame(&mut *s, &frame).is_ok(),
            Err(_) => false,
        };
        if !ok {
            gone.store(true, Ordering::Relaxed);
            return;
        }
        advance_delivered(&delivered_through, *seq);
    }
    while let Ok(msg) = rx.recv() {
        let (frame, seq) = match &msg {
            CtrlMsg::Output(seq, frame) => (frame, Some(*seq)),
            CtrlMsg::Control(frame) => (frame, None),
        };
        let ok = match send.lock() {
            Ok(mut s) => write_frame(&mut *s, frame).is_ok(),
            Err(_) => false,
        };
        if !ok {
            gone.store(true, Ordering::Relaxed);
            return;
        }
        if let Some(seq) = seq {
            advance_delivered(&delivered_through, seq);
        }
    }
}

/// A child the broker hosts under a PTY — the §B-owned resources for one


    while let Ok(frame) = rx.recv() {
        let ok = match send.lock() {
            Ok(mut s) => write_frame(&mut *s, &frame).is_ok(),
            Err(_) => false,
        };
        if !ok {
            return;
        }
    }
}

/// A child the broker hosts under a PTY — the §B-owned resources for one

    while let Ok(frame) = rx.recv() {
        let ok = match send.lock() {
            Ok(mut s) => write_frame(&mut *s, &frame).is_ok(),
            Err(_) => false,
        };
        if !ok {
            return;
        }
    }
}

/// A message to the CONTROLLER writer thread (W1). `Output` carries a sequenced
/// chunk and advances the authoritative `delivered_through` on a successful
/// write; `Control` is an out-of-band notice (Displaced, …) that is written but
/// does NOT move the resume cursor.
enum CtrlMsg {
    Output(u64, Envelope),
    Control(Envelope),
}

/// One live-output delivery to the controller, handed back by
/// [`OutputLog::append`] so the drain can do the bounded send OFF the log lock
/// (W1 / REQ-HAZARD-INJECT-CONTROL-COEXIST). [`ControllerJob::deliver`] blocks at
/// most [`CONTROLLER_WRITE_DEADLINE`]; on a fully-stalled controller it returns
/// the `epoch` so the drain can detach exactly that generation.
struct ControllerJob {
    tx: SyncSender<CtrlMsg>,
    seq: u64,
    frame: Envelope,
    epoch: u64,
}

impl ControllerJob {
    /// Deliver into the controller's writer-thread channel with a bounded
    /// deadline. `Ok(())` = queued (the writer does the blocking socket write);
    /// `Err(epoch)` = the controller is fully stalled or gone and must be
    /// detached (the wedge is thereby BOUNDED, never permanent — the v0.12.x
    /// root). A live-but-slow controller drains a slot before the deadline and is
    /// untouched.
    fn deliver(self) -> Result<(), u64> {
        match self
            .tx
            .send_timeout(CtrlMsg::Output(self.seq, self.frame), CONTROLLER_WRITE_DEADLINE)
        {
            Ok(()) => Ok(()),
            Err(SendTimeoutError::Timeout(_)) | Err(SendTimeoutError::Disconnected(_)) => {
                Err(self.epoch)
            }
        }
    }
}

/// Advance the shared `delivered_through` cursor to `seq + 1`, monotonically
/// (D4-1, via [`advanced_cursor`]) and CAS-safe against a brief two-writer
/// overlap during a controller displace.
fn advance_delivered(dt: &AtomicU64, seq: u64) {
    let mut cur = dt.load(Ordering::Acquire);
    loop {
        let next = advanced_cursor(cur, seq, true);
        if next == cur {
            return;
        }
        match dt.compare_exchange_weak(cur, next, Ordering::AcqRel, Ordering::Acquire) {
            Ok(_) => return,
            Err(actual) => cur = actual,
        }
    }
}

/// The interactive CONTROLLER's dedicated writer thread (W1 /
/// REQ-HAZARD-INJECT-CONTROL-COEXIST) — the authoritative analog of
/// [`viewer_writer`]. Write the `initial` ring-replay batch (advancing the resume
/// cursor on each success), then drain live [`CtrlMsg`]s with a BLOCKING socket
/// write each — so a backed-up controller blocks ONLY this thread, never the
/// session drain (which used to write the controller inline under the log lock).
/// A failed write (dead operator) flips `gone` and ends the thread; the drain's
/// next bounded `send_timeout` then sees `Disconnected` and detaches the row.
/// `Output` advances `delivered_through`; `Control` (Displaced/…) does not.
fn controller_writer(
    sid: u64,
    send: SharedSend,
    initial: Vec<(u64, Vec<u8>)>,
    rx: Receiver<CtrlMsg>,
    delivered_through: Arc<AtomicU64>,
    gone: Arc<AtomicBool>,
) {
    for (seq, bytes) in &initial {
        let frame = output_envelope(sid, *seq, bytes);
        let ok = match send.lock() {
            Ok(mut s) => write_frame(&mut *s, &frame).is_ok(),
            Err(_) => false,
        };
        if !ok {
            gone.store(true, Ordering::Relaxed);
            return;
        }
        advance_delivered(&delivered_through, *seq);
    }
    while let Ok(msg) = rx.recv() {
        let (frame, seq) = match &msg {
            CtrlMsg::Output(seq, frame) => (frame, Some(*seq)),
            CtrlMsg::Control(frame) => (frame, None),
        };
        let ok = match send.lock() {
            Ok(mut s) => write_frame(&mut *s, frame).is_ok(),
            Err(_) => false,
        };
        if !ok {
            gone.store(true, Ordering::Relaxed);
            return;
        }
        if let Some(seq) = seq {
            advance_delivered(&delivered_through, seq);
        }
    }
}

/// A child the broker hosts under a PTY — the §B-owned resources for one

+/// A message to the CONTROLLER writer thread (W1). `Output` carries a sequenced

+/// chunk and advances the authoritative `delivered_through` on a successful

+/// write; `Control` is an out-of-band notice (Displaced, …) that is written but

+/// One live-output delivery to the controller, handed back by

+/// [`OutputLog::append`] so the drain can do the bounded send OFF the log lock

+/// (W1 / REQ-HAZARD-INJECT-CONTROL-COEXIST). [`ControllerJob::deliver`] blocks at

+/// most [`CONTROLLER_WRITE_DEADLINE`]; on a fully-stalled controller it returns

+/// the `epoch` so the drain can detach exactly that generation.

+    /// Deliver into the controller's writer-thread channel with a bounded

+    /// deadline. `Ok(())` = queued (the writer does the blocking socket write);

+    /// `Err(epoch)` = the controller is fully stalled or gone and must be

+    /// detached (the wedge is thereby BOUNDED, never permanent — the v0.12.x

+    /// root). A live-but-slow controller drains a slot before the deadline and is

+    fn deliver(self) -> Result<(), u64> {

+            .send_timeout(CtrlMsg::Output(self.seq, self.frame), CONTROLLER_WRITE_DEADLINE)

+            Err(SendTimeoutError::Timeout(_)) | Err(SendTimeoutError::Disconnected(_)) => {

+/// Advance the shared `delivered_through` cursor to `seq + 1`, monotonically

+/// (D4-1, via [`advanced_cursor`]) and CAS-safe against a brief two-writer

+/// overlap during a controller displace.

+fn advance_delivered(dt: &AtomicU64, seq: u64) {

+    let mut cur = dt.load(Ordering::Acquire);

+        let next = advanced_cursor(cur, seq, true);

+        match dt.compare_exchange_weak(cur, next, Ordering::AcqRel, Ordering::Acquire) {

+            Err(actual) => cur = actual,

+/// The interactive CONTROLLER's dedicated writer thread (W1 /

+/// REQ-HAZARD-INJECT-CONTROL-COEXIST) — the authoritative analog of

+/// [`viewer_writer`]. Write the `initial` ring-replay batch (advancing the resume

+/// cursor on each success), then drain live [`CtrlMsg`]s with a BLOCKING socket

+/// write each — so a backed-up controller blocks ONLY this thread, never the

+/// session drain (which used to write the controller inline under the log lock).

+/// A failed write (dead operator) flips `gone` and ends the thread; the drain's

+/// next bounded `send_timeout` then sees `Disconnected` and detaches the row.

+/// `Output` advances `delivered_through`; `Control` (Displaced/…) does not.

+        let frame = output_envelope(sid, *seq, bytes);

+            Ok(mut s) => write_frame(&mut *s, &frame).is_ok(),

+            gone.store(true, Ordering::Relaxed);

+        advance_delivered(&delivered_through, *seq);

+        let (frame, seq) = match &msg {

+            CtrlMsg::Output(seq, frame) => (frame, Some(*seq)),

+            CtrlMsg::Control(frame) => (frame, None),

+            Ok(mut s) => write_frame(&mut *s, frame).is_ok(),

+            advance_delivered(&delivered_through, seq);

/// session, plus its gapless-resume output log.


Update the drain closure to deliver off-lock with the bounded deadline.


        // Output drain → appends to the log (which live-sends to the subscriber).
        let log_drain = Arc::clone(&log);
        let drain = session
            .drain(move |chunk| {
                log_drain.lock().unwrap().append(chunk);
            })
            .map_err(|e| format!("drain failed: {e}"))?;

        // Output drain → append under the log lock (fast: ring + viewer fan-out),
        // then deliver to the controller OFF the lock with a bounded deadline
        // (W1 / REQ-HAZARD-INJECT-CONTROL-COEXIST). The controller write is no
        // longer inline under the log lock, so a backed-up controller can never
        // wedge the session; a fully-stalled controller is detached after the
        // deadline (bounded wedge, never permanent).
        let log_drain = Arc::clone(&log);
        let drain = session
            .drain(move |chunk| {
                let job = log_drain.lock().unwrap().append(chunk);
                if let Some(job) = job {
                    if let Err(epoch) = job.deliver() {
                        log_drain.lock().unwrap().mark_controller_gone(epoch);
                    }
                }
            })
            .map_err(|e| format!("drain failed: {e}"))?;


        // Output drain → appends to the log (which live-sends to the subscriber).
        let log_drain = Arc::clone(&log);
        let drain = session
            .drain(move |chunk| {
                log_drain.lock().unwrap().append(chunk);
            })
            .map_err(|e| format!("drain failed: {e}"))?;

        // Output drain → append under the log lock (fast: ring + viewer fan-out),
        // then deliver to the controller OFF the lock with a bounded deadline
        // (W1 / REQ-HAZARD-INJECT-CONTROL-COEXIST). The controller write is no
        // longer inline under the log lock, so a backed-up controller can never
        // wedge the session; a fully-stalled controller is detached after the
        // deadline (bounded wedge, never permanent).
        let log_drain = Arc::clone(&log);
        let drain = session
            .drain(move |chunk| {
                let job = log_drain.lock().unwrap().append(chunk);
                if let Some(job) = job {
                    if let Err(epoch) = job.deliver() {
                        log_drain.lock().unwrap().mark_controller_gone(epoch);
                    }
                }
            })
            .map_err(|e| format!("drain failed: {e}"))?;

-        // Output drain → appends to the log (which live-sends to the subscriber).

+        // Output drain → append under the log lock (fast: ring + viewer fan-out),

+        // then deliver to the controller OFF the lock with a bounded deadline

+        // (W1 / REQ-HAZARD-INJECT-CONTROL-COEXIST). The controller write is no

+        // longer inline under the log lock, so a backed-up controller can never

+        // wedge the session; a fully-stalled controller is detached after the

+        // deadline (bounded wedge, never permanent).

-                log_drain.lock().unwrap().append(chunk);

+                let job = log_drain.lock().unwrap().append(chunk);

+                if let Some(job) = job {

+                    if let Err(epoch) = job.deliver() {

+                        log_drain.lock().unwrap().mark_controller_gone(epoch);


Remove the redundant `gone` field (the `Disconnected` send result already signals a dead writer). Three sites + the `AtomicBool` import.


    /// The controller's identity: `Some(node)` = a remote operator, `None` =
    /// local (the brain's spawn-reader / resume). Ownership keys on this.
    by: Option<String>,
    /// Set by the writer thread when its socket write fails (dead operator) — a
    /// cheap liveness flag the drain can observe without joining the thread.
    gone: Arc<AtomicBool>,
    /// The writer thread handle (held for ownership; exits when `tx` drops, a
    /// socket write fails, or the deadline detaches it).
    _writer: JoinHandle<()>,
}

    /// The controller's identity: `Some(node)` = a remote operator, `None` =
    /// local (the brain's spawn-reader / resume). Ownership keys on this.
    by: Option<String>,
    /// The writer thread handle (held for ownership; exits when `tx` drops — the
    /// drain's bounded `send_timeout` then sees `Disconnected` and detaches — or
    /// when a socket write fails).
    _writer: JoinHandle<()>,
}


    /// The controller's identity: `Some(node)` = a remote operator, `None` =
    /// local (the brain's spawn-reader / resume). Ownership keys on this.
    by: Option<String>,
    /// Set by the writer thread when its socket write fails (dead operator) — a
    /// cheap liveness flag the drain can observe without joining the thread.
    gone: Arc<AtomicBool>,
    /// The writer thread handle (held for ownership; exits when `tx` drops, a
    /// socket write fails, or the deadline detaches it).
    _writer: JoinHandle<()>,
}

    /// The controller's identity: `Some(node)` = a remote operator, `None` =
    /// local (the brain's spawn-reader / resume). Ownership keys on this.
    by: Option<String>,
    /// The writer thread handle (held for ownership; exits when `tx` drops — the
    /// drain's bounded `send_timeout` then sees `Disconnected` and detaches — or
    /// when a socket write fails).
    _writer: JoinHandle<()>,
}

-    /// Set by the writer thread when its socket write fails (dead operator) — a

-    /// cheap liveness flag the drain can observe without joining the thread.

-    /// The writer thread handle (held for ownership; exits when `tx` drops, a

-    /// socket write fails, or the deadline detaches it).

+    /// The writer thread handle (held for ownership; exits when `tx` drops — the

+    /// drain's bounded `send_timeout` then sees `Disconnected` and detaches — or


        let (tx, rx) = sync_channel::<CtrlMsg>(CONTROLLER_CHANNEL_DEPTH);
        let gone = Arc::new(AtomicBool::new(false));
        let writer_send = Arc::clone(&sub);
        let dt = Arc::clone(&self.delivered_through);
        let w_gone = Arc::clone(&gone);
        let sid = self.session_id;
        let writer =
            thread::spawn(move || controller_writer(sid, writer_send, initial, rx, dt, w_gone));
        self.controller = Some(ControllerSink {
            tx,
            send: sub,
            by,
            gone,
            _writer: writer,
        });

        let (tx, rx) = sync_channel::<CtrlMsg>(CONTROLLER_CHANNEL_DEPTH);
        let writer_send = Arc::clone(&sub);
        let dt = Arc::clone(&self.delivered_through);
        let sid = self.session_id;
        let writer = thread::spawn(move || controller_writer(sid, writer_send, initial, rx, dt));
        self.controller = Some(ControllerSink {
            tx,
            send: sub,
            by,
            _writer: writer,
        });


        let (tx, rx) = sync_channel::<CtrlMsg>(CONTROLLER_CHANNEL_DEPTH);
        let gone = Arc::new(AtomicBool::new(false));
        let writer_send = Arc::clone(&sub);
        let dt = Arc::clone(&self.delivered_through);
        let w_gone = Arc::clone(&gone);
        let sid = self.session_id;
        let writer =
            thread::spawn(move || controller_writer(sid, writer_send, initial, rx, dt, w_gone));
        self.controller = Some(ControllerSink {
            tx,
            send: sub,
            by,
            gone,
            _writer: writer,
        });

        let (tx, rx) = sync_channel::<CtrlMsg>(CONTROLLER_CHANNEL_DEPTH);
        let writer_send = Arc::clone(&sub);
        let dt = Arc::clone(&self.delivered_through);
        let sid = self.session_id;
        let writer = thread::spawn(move || controller_writer(sid, writer_send, initial, rx, dt));
        self.controller = Some(ControllerSink {
            tx,
            send: sub,
            by,
            _writer: writer,
        });

-        let gone = Arc::new(AtomicBool::new(false));

-        let w_gone = Arc::clone(&gone);

-            thread::spawn(move || controller_writer(sid, writer_send, initial, rx, dt, w_gone));

+        let writer = thread::spawn(move || controller_writer(sid, writer_send, initial, rx, dt));