Before submitting
Area
apps/web, thread creation, worktree isolation, checkpoint diffs
Summary
The New threads setting explicitly asks users to choose the default workspace mode for newly created draft threads. Its available options are currently:
When New worktree is selected, not every New Thread entry point honors that setting. Several contextual entry points silently copy the active thread's existing branch, worktreePath, and environment mode into the new draft.
This is not merely a feature request or a proposed behavior change. It is a bug: the UI explicitly says New worktree, but some New Thread actions create a second thread in the current worktree instead.
Steps to reproduce
- Open Settings → New threads.
- Select New worktree as the default workspace mode.
- Start a worktree-backed thread and leave it running.
- Create another thread using a contextual/global New Thread entry point, such as the keyboard shortcut, command palette action in the active project, or the Sidebar V2 New Thread button in a single-project setup.
- Send the first message in the new thread.
- Inspect the two thread records or provider working directories.
Expected behavior
Every ordinary New Thread entry point should honor the configured New worktree default and create a fresh isolated worktree.
The new draft should not inherit an existing worktreePath, and the first-turn bootstrap should execute prepareWorktree.
Actual behavior
Depending on the New Thread entry point, the new draft inherits the active thread's existing worktreePath.
Once that path is present, the first-turn bootstrap assumes the worktree already exists and does not invoke the Git worktree creator. Both agents can then run concurrently in the exact same directory.
The behavior is inconsistent across entry points:
- some project-specific creation paths honor New worktree and create an isolated worktree;
- the global New Thread command/shortcut can reuse the active worktree;
- the command palette can reuse the active worktree when creating a thread in the current project;
- the Sidebar V2 New Thread action can reuse the active worktree in a single-project setup.
All of these are presented as New thread, so the user is not informed that one of them may create another writer in an existing workspace.
Concrete failure mode
In one observed case:
- A migration thread was running in a T3-managed worktree.
- A second, read-only investigation thread was created from the active context while New worktree was the configured default.
- Both thread records contained the exact same
worktreePath from their initial thread.created events.
- The migration thread ran
git merge origin/main while the investigation turn was active.
- The investigation thread's checkpoint UI attributed the resulting 112-file diff (
+10,163 / -802) to the read-only assistant response.
The investigation agent itself had only executed read commands (rg, sed, git log, and git status).
This happens because turn checkpoints capture the entire worktree state, not writes attributable to one agent process. Shared worktrees therefore also make checkpoint restore/revert potentially destructive to another active thread's work.
Current implementation behavior
On current main (1c9a6de26e when verified):
apps/web/src/lib/chatThreadActions.ts builds contextual thread options by copying the active thread's worktreePath.
apps/web/src/hooks/useHandleNewThread.ts gives explicitly passed contextual options precedence over defaultThreadEnvMode.
apps/web/src/components/ChatView.tsx only creates bootstrap.prepareWorktree when the draft has no existing worktreePath.
The Git worktree creator is not failing or selecting a duplicate path. It is never invoked because the new thread has already inherited an existing path.
Proposed fix
All ordinary New Thread entry points must consistently apply the configured default workspace mode.
When the setting is New worktree:
- do not propagate the active thread's
worktreePath;
- create a fresh T3-managed worktree on first send;
- make this consistent across global buttons, project buttons, shortcuts, command palette, Sidebar V1, and Sidebar V2.
Reusing an existing worktree should be an explicit user decision. It could be exposed through actions such as:
- Command Palette: New thread in current worktree;
- right-click an existing thread: New thread in this worktree.
If T3 wants worktree reuse to be configurable as the normal default, Settings could add a third clearly named option alongside the existing choices:
- Local
- New worktree
- Current/existing worktree
That would preserve the useful ability to share a workspace while making it explicit and keeping New worktree semantically correct.
If another thread is currently writing in the selected existing worktree, T3 should ideally warn the user or prevent concurrent writers.
Why this matters
Worktrees are the isolation boundary that makes parallel agent execution safe. Silently sharing them can cause:
- one thread's changes to appear under another thread's response;
- misleading changed-file counts and turn diffs;
- mixed or conflicting edits;
- branch movement caused by another agent during a turn;
- unsafe checkpoint reverts that overwrite or clean another thread's work.
The risk is especially high because the current Settings UI explicitly promises New worktree, while the affected creation paths silently do something else.
Acceptance criteria
Related issues
Workaround
Create new threads only through an entry point known to honor the New worktree setting, then verify that the draft says New worktree rather than Worktree before sending the first message.
Before submitting
Area
apps/web, thread creation, worktree isolation, checkpoint diffsSummary
The New threads setting explicitly asks users to choose the default workspace mode for newly created draft threads. Its available options are currently:
When New worktree is selected, not every New Thread entry point honors that setting. Several contextual entry points silently copy the active thread's existing
branch,worktreePath, and environment mode into the new draft.This is not merely a feature request or a proposed behavior change. It is a bug: the UI explicitly says New worktree, but some New Thread actions create a second thread in the current worktree instead.
Steps to reproduce
Expected behavior
Every ordinary New Thread entry point should honor the configured New worktree default and create a fresh isolated worktree.
The new draft should not inherit an existing
worktreePath, and the first-turn bootstrap should executeprepareWorktree.Actual behavior
Depending on the New Thread entry point, the new draft inherits the active thread's existing
worktreePath.Once that path is present, the first-turn bootstrap assumes the worktree already exists and does not invoke the Git worktree creator. Both agents can then run concurrently in the exact same directory.
The behavior is inconsistent across entry points:
All of these are presented as New thread, so the user is not informed that one of them may create another writer in an existing workspace.
Concrete failure mode
In one observed case:
worktreePathfrom their initialthread.createdevents.git merge origin/mainwhile the investigation turn was active.+10,163 / -802) to the read-only assistant response.The investigation agent itself had only executed read commands (
rg,sed,git log, andgit status).This happens because turn checkpoints capture the entire worktree state, not writes attributable to one agent process. Shared worktrees therefore also make checkpoint restore/revert potentially destructive to another active thread's work.
Current implementation behavior
On current
main(1c9a6de26ewhen verified):apps/web/src/lib/chatThreadActions.tsbuilds contextual thread options by copying the active thread'sworktreePath.apps/web/src/hooks/useHandleNewThread.tsgives explicitly passed contextual options precedence overdefaultThreadEnvMode.apps/web/src/components/ChatView.tsxonly createsbootstrap.prepareWorktreewhen the draft has no existingworktreePath.The Git worktree creator is not failing or selecting a duplicate path. It is never invoked because the new thread has already inherited an existing path.
Proposed fix
All ordinary New Thread entry points must consistently apply the configured default workspace mode.
When the setting is New worktree:
worktreePath;Reusing an existing worktree should be an explicit user decision. It could be exposed through actions such as:
If T3 wants worktree reuse to be configurable as the normal default, Settings could add a third clearly named option alongside the existing choices:
That would preserve the useful ability to share a workspace while making it explicit and keeping New worktree semantically correct.
If another thread is currently writing in the selected existing worktree, T3 should ideally warn the user or prevent concurrent writers.
Why this matters
Worktrees are the isolation boundary that makes parallel agent execution safe. Silently sharing them can cause:
The risk is especially high because the current Settings UI explicitly promises New worktree, while the affected creation paths silently do something else.
Acceptance criteria
defaultThreadEnvMode.worktreePath.Related issues
defaultThreadEnvMode: "worktree"can still result in subsequent threads reusing an existing worktree.Workaround
Create new threads only through an entry point known to honor the New worktree setting, then verify that the draft says New worktree rather than Worktree before sending the first message.