# 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; `quit` retains 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 `quit` semantics 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.