0038 — The spawner names the pane; while a Driver's sid is unknown, the judge reads that pane's stamp
- Status: Accepted. The build is local-bin
slug-owner+start-driver(part 3a) and this repo's Supervisor (part 3b). - Date: 2026-10-02
- Deciders: the dock-found-fleet Driver, assigning row
bug-two-live-sessions-share-one-driver-slugpart 3: "the empty-owner window … IS in our fleet scope … close the window."
The problem
A Driver's task dir holds the claim register, the acceptance gate and the row fence. slug-owner decides whose that dir is from task.json's operatorSid.
Every spawn writes that sid empty:
- the Supervisor on every mint and every respawn (
driverSid: '', "resolved from the roster on the next sweep"); start-driverwhenever the pane's session stamp has not landed within its wait.
Until a later sweep fills the sid in, slug-owner answered 5 ("cannot tell") to every session. That includes a predecessor that was still running and about to write the same register, which is the 2026-09-12 incident's shape. The window is a sweep long, and it opens on every respawn.
The decision
The spawner records the pane it put the Driver in, as
driverPane, in the same write that blanks the sid. That is the Supervisor'spendingDriver()(for both the mint and the respawn), its intake spawn (consumeIntakes), andstart-driver's task.json mint. One writer per spawn; many readers.While the sid is empty, the judge asks the pane, not the name.
slug-ownerrunssession-id --sid-of-pane <driverPane>and answers:- 0 if the stamp is the asker;
- 9 (with that session's liveness) if it is somebody else;
- 5 if the pane has no stamp yet, or no pane is recorded.
The pane's current stamp decides, never the pane's name: the 2026-09-12 incarnations shared one pane.
driverPaneis meaningful only while the sid is empty. It is written at spawn and never cleared, so after the sid resolves, or a takeover arms from another pane, it can name a stale pane. Nothing may read it as "the Driver's current pane".The launcher is never the owner. It is live when the Driver it spawned first arms. Recording it as owner would make the judge refuse that very Driver. Launch-written acceptance items carry the launcher as their author (
addedBy), which is a different fact.The Supervisor carries the ownership record through
readTasks—driverPaneand the takeover recorddriver-herewrites (priorDriverSid/priorOperatorSid,driverEpoch/operatorEpoch,handovers). Its allowlist used to erase them on the next write. That is why no task on the box carried ahandoversentry, and why the slug-owner catalog entry'ssignalscould never fill.
Integration
The two systems talk only through the shared task.json fields, never by calling each other (ADR-0003). The Supervisor writes driverPane; slug-owner reads it. Neither calls the other.
What this does not close
- The boot sub-window, before the new session stamps its pane, still reads 5. That is honest: nobody can be named yet.
- Releasing a row out from under a live lane is agent-smith#511, under a separate row.
Amendment of 2026-10-02: every spawn marks its own session
What was wrong. Decision 2 judged the pending window by the stamp on driverPane. But driverPane is a tmux session name, it is never cleared, and names are reused. A later session that took op-<task> would be read as the task's Driver. Codex rejected two narrower fixes on local-bin#347: matching the pane name (reusable), then the session's creation time (not unique, and read in a separate call from the stamp, so it could change in between).
Decision.
- Each spawn creates a random value (128 bits, hex), sets it on the new tmux session as the user option
@spawn_noncebefore claude starts in it, and records it in task.json asspawnNoncein the same write that recordsdriverPane. Spawners: the Supervisor's mint and respawn (pendingDriver), its intake spawn, and local-binstart-driver. If setting the option fails, the boot fails; a nonce is only ever recorded when the session carries it. spawnNoncelives only while the sid is empty. Every write that fills in the Driver's sid removes it. In the Supervisor that rule sits in the one serializer every write goes through (toDisk).readTaskscarries it (OWNERSHIP_KEYS), so a pending-window write does not erase it.- The judge reads the nonce and the stamp in ONE tmux call (
display-message -p -t '=<driverPane>:' '#{@spawn_nonce} #{@claude_session_id}'; the=name:form, because a bare=nameprints empty and exits 0 for pane-type commands). Exit 5 on a nonce mismatch, a missing nonce or a tmux failure. A reused name or a recreated session carries a different nonce, so it can never be read as the recorded Driver.
Order. The Supervisor ships first, then local-bin. A task written before this has no spawnNonce; how slug-owner treats that is decided in its own PR.
Still inert, by construction. driver-here (dotclaude) also fills the sid on a takeover and does not remove the nonce. The judge reads the nonce only while the sid is empty, so a leftover is never consulted. A task whose sid is blanked without a spawn (a park) can keep a nonce, but that nonce only matches the one session it was set on.