INSTANCE-AXES grill — Round 2
Code facts read at main 456c8554. Answers save in this browser; "Copy answers" gives Markdown to paste back.
Recorded from Round 1
- Q1 wake landing: (a) attach→suspended = dormant · (b)
spt wake= active · (c) active sibling's normal msg = dormant · (d) other endpoint = active · (e) shell wake-watcher = active (you changed this one). - Q2 any message that is NOT
--busy-only-class steals active. spt-core builds no rule around adapter ideas (pacer, alchemy, recharge wake). - Q3 agent idle = the activity sentinel (
busy|idle). - Q4 boot: no time window; "no active sibling".
- Q5 the dormant send restriction covers peer
msgand its own shells;SEND_REFUSED_DORMANTnames the active sibling. - Q6 handoff: active-only sender; to a suspended sibling = it wakes active; to an offline sibling = refused and the sender stays active; carries a body; a flag on send.
- Q8 keep the knob chain; value
{mode, after_ms}; default{dormant-enable, 900000}(15 min); every existing value migrates to the new default. - Q9 three requests: A (axis split, counter, boot rule, auto-suspend modes) → #345 (resolver) → B (handoff + dormant restriction). Milestone INSTANCE-AXES.
Round 2
R2-1Shells are NOT routed to the active instance today. Should they be?
Your Q2 premise, checked against the code: a shell is bound to its node, not to the active instance.
- A shell's perch lives inside its owner's namespace on the shell's own node (
shellchan.rs:343). The shell side records the owner only as an endpoint id: no node, session or instance. - Sensory (
api emit) goes to the owner's perch on the same node or is dropped. It is never spooled and never crosses nodes (reporting.rs:603-614). - Text/file ride an ordinary
spt send <owner>, and a local perch always wins: it is delivered even to an offline perch, which spools. The cross-node leg runs only when there is no local perch (cli.rs:13071).
dean on nodes A and B, a shell running on A always talks to dean@A. Under your Q2 rule, every non-busy-only shell message would then pull active back to A, even while you are working on dean@B.Update: what CONTEXT.md says. It matches your memory, not the code.
One more line needs amending: §Instances says "A linked Shell counts as a driver". Under the split, a linked shell sits on neither axis: it never counts as control and never makes an instance active by itself.
- §Shell model: "An owner and its shell can link across nodes (the shell perch lives on the shell's node; commands ride Iroh)". Also: "a remote agent (on another node) drives it".
- Wake resolution looks for "any reachable instance of the owner endpoint on the subnet", including "owner active elsewhere → attach/online the shell".
- The 2026-07-24 (#70) rulings made shell refs resolve local-first, and made
persistentrestore node-qualified. - CONTEXT.md never names which owner instance receives shell→owner traffic. The code fills that gap with "the owner's perch on the shell's node", and sensory cannot leave the node at all.
One more line needs amending: §Instances says "A linked Shell counts as a driver". Under the split, a linked shell sits on neither axis: it never counts as control and never makes an instance active by itself.
Two coherent models:
- (a) Shells follow active. Shell → owner traffic resolves to the owner's active instance: over the subnet when that instance is remote, and spooled to it when it is suspended. That includes sensory, which is local-only today. Shell traffic then never steals active, because it already goes where active is. Q5 (a dormant instance can't message its own shells) fits: the shells belong to whichever instance is active.
- (b) Shells stay node-bound and non-busy-only shell traffic steals active to the shell's node. That is simple, but a chatty shell drags active around.
Recommended: (a). It is the model you described. It makes the Q5 answer consistent and removes the "chatty shell steals active" failure. Its cost is cross-node sensory, a real new leg: today sensory is never spooled and never crosses a node. It would also be a fourth request (C) or part of B.
R2-2One spt-core frame is NOT busy-only: the trust warning
Checked: away/return notices and every notif (update consent, rollback, escalation, knocks, pairing, scoped) are already sent deferred (busy-only class), so under your Q2 rule none of them steal active. The one exception is the trust warning (
wan.rs:1073-1087): a live delivery plus inject, not deferred. As the rule stands, it would steal active.Recommended: move the trust warning into the busy-only class, like every other notice. The rule then stays exactly "busy-only never steals, everything else does", with no sender exemptions.
R2-3Messages from the SAME endpoint id
Q2 says "from another endpoint". What about a message whose sender is the same endpoint id:
- (a) from a sibling instance: already covered by the handoff rules (normal msg = no transition;
--handoffswaps); - (b) from the same instance to itself (an adapter's self-send; spt-core sees only "sender = my own id").
Recommended: a same-id message never steals; only the handoff rules move active between siblings. This is an id-level rule with no adapter idea in it, and a self-send on a dormant instance then cannot quietly take active.
R2-4The user-input trigger (carried from Round 1)
There is no dedicated user-input event.
api state busy with a USER_INPUT payload already reaches the daemon (broker.rs:6398). api presence ("report user interaction") only writes a local file the daemon never reads.Recommended: the busy report carrying a
USER_INPUT payload is the "user input → active" trigger. It exists, the daemon already consumes it, and it is harness-neutral. api presence is retired, or documented as not a trigger.R2-5Auto-suspend: where and how is it configured? (your Q8 question)
Today:
- Node default:
auto_suspend_after_msin<spt_home>/daemon.json. - Per-endpoint override:
auto_suspend_after_msin the perch'sinfo.json. The endpoint wins, and 0 means off. It resolves atresting.rs:27-34. - No CLI surface. Hand-edit only.
- Undocumented in the public docs; only the manual
endpoint suspend/wakeverbs appear. - No shipped value is > 0. Only tests use one, which confirms your migration premise.
Recommended, folded into request A:
spt daemon config auto-suspend <disable|dormant-enable|enable> [--after 15m]sets the node default.spt endpoint auto-suspend <id> <mode> [--after …] | --inheritsets or clears the override.- A bare form prints the effective value and where it came from.
- A public docs section in instances/overview.
{dormant-enable, 15 min} turns auto-suspend ON fleet-wide at upgrade. Every uncontrolled, idle, dormant instance suspends after 15 min. A sole instance is never dormant, so it never auto-suspends under that mode. The release note should say this plainly.