3.4 KiB
G-010 Subshell suspend/resume and tree navigation
Status: proposed
Scope: src/modules/punk/repl-999999.0a1.0.tm, src/modules/punk/repl/codethread-999999.0a1.0.tm
Acceptance: from a grandchild subshell a single switch command reaches the grandparent without unwinding through the intermediate parent; switching between subshells on different branches preserves each subshell's session state and re-applies its console state set on activation; suspended subshells can be listed and resumed; quit still unwinds to the launching parent as today; a subshell whose switch commands are hidden/restricted cannot initiate switches.
Context
The current subshell model supports only launch and quit, in strict LIFO order, implemented as synchronous nested interp evals - a grandchild cannot reach its grandparent without unwinding through the parent, and nothing can be suspended. The desired model: subshells form a tree (launch structure), any live subshell can be suspended rather than quit, and the console can be switched to any live subshell - grandchild to grandparent, or across branches - not only along parent/child edges. Which switches are available is governed by the commands exposed in the current subshell, so restricted subshells (G-003/G-009 profiles) cannot use switching as an escape hatch.
Approach
- Subshell registry as a tree: launch records parentage; suspend detaches a subshell from the console without tearing down its interp/session state; resume/switch re-attaches.
- Switching = console attachment handoff + state activation: transferring which subshell drives the console is an ownership/attachment change (the G-007 registry is the natural record), followed by activating the target's G-008 console-state set. Session state (variables, history, running state) stays with each subshell's interp/thread.
- Navigation as commands: list/switch/suspend/resume are ordinary exposed commands, so
G-003's hide/expose mechanism governs who may navigate;
quitretains its current meaning (terminate and return to the launching parent). - Requires G-002's non-nested execution model: with synchronous nested evals, every ancestor is blocked inside the descendant's eval and cross-branch attachment is impossible.
Alternatives considered
- Flat MRU list instead of a tree - rejected as the model (parentage determines
quitsemantics and inheritance of profiles/state baselines), though flat listing is fine as a view for switching. - Delegating switching to a terminal multiplexer (tmux-style panes/windows per subshell) - rejected as the mechanism: punk sessions must work without a multiplexer and across platforms; nothing prevents complementary use of one.
- Allowing switch from any subshell unconditionally - rejected: switching is a capability; restricted subshells must not reach less-restricted contexts (alignment with G-003/G-009).
Notes
- Dependency chain: G-002 (non-nested subshells, first-subshell asymmetry) is prerequisite; G-008 supplies the console-state swap on activation; G-007's ownership registry is where attachment handoff is recorded. G-009 profiles make switch targets visually identifiable.
- Suspend/resume semantics for in-flight commands in a suspended subshell (block? continue headless with output buffered?) is an implementation-time decision to be recorded here when made; the acceptance only requires suspended subshells to be listable and resumable.