T3 Code · Sidebar v2 experiment · implementation plan
+
Workspace tasks with agent tabs
+
+ Turn one sidebar “thread” into a durable task that owns a worktree, then let multiple
+ provider-backed conversation tabs branch from the task’s context while operating on the
+ same files.
+
+
+ Recommended: additive WorkspaceTask aggregate
+ Keep Thread as the provider conversation primitive
+ Web · Sidebar v2 only
+ Experimental shared-worktree concurrency
+
+
+
+
+
+
+
+
+
The recommendation
+
+ Do not rename the existing backend concept of a thread. It is already the identity
+ used by provider sessions, turns, messages, approvals, checkpoints, terminals,
+ routes, caches, and runtime events. Treat that existing object as an
+ agent tab, then add one product-level container above it.
+
+
+
+
+ New product primitive
+
WorkspaceTask
+
+ Owns the goal/title, project, environment, branch, worktree, sidebar lifecycle,
+ aggregate status, and the set of tabs.
+
+
+
+ Existing primitive, new presentation
+
Thread → agent tab
+
+ Continues to own provider instance, model, harness resume state, transcript,
+ turns, approvals, interaction mode, and permissions.
+
+
+
+
+
+
+ ⌘N / Ctrl+N
+
+ Creates a new task draft with its first agent tab. This feels exactly like “new
+ thread” today until the user adds another tab.
+
+
+
+ New tab
+
+ Desktop/Electron uses ⌘T. Browsers reserve that accelerator, so web
+ uses Mod+Alt+T plus a visible + button and “New tab in
+ task” command-palette action.
+
+
+
+ Context choice
+
+ The new-tab sheet defaults to “Fork through the latest completed turn,” with
+ “Start fresh in the same worktree” as the explicit alternative.
+
+
+
+ Provider choice
+
+ Every tab picks its own provider instance, model, model options, permission mode,
+ and interaction mode. The source tab’s selections are convenient defaults, not
+ task-wide constraints.
+
+
+
+ Route strategy
+
+ Keep /$environmentId/$threadId as the canonical active-tab route in
+ the first experiment. Resolve the task from the thread shell. This preserves
+ every existing deep link and avoids a route migration.
+
+
+
+ Rollout boundary
+
+ Render task rows and tab chrome only when
+ sidebarV2Enabled && taskTabsEnabled. Advertise server support
+ with a new workspaceTasks environment capability.
+
+
+
+
+
+ Why this seam is unusually valuable.
+ Provider adapters and orchestration can keep speaking in threads. The UI gains a
+ richer task abstraction without forcing a high-risk rename through hundreds of
+ thread-scoped call sites. A kill switch can always fall back to rendering each tab as
+ an ordinary thread, so the experiment is reversible without discarding data.
+
Replace its input view-model with task summaries; do not rewrite rows blind.
+
+
+
Draft promotion is first-turn driven
+
+ useHandleNewThread.ts, ChatView.tsx, and
+ apps/server/src/ws.ts create the thread/worktree during the first
+ turn bootstrap.
+
+
A task draft and a tab draft can reuse the same promotion pattern.
+
+
+
Provider state is thread-scoped
+
+ ProviderService, adapters, resume cursors, and runtime bindings
+ all key sessions by ThreadId.
+
+
The existing Thread is exactly the correct agent-tab primitive.
+
+
+
Codex supports exact forks
+
+ The generated app-server contract already includes thread/fork
+ with threadId and optional lastTurnId.
+
+
Same-continuation Codex tabs can get a real provider-native fork.
+
+
+
Worktree deletion detects sharing
+
+ worktreeCleanup.ts avoids deleting a path while another thread
+ references it.
+
+
Existing safety helps, but task-level deletion should become canonical.
+
+
+
Checkpoints assume one writer
+
+ CheckpointReactor.ts captures diffs per thread against a shared
+ filesystem state.
+
+
Parallel tabs require explicit overlap detection before revert can be safe.
+
+
+
+
+
+
+
+
What it looks and feels like
+
+ The sidebar remains the task inbox. Tabs live in the task workspace header because
+ they are alternate agents working on the same thing—not peer items that should crowd
+ the global task list.
+
Existing sidebar jump slots become task slots and open that task’s last-visited visible tab
+
Keep Mod+1…9
+
+
+
Close tab
+
Hide one conversation from the strip; block while it is running or awaiting input; never remove the worktree
+
Command palette initially; no browser-conflicting default required
+
+
+
Settle / snooze / archive / delete
+
Operate on the whole task. Individual tabs are closed/restored, not settled or snoozed.
+
Existing task-row actions
+
+
+
+
+
+
+ Browser accelerator reality. A web page cannot reliably own
+ Cmd+T or Ctrl+T; the browser opens a browser tab before the
+ React key handler can act. Electron can register the native accelerator. The visible
+ plus button and command palette are therefore first-class, not fallbacks.
+
+
+
+
+
Domain model and ownership
+
+ Internally call the new entity WorkspaceTask, not just
+ Task. The contracts already have RuntimeTaskId for provider
+ tool/sub-agent progress events, so the longer name prevents a subtle and permanent
+ terminology collision.
+
+
+
+
+
+ Provider events can continue to use ThreadId. The WorkspaceTask owns everything
+ that must be shared across tabs.
+
+
+
+
+
+
+
+
State
+
Owner
+
Why
+
+
+
+
+
Project, environment, branch, worktree path
+
WorkspaceTask
+
Every tab must resolve exactly the same effective cwd.
+
+
+
Task title, sidebar position, settle/snooze/archive state
+
WorkspaceTask
+
The sidebar row represents the whole unit of work.
Provider conversations remain isolated and independently interruptible.
+
+
+
Fork source, fork point, strategy, context bundle
+
Thread/tab
+
Provenance describes how this particular conversation began.
+
+
+
Composer draft
+
Thread/tab (client local until promotion)
+
Each agent can hold a distinct unsent prompt.
+
+
+
Terminals, preview, file panel presentation
+
Thread/tab for the experiment
+
They already key by ThreadId and still launch in the task’s effective cwd; task-scoping can be a later UX choice.
+
+
+
Git/source-control status
+
WorkspaceTask-derived
+
It reflects one shared worktree even when surfaced inside multiple tabs.
+
+
+
+
+
+
+ Compatibility denormalization. During the experiment, keep
+ branch, worktreePath, and a compatibility
+ title on each thread shell. The server derives them from the task and
+ enforces equality. New code reads the task as canonical; older clients continue to
+ function from thread fields. Remove the duplicate fields only in a later protocol
+ major version.
+
Context forking: exact when possible, honest when not
+
+ “Fork” cannot mean the same implementation for every harness. The product should
+ expose one consistent action while recording which fidelity it delivered.
+
+
+
+
+ Strategy A · highest fidelity
+
Native provider fork
+
+ Use when source and target share a provider driver and continuation identity, and
+ that adapter advertises native fork support.
+
+
+
Codex calls app-server thread/fork.
+
Pass the source provider thread id and provider-native last completed turn id.
+
Bind the returned provider thread id as the target tab’s resume cursor.
+
Never reuse the source resume cursor for two live T3 threads.
+
+
+
+ Strategy B · cross-provider
+
Portable context handoff
+
+ Use when moving between harnesses, accounts, provider homes, or adapters without a
+ native fork primitive.
+
+
+
Freeze a bounded, provider-neutral ContextBundle at the chosen turn.
+
Inject it once when the target tab starts its first provider session.
+
Show a “Portable handoff” provenance card in the timeline.
+
Do not silently label this as an exact clone.
+
+
+
+
+
+
+
+ One UX action, two persisted strategies. Failures remain visible and retryable; they
+ never silently change fidelity.
+
+
+
+
Portable ContextBundle contents
+
+
+
+
+
Include
+
Exclude or summarize
+
Constraint
+
+
+
+
+
Task title, project, branch, effective cwd, fork source and point
+
Absolute machine metadata that the target does not need
+
Structured envelope, versioned schema
+
+
+
User + assistant conversation through the fork point
+
Raw provider-native event payloads
+
Deterministic truncation from oldest low-value content first
+
+
+
Latest proposed plan and unresolved user decisions
+
Resolved approvals and transient permission prompts
The agent can inspect the shared worktree directly
+
+
+
Attachment names/types and durable references
+
Inline duplicate binaries unless the target explicitly supports them
+
Never smuggle local secrets or raw tool logs
+
+
+
+
+
+
+ Do not summarize with an LLM in the first slice. Begin with a
+ deterministic, bounded transcript/context envelope so the fork is predictable,
+ testable, and does not make an invisible model call. A separately labeled
+ “condensed handoff” optimization can come later if real usage proves the raw bundle
+ too expensive.
+
+ Multiple agents can safely read the same worktree. Multiple agents can also write it,
+ but T3 cannot truthfully attribute overlapping filesystem changes to one tab using
+ ordinary git diffs. The plan must make that limitation visible and prevent unsafe
+ reverts.
+
+
+
+
+ Failure mode
+
Cross-contaminated checkpoints
+
+ Tab A’s completion diff may include Tab B’s edits if their turns overlap in the
+ same checkout.
+
+
+
+ Failure mode
+
Destructive revert
+
+ Reverting A’s checkpoint could erase B’s legitimate work because the existing
+ checkpoint model assumes one writer.
+
+
+
+ UX risk
+
Invisible collisions
+
+ Two agents can edit the same file while both timelines look independently
+ healthy.
+
+
+
+
+
+ Recommended experiment policy
+
Allow parallel turns, but degrade attribution explicitly
+
+
+ Add a task-scoped workspace activity coordinator that records
+ active tab turns and a git/worktree fingerprint at every turn boundary.
+
+
+ When more than one writing-capable turn overlaps, mark all involved checkpoints
+ isolation: "overlapping".
+
+
+ Continue showing task-wide changed files and diff, but label them
+ shared-worktree changes, not “changes from this tab.”
+
+
+ Disable checkpoint revert for overlapping turns and explain why. Never expose an
+ action that may erase a sibling tab’s work.
+
+
+ Show a persistent header badge such as “2 agents active in shared worktree” and
+ surface which tabs are running.
+
+
+ Keep an optional task setting for single-writer mode if dogfood
+ usage shows parallel writes are too chaotic; it can queue or block a second turn.
+
+
+
+
+
+ Hard invariant for launch: no overlapping checkpoint may be reverted.
+ Perfect per-agent diff attribution would require isolated worktrees/overlays and a
+ merge layer, which contradicts the experiment’s defining idea that tabs operate on
+ the same live worktree.
+
+
+
Workspace fingerprint
+
+ Capture enough state to detect interference without trying to assign authorship:
+ HEAD, branch, staged/unstaged status entries, untracked-path set, and a
+ stable hash of the status snapshot. Store the fingerprint and sibling active-turn ids
+ with the checkpoint projection.
+
+
+
+
+
Task-level status and lifecycle
+
+ A task row needs one understandable status even when several tabs are doing different
+ things. Preserve Sidebar v2’s “inbox” philosophy and aggregate by urgency.
+
+
+
+
+
+
+
Priority
+
Task status
+
Aggregation rule
+
Row treatment
+
+
+
+
+
1
+
Approval
+
Any visible tab has a pending approval
+
“Approval · Codex” plus count when more than one
+
+
+
2
+
Input
+
Any visible tab awaits structured user input
+
“Input · Claude”
+
+
+
3
+
Failed
+
Any tab failed and no tab has a more urgent user request
+
“Failed · Review”
+
+
+
4
+
Working
+
One or more tabs are starting/running
+
“2 working · 3 tabs” and provider avatar stack
+
+
+
5
+
Done
+
At least one tab completed after its last local visit
+
Unread completion treatment
+
+
+
6
+
Ready
+
No higher-priority state
+
Quiet row using current v2 semantics
+
+
+
+
+
+
+
+ Task actions
+
Settle, snooze, archive, delete
+
+
Block settle while any tab is running or needs user input/approval.
+
Snoozing suppresses the whole task; activity in any tab wakes it.
+
Archiving stops all live provider sessions and task-linked terminals.
+
Deleting offers worktree cleanup once, after all tabs are handled.
+
+
+
+ Tab actions
+
Rename, close, restore
+
+
Rename changes only the tab label.
+
Close is blocked for running/pending tabs and preserves history.
+
The last visible tab cannot be closed; archive/delete the task instead.
+
Closed tabs remain available from a task menu for restoration.
+
+
+
+
+
+ Last-opened tab is client preference. Store
+ lastVisitedThreadIdByTask in the UI state store. Clicking a task opens
+ that visible tab when it still exists; otherwise choose the tab with the most recent
+ actionable activity, then the oldest root tab. Avoid persisting “active tab” on the
+ server, which would create noisy cross-device races.
+
+
+
+
+
Architecture changes
+
+ This is an additive vertical slice through contracts, event sourcing, provider
+ adapters, shared client state, and Sidebar v2. The provider runtime remains
+ thread-scoped end to end.
+
+
+
Contracts and shell protocol
+
+
+
+ Add WorkspaceTaskId and ContextBundleId in
+ packages/contracts/src/baseSchemas.ts.
+
+
+ Extend OrchestrationReadModel and shell snapshots with a
+ tasks array. Keep tasks and threads separate and join by
+ workspaceTaskId; avoid nesting copies of thread shells inside every
+ task.
+
+
+ Add shell events task-upserted and task-removed. Existing
+ thread shell events continue unchanged except for additive fields.
+
+
+ Add task commands/events for create, metadata, settle/unsettle, snooze/unsnooze,
+ archive/unarchive, and delete.
+
+
+ Add thread tab commands/events for label, close/restore, and fork metadata.
+
+
+ Advertise environment.capabilities.workspaceTasks and add provider
+ native-fork capability at the provider adapter/instance layer.
+
+
+
+
+
Persistence and event sourcing
+
+
+
+
+
Storage
+
Change
+
+
+
+
+
orchestration_events
+
Add aggregate kind workspace-task and task event types.
+
+
+
projection_workspace_tasks
+
New canonical task projection with project/workspace/lifecycle fields.
+
+
+
projection_threads
+
Add task id, tab label, closed timestamp, fork source/point/strategy, and context bundle reference.
+
+
+
projection_context_bundles
+
Immutable bounded JSON/blob payload for portable handoffs; events store the reference, not the potentially large body.
+
+
+
projection_turns
+
Persist provider-native turn id plus overlap/isolation metadata required by exact fork and safe revert.
+
+
+
checkpoint_diff_blobs
+
Add task id / workspace fingerprint linkage or companion metadata table.
+
+
+
+
+
+
First-turn bootstrap
+
+ Keep drafts local until the first message, including a newly added unsent tab.
+ Extend the existing thread.turn.start bootstrap rather than inventing a
+ second transport path.
+
+ Bootstrap cleanup must become task-aware. If worktree preparation,
+ tab fork setup, or the first provider turn fails, tombstone the newly created thread
+ and task and remove any worktree created by that bootstrap. Existing cleanup currently
+ centers on the thread; this slice must not leave an orphan task or checkout.
+
+
+
Client state and UI
+
+
+ Shared client runtime
+
+
Add environment-scoped task models and refs.
+
Teach shell reducer/cache to accept task events.
+
Build pure selectors that join task + tab shells and aggregate status.
+
Add task commands and capability reads.
+
Decode old cached snapshots with missing tasks.
+
+
+
+ Web · Sidebar v2
+
+
Feed SidebarV2 task summaries rather than raw threads.
+
Add TaskTabBar and NewTaskTabDialog above ChatView.
+
Extend the composer draft store with task id + captured fork spec.
+
Keep existing active thread routes and detail subscriptions.
+ Suggested new modules.
+ packages/client-runtime/src/state/tasks.ts,
+ apps/web/src/components/tasks/TaskTabBar.tsx,
+ apps/web/src/components/tasks/NewTaskTabDialog.tsx,
+ apps/web/src/tasks/taskPresentation.ts,
+ apps/server/src/orchestration/Layers/TaskLifecycleReactor.ts, and
+ apps/server/src/provider/ContextForkService.ts. Keep pure aggregation
+ logic out of the already-large Sidebar and ChatView components.
+
+
+
+
+
Migration and version skew
+
+ Every existing thread becomes a one-tab task. Use
+ workspaceTaskId = threadId for the backfill so identifiers are stable,
+ deterministic, and easy to reason about.
+
+
+
+ Migration 035 · proposed
+
+
Create projection_workspace_tasks and context-bundle storage.
+
Add task/tab/fork columns and indexes to thread and turn projections.
+
+ For every existing thread, set workspace_task_id = thread_id and copy
+ title/project/branch/worktree/lifecycle fields into a one-tab task.
+
+
+ Append deterministic, idempotent workspace-task.created migration
+ events plus lifecycle events needed to reproduce archive/settle/snooze/delete
+ state during a complete replay.
+
+
+ Use deterministic event ids and stream versions; migration tests must prove a
+ second run inserts nothing.
+
+
+ Backfill provider_turn_id from orchestration event metadata where it
+ exists. Legacy turns without it simply cannot be a precise historical native-fork
+ point and fall back to a portable handoff.
+
+
+
+
+
+
+
+
+
Client/server pairing
+
Behavior
+
+
+
+
+
New client + old server
+
+ Synthesize one task per thread client-side for Sidebar v2 presentation.
+ Hide/disable “New tab” and explain that the environment must be updated.
+
+
+
+
Old client + new server
+
+ Extra fields are ignored. Tabs render as separate legacy threads with
+ compatibility titles; thread commands remain valid and cannot delete a
+ worktree still referenced by sibling tabs.
+
+
+
+
New client + new server, flag off
+
+ Preserve current thread-per-row UI. This is the operational kill switch and
+ must reveal all created tabs rather than hiding data.
+
+
+
+
New client + new server, flag on
+
Full task rows, tab strip, fresh tabs, context forks, and task lifecycle.
+
+
+
+
+
+
+ Reversibility target. Disabling the experiment changes only
+ presentation and available creation actions. It does not need a down-migration:
+ every tab remains a valid thread, provider resume state remains keyed by ThreadId, and
+ the worktree remains referenced by all sibling thread shells.
+
+
+
+
+
Delivery plan
+
+ Ship behind a beta flag in reviewable vertical slices. Each phase has a useful exit
+ condition and keeps current thread behavior working.
+
+
+
+
+
+
+
Pure model and UX specification
+
+ Add pure task aggregation selectors, naming, status priority, last-tab fallback,
+ and fork-strategy decision logic with tests. Add the beta setting and keybinding
+ command ids, but keep the feature unavailable.
+
+
Exit: core semantics are testable without server or React component churn.
+
+
+
+
+
+
+
Contracts, projections, migration, and capability
+
+ Add WorkspaceTask schemas/events/commands, shell protocol fields, migration 035,
+ task repositories, projection pipeline support, client shell state, and
+ workspaceTasks capability. Backfill every thread as a one-tab task.
+
+
+ Exit: a new client can read real task shells and an old environment still decodes
+ as synthetic one-tab tasks.
+
+
+
+
+
+
+
+
Sidebar v2 grouping and task lifecycle
+
+ Switch Sidebar v2 to task summaries. Move rename, settle, snooze, archive,
+ delete, selection, jump hints, status, and worktree cleanup to task actions.
+ Keep the flag off by default.
+
+
+ Exit: existing users see one task row per migrated thread with no visual or
+ lifecycle regression when each task has one tab.
+
+
+
+
+
+
+
+
Tab chrome and fresh tabs
+
+ Add TaskTabBar, NewTaskTabDialog, draft-tab state, task-aware promotion, route
+ fallback, tab labels, close/restore, command palette entries, and desktop/web
+ shortcut split. First ship “Start fresh” in the same worktree.
+
+
+ Exit: a task can run two independent providers against one worktree without
+ context inheritance.
+
+
+
+
+
+
+
+
Portable cross-provider context handoff
+
+ Add immutable ContextBundle storage/building, captured fork points, one-time
+ target-session injection, provenance cards, size limits, and deterministic
+ truncation. This unlocks different harnesses first.
+
+
+ Exit: Codex → Claude (and any other provider pair) starts with a visible,
+ reproducible portable context bundle.
+
+
+
+
+
+
+
+
Exact Codex native fork
+
+ Extend ProviderAdapter capabilities and fork method, persist provider turn ids,
+ wire CodexSessionRuntime to thread/fork, enforce continuation-key
+ compatibility, bind the new resume cursor, and add exact-fork retry/fallback UI.
+
+
+ Exit: Codex → compatible Codex creates a genuine provider-native branch through
+ the selected completed turn.
+
+
+
+
+
+
+
+
Shared-worktree safety and dogfood rollout
+
+ Add workspace activity coordination, overlap metadata, unsafe-revert blocking,
+ shared-worktree status UI, metrics, and the hidden Beta toggle. Dogfood with
+ focused scenarios before enabling the experiment for broader v2 users.
+
+
+ Exit: parallel tabs are observable, overlapping changes cannot be destructively
+ reverted, and the feature can be disabled without losing access to any thread.
+
+
+
+
+
+
+ Why fresh tabs precede forks. They prove the task/worktree/tab model,
+ provider isolation, lifecycle, draft promotion, and route behavior without mixing in
+ context-fidelity bugs. Portable handoff then unlocks the headline cross-harness use
+ case; native Codex fork becomes an optimization with stronger fidelity.
+
+
+
+
+
Verification strategy
+
+ Backend behavior requires focused tests in every changed layer. The final web slices
+ require one integrated Sidebar v2 pass in an isolated T3 environment, as required by
+ the repository workflow.
+
+
+
+
+ Contracts + migration
+
+
Decode old snapshots/events.
+
Backfill one task per thread.
+
Preserve lifecycle state.
+
Prove migration idempotence.
+
Replay reconstructs the same projections.
+
+
+
+ Orchestration
+
+
Task/thread membership invariants.
+
All tabs resolve the task cwd.
+
Task settle/snooze guards.
+
Activity wakes the whole task.
+
Cascade stop/archive/delete behavior.
+
+
+
+ Provider layer
+
+
Native eligibility matrix.
+
Codex request parameters.
+
New cursor bound to target only.
+
Portable injection happens once.
+
Failure is retryable and visible.
+
+
+
+ Client + React
+
+
Status priority and counts across mixed tab states.
+
Task sorting stays stable under tab activity.
+
Task click chooses last visited/fallback tab.
+
Draft tab captures a fixed fork point and promotes once.
+
Keyboard commands respect terminal/preview focus and browser differences.
+
Flag-off mode exposes every underlying thread.
+
+
+
+ Checkpoint safety
+
+
One active tab keeps current checkpoint/revert behavior.
+
Two overlapping turns mark both checkpoints overlapping.
+
Overlapping revert is rejected server-side, not only hidden in UI.
+
Task-wide diff remains viewable and clearly labeled.
+
Deleting one tab never offers shared worktree deletion.
+
+
+
+
+
Integrated dogfood script
+
+
+
Enable Sidebar v2 + Task Tabs in an isolated environment.
+
Create a new task with Mod+N in a dedicated worktree.
+
Send a planning turn in the root Codex tab and wait for completion.
+
Create a fresh Claude tab; confirm same branch/cwd and independent transcript.
+
Create a portable fork from Codex to Claude; inspect the provenance card and handoff contents.
+
Create an exact Codex fork; confirm the native branch begins at the captured completed turn.
+
Run two tabs concurrently; confirm the task row shows both and overlapping revert is disabled/rejected.
+
Complete one background tab; confirm task “Done” and last-visited routing.
+
Settle, un-settle, snooze, wake, archive, and restore the whole task.
+
Disable the beta flag; confirm all tab threads remain reachable in legacy thread-per-row presentation.
+
Delete the task; confirm one worktree-removal prompt and no provider/terminal residue.
+
+
+
+
+ Run focused vp test run <affected-test-files>, targeted package
+ typechecks/formatting, and the test-t3-app integrated web pass. Do not
+ substitute the repo-wide suite for focused local verification.
+
+
+
+
+
Risks and decisions to lock before implementation
+
+
+
+
+
Question
+
Recommendation
+
Reason
+
+
+
+
+
Are task tabs allowed to write concurrently?
+
Yes for the experiment, with overlap labeling and server-enforced revert blocking.
+
This tests the bold idea without pretending attribution is safe.
+
+
+
Should “fork” always imply exact history?
+
No. Persist and display native vs portable.
+
Cross-provider exact cloning is not generally available.
+
+
+
Should a new tab immediately persist?
+
No. Keep it as a local draft until first send, matching current thread drafts.
+
Closing an unused tab leaves no server/provider debris.
+
+
+
Should routes be task-shaped now?
+
No. Preserve active thread routes for the first version.
+
Deep-link stability and smaller blast radius outweigh URL purity.
+
+
+
Should terminals/previews be shared across tabs?
+
Not initially. Keep presentation tab-local while resolving all launches to task cwd.
+
Avoids forcing a ChatView/right-panel/terminal state migration into the core experiment.
+
+
+
Should mobile or Sidebar v1 group tasks?
+
No for this experiment. They retain thread-per-row compatibility presentation.
+
The user-visible scope is explicitly Sidebar v2.
+
+
+
Can the task title and tab title be the same field?
+
No. Add a tab label; denormalize task title into legacy thread title only for compatibility.
+
Multi-tab tasks need a stable goal and distinguishable agent labels.
+
+
+
+
+
+
+
+ Do not do
+
+
Do not mass-rename ThreadId or provider runtime events to TabId.
+
Do not share one provider resume cursor across concurrent T3 threads.
+
Do not call portable handoff an exact fork.
+
Do not allow task tabs to diverge onto different worktrees.
+
Do not expose checkpoint revert after overlapping writes.
+
Do not hide task data when the beta flag is disabled.
+
+
+
+ Preserve
+
+
Current Mod+N new-work behavior and draft-first feel.
+
Per-provider sessions, approvals, and interrupt controls.
+
Existing thread deep links and subscriptions.
+
Sidebar v2 stable creation-order sorting and inbox lifecycle.
+
Worktree sharing checks for legacy clients.
+
Capability-based behavior under client/server version skew.
+
+
+
+
+
Telemetry for the experiment
+
+ Record counts and timings only: task creation, tab count distribution, fork strategy,
+ source/target driver kinds, fork failures, time to first target turn, overlapping-turn
+ frequency, and flag disablement. Never include prompt text, context bundles, paths, or
+ transcript content in analytics.
+
+
+
+
+
Definition of done
+
+
Sidebar v2 shows one row per WorkspaceTask.
+
Existing threads migrate to one-tab tasks without title or lifecycle loss.
+
Mod+N creates a task draft and first tab with current defaults.
+
Desktop Cmd+T and web-safe action open the new-tab sheet.
+
Fresh tabs use the exact same project, branch, and effective cwd.
+
Each tab independently selects provider, model, and runtime mode.
+
Portable forks capture a fixed, bounded, visible ContextBundle.
+
Compatible Codex forks use app-server thread/fork.
+
Running source turns fork only through the latest completed turn.
+
Task status aggregates all visible tab states deterministically.
+
Task lifecycle actions guard and affect every tab.
+
Parallel tab activity is visible at task and tab level.
+
Overlapping checkpoints cannot be reverted in client or server.
+
Disabling the flag exposes all tabs as ordinary threads.
+
Old-server capability fallback is clear and non-failing.
+
Focused backend, contract, client, and integrated web verification passes.
+
+
+
+ The experiment succeeds if one task can hold multiple independently
+ useful agent conversations—especially across harnesses—while the user continues to
+ reason about exactly one checkout, one goal, and one sidebar item. The plan
+ deliberately makes provider-fork fidelity and shared-filesystem hazards visible
+ instead of smoothing over them.
+