Date: 2026-07-22
Status: Phase 6F.2 accepted; Phase 6G paused, redesign contract unapproved
Accepted historical workflow: this document remains the implemented Phase 6 behavior. The Thread and Workstream Redesign Decision accepts a future clean-break direction that preserves completed result tips and adopts provider-native fresh-thread transitions. Its production contract is unapproved, and Phase 6G implementation remains paused. The replacement workflow is sequenced in the redesign roadmap. This technically accepted workflow was never adopted as a viable product and creates no backwards-compatibility obligation.
This record defines user-visible behavior for durable Switchboard views, workspace/task frames, and strategic agent control turns. It replaces the task-first foreground-stack proposal. Product boundaries are in the design; normative states/invariants are in the state contract.
The user owns a durable terminal view. Switchboard owns navigation around the native provider pane, not the conversation inside it.
UserView (one host, one cursor)
navigator mode: [Switchboard sidebar] [active native provider pane]
direct mode: [active native provider pane]
Project
workspace frame
task frame
nested task frame later Phase 6 slice
Frame lineage answers “where did this work come from?” View selection answers “what is this terminal showing?” Project entry answers “take me back to my current work in this project.” These are separate facts.
- A new CLI/SSH view starts in navigator mode.
- Direct mode is an explicit minimal/no-TUI choice.
- A future optional desktop adapter may also request navigator mode.
- Reopening a view preserves its mode.
Viewsfocuses as-is;Projectsexplicitly navigates.- Automatic task push is conservative and project-configurable.
- Complete-and-return triggers one parent synthesis turn by default.
- Back, focus, mode change, and Human close are model-free.
- Control turns prefer a safely live pane and otherwise exact UUID resume.
- Explicit user instructions override the automatic task-boundary heuristic.
- The first shipped workflow allows workspace to one child; recursive push is disabled until its later work-context slice.
CLI/TUI opens project
-> core focuses/creates its host-local view
-> view presents the project's current open frame or workspace
-> user starts the empty workspace once; later entry reuses its exact session
-> user asks for a substantial outcome
-> workspace agent prepares a child frame and bounded brief
-> trusted post-turn hook parks/fences the workspace
-> core transfers WorkContext foreground authority to the child
-> child starts from the fixed claim control turn
-> child claims the brief and works in its native TUI
-> child stores one exact handoff and requests Complete-and-return
-> trusted hook presents the exact workspace parent
-> parent receives one fixed control turn and claims the handoff
-> child closes immediately after that exact claim
-> parent synthesizes the result and continues naturally
There is no task form, duplicate provider picker, ceremonial continue, raw
prompt replay, hidden semantic injection, or manual tmux lookup.
Project/view entry is navigation-only. If the workspace has no provider
session, the navigator exposes n and the public equivalent is:
swbctl frame start --host HOST --frame FRAME --request-id UUIDProvider selection follows the frame/project configuration; the start command
does not add a second provider picker. Before provider execution, core commits
the first FrameSession, planned launch/surface, staged placement, and held
WorkContext with the workspace as foreground in one transaction. A failure
before execution removes that exact bundle and staged pane. Once provider
execution is attempted, ambiguity opens recovery and is never silently retried.
Success binds the exact provider UUID and capability, activates and presents the
surface, and leaves the workspace immediately eligible for conservative task
push.
View activation focuses/attaches exactly that durable view. It never changes the active frame or navigator/direct mode.
Project activation is explicit navigation:
- Core resolves the project's workspace placement and owning view.
- If that view already shows the project, retain its active frame.
- Otherwise target the most recently focused open descendant owned by that view, falling back to the workspace frame.
- Commit the target with a live view-revision CAS, then focus/attach the view.
- If the workspace has no placement, single-flight creation of one navigator-mode CLI view unless direct mode was explicitly requested.
- Missing defaults, checkout conflicts, or stale ownership become bounded blocked/recovery results.
Different request IDs opening the same unowned project converge on the one workspace reservation. Clicking a project never focuses a view still displaying an unrelated project.
The one-command terminal route is view enter. From a plain shell it execs the
exact local tmux attach or configured SSH attach. From a managed view it stays
in place for the same view, switches only the exact invoking client for another
local view, or preflights the remote owner before replacing that client with
SSH. Multiple/no exact client matches block. Four nested cross-host replacements
are allowed; the fifth tells the user to detach the outer connection and enter
the desired host directly.
Focus is navigation, not lifecycle:
- it creates no lineage or handoff;
- it does not close either frame;
- it keeps the source runtime live by default;
- it moves only the selected view's active slot; and
- it transfers foreground authority only when source/target share a WorkContext.
If the target live pane belongs to another view, Switchboard focuses that owner. It never steals the pane.
A source moved into holding has client input disabled. If source/target share a WorkContext, known/uncertain background mutation requires explicit confirmation before lease transfer. The warning states that Switchboard cannot prevent an already-running process from writing. Automatic transitions never offer this override.
The current provider agent detects semantic task boundaries. Core validates an explicit tool request but never interprets conversation text.
Implicit push is appropriate only for an independently meaningful outcome likely to need multiple interactive turns. Incidental questions, ordinary implementation steps, bounded diagnostics, provider subagents, and background commands remain in the frame. Uncertainty means stay.
The current agent calls:
task_push(title, brief, purpose?, provider?, park_safe=true)
It supplies no source frame/session/view/surface/checkout/launch identity. Core derives authority from the exact current capability.
Preparation during the source turn:
- validate frame/view/project/depth/checkout and park-safe claim;
- commit child frame, transition, planned surface, launch intent, bounded brief,
and one
claim_briefControlTurn; - optionally precreate/name a zero-turn provider session through a version-gated adapter; and
- create/reconcile the staged physical pane as a separate saga, leaving its provider bootstrap inert in the unattached holding session.
After the source Stop:
- the trusted hook claims the transition and revalidates view revision, WorkContext generation, source pane, staged target, and server generation;
- source input is disabled and its pane moves to holding;
- core proves park safety and atomically transfers foreground ownership to the child;
- the child is moved into
view.mainand selected; - the bootstrap gate proves exact authorized main placement and starts the native provider with the fixed visible control prompt;
- provider binding must match a preallocated UUID when one exists; and
transition_claim()returns the brief only after the child UUID, pane, placement, transition, and foreground WorkContext all agree.
If foreground transfer fails, the child never receives its brief. Reconciliation restores the source or leaves both panes input-fenced with one recovery record.
Back means “show my semantic parent without completing this child.” It:
- targets exactly
parent_frame_id; - creates no handoff or control turn;
- leaves the child open;
- keeps its runtime live and input-disabled in holding by default; and
- applies the shared-checkout background confirmation before lease transfer.
If the parent runtime stopped, core resumes its exact provider UUID without an initial semantic prompt and presents it at the normal idle prompt. Back never starts a parent model turn.
The child calls:
task_complete_return(summary, next_action, park_safe=true)
Core stores one immutable handoff tied to the exact child session, marks the
child closing, and prepares the exact parent plus one claim_handoff
ControlTurn.
After the child Stop:
- claim/revalidate transition, parent, child, view, WorkContext, and panes;
- input-fence the child and present the exact parent, swapping the child into
holding so
view.mainalways retains a pane; - transfer WorkContext foreground ownership to the parent;
- submit the fixed control prompt to the live verified-idle parent, or resume its exact UUID with that initial prompt;
- return from the trusted hook without waiting for the model;
- the parent calls
transition_claim()and receives the exact handoff; - that claim closes the child as
completedand stops its exact parked runtime; - the parent synthesizes the user-visible result; and
- the parent's exact post-claim
Stopsettles the transition.
If the parent model fails after claim, the child remains closed because its durable handoff was delivered. Claim is idempotent, so a recovery control turn may return the same handoff without another child or handoff.
If parent presentation/submission fails before claim, the child stays
closing and recoverable. Uncertain submission is never automatically repeated.
Projects may override complete_return to handoff. That mode presents the
parent without a control turn, surfaces a pending handoff in the navigator, and
lets the next normal parent turn claim it.
The only terminal-submitted text is the literal control.claim.v1 template:
Call transition_claim() and follow the returned transition instructions.
A live target is eligible only when:
- it is the exact managed target session/pane/placement;
- it is parked in the view's holding session with input disabled;
- a trusted
Stopproves foreground turn completion; - no permission question or known/uncertain background mutation exists;
- the executing transition and WorkContext generations still match; and
- no submission has been attempted for this ControlTurn.
One tmux command queue swaps/selects the target, creates a uniquely named
ephemeral buffer, enables input, bracket-pastes the literal template, deletes
the buffer, sends Enter, and disables input. An exact UserPromptSubmit
observation or bounded watchdog re-enables it. The buffer is never shared,
retained, or reused.
A timeout after submission becomes uncertain: re-enable user input, retain the
handoff/brief, surface recovery, and do not inject again. A later exact claim
and hook may settle the same turn; successful settlement resolves that exact
timeout recovery.
Human close is organizational and model-free:
- validate or prepare the exact parent/placeholder target;
- present the parent first and move the child into holding;
- transfer WorkContext foreground authority when applicable;
- stop only the exact parked child runtime after ownership revalidation; and
- mark the frame
closed/dismissedwithout a handoff or parent model turn.
If the parent cannot be presented, the child remains active/open. If cleanup is uncertain only after safe presentation, the frame closes with a structural warning and the runtime becomes a recovery target. Workspace roots are not closed through this task action.
Cancel is valid only while a push is prepared and before child binding/input.
It deletes only transition-owned planned/zero-turn resources after exact proof.
After execution begins, the user chooses Back, Complete, Human close, or
recovery; provider history is never silently deleted.
Manual focus/mode changes may supersede only prepared. An executing or later
transition owns the view mutation lease and must settle/fail/recover. A late
hook for a superseded transition may record failure but cannot retarget the view.
Navigator mode owns one compact sidebar pane with breadcrumb, projects/open frames, attention, transition/control state, recovery, search/focus, Back, close, mode toggle, and focused management entry.
Direct mode removes sidebar pane/process through an external short-lived
executor. The provider fills main. A dead remain-on-exit placeholder keeps
main durable when no provider exists. Toggling navigator recreates the sidebar
without changing provider pane/process.
Mode changes are allowed only without an executing-or-later transition. Zoom is preserved/restored as display state and never changes durable mode.
- One view may have multiple Switchboard-managed clients sharing the cursor.
- Managed attach rejects/degrades tmux
active-pane; it never claims a shared cursor when clients have independent selection. - Different client sizes follow an explicit tmux window-size policy; read-only clients do not become the mutation executor.
- One host may have multiple independent views.
- One live/stopped frame affinity has one owning view.
- Opening a live frame elsewhere focuses its owner.
- A view never navigates to a remote frame; remote selection opens a separate SSH-backed host-local view.
An SSH client uses the primary terminal-native path. swbctl view enter
resolves a project, exact view/frame, or recovery and preserves the selected
navigator/direct mode. swbctl view list discovers durable local views and
swbctl view attach --view VIEW remains the lower-level exact attach command.
Neither navigation command starts or resumes a provider. Explicit frame start
and frame reopen report success only after the exact surface has moved from
holding into view.main.
A future dumb desktop adapter may list Views, Projects, then structural Recovery. It never lists normal tasks or provider sessions and does not participate in the TUI-first adoption gate.
- View selection preserves active frame/mode.
- Project selection performs the explicit project route.
- One canonical desktop-adapter client exists per view; other tmux clients do not share its compositor identity.
- Concurrent launch fallback uses one expiring desktop lease.
- Multiple matching canonical windows block instead of launching another.
safe_autorecovery may execute directly;open_viewopens core recovery;manualonly explains the next step.
Needs-input, working, ready, stopped, stale, and offline remain view badges.
- Preparation failure: source/view unchanged and no duplicate child.
- Hook absent: durable prepared state; no view movement.
- Child bind timeout: reclaim exact staged resources; source remains usable.
- Child bound before presentation failure: retain one recovery target.
- Foreground transfer failure: do not release brief.
- Control submit uncertain: re-enable input, retain semantic payload, never auto-resubmit.
- Parent unavailable before claim: keep child closing/usable and handoff durable.
- Parent failure after claim: child closed; retry synthesis from same handoff.
- Sidebar crash: provider survives; restart only in navigator mode.
- Locator crash: reconcile intent against server generation/pane metadata.
- tmux server loss: invalidate locators and resume exact UUIDs into a new shell.
- Offline/cutover-staged host: retain state but reject mutation.
Retained evidence establishes feasibility, not production acceptance:
- tmux
3.7bpreserves pane/process identity and supports input-off fencing; - a compound
enable -> literal send -> disablequeue delivers the fixed text while client input stays fenced before and afterward; - Codex
0.144.6accepts an initial prompt on exactforkandresume; - Claude Code
2.1.216accepts a prompt with--resumeand optional--fork-session; and - bounded Codex stdio App Server clients can precreate/name/delete an empty thread without a shared daemon.
The retained topology/control proof is
spikes/tmux_sidebar_swap_spike.py.
Phase 6D implementation and guarded installed-provider evidence are recorded in
Phase 6D Acceptance.
- TUI Project entry navigates to that project; View entry focuses as-is.
- CLI Project entry uses the same route with navigator-mode creation default.
- Reopening preserves view mode and active frame.
- Push releases exactly one child brief only after foreground transfer.
- Retried push creates no duplicate frame, UUID, launch, pane, or handoff.
- Back leaves child open and starts no parent turn.
- Complete submits one parent control turn and closes child on exact claim.
- Uncertain submission never produces an automatic duplicate turn.
- Human close presents parent first and starts no model turn.
- Normal view window navigation cannot expose/activate holding panes.
- Shared managed clients share cursor;
active-paneis rejected/degraded. - Direct/navigator toggles preserve provider pane/process, including zoom.
- Shared-checkout ambiguity blocks automation and requires core confirmation.
- Remote selection opens a separate SSH-backed view.
- No normal path invokes Snapshot/Fleet/task-first/DMS compatibility.
Views,Projects, and openTaskscan switch among existing sibling frames; closed frames remain read-onlyHistory.- Recursive task creation and task-to-child-task return are not implied by sibling navigation; they remain Phase 6G.