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

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).
So with 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.
  • §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 persistent restore 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.
So model (a) is not a new design. It delivers what CONTEXT.md already promises, with the gap closed as "the owner's active instance".
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:

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:

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_ms in <spt_home>/daemon.json.
  • Per-endpoint override: auto_suspend_after_ms in the perch's info.json. The endpoint wins, and 0 means off. It resolves at resting.rs:27-34.
  • No CLI surface. Hand-edit only.
  • Undocumented in the public docs; only the manual endpoint suspend/wake verbs 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 …] | --inherit sets or clears the override.
  • A bare form prints the effective value and where it came from.
  • A public docs section in instances/overview.
Note on your new default: shipping {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.

+Anything else