Scenario
A user works in a project whose folder is not a git checkout (a folder of documents), on a local machine. They open a child thread of the focused thread — a second opinion from another model, or bb thread spawn --parent-thread <id> without an explicit environment.
What happens today
resolveCreateThreadEnvironment turns the implicit host default of any child of a live parent into { type: "managed-worktree", baseBranch: { kind: "default" } } (apps/server/src/services/threads/thread-default-policy.ts, resolveCreateThreadEnvironment, second branch).
For a non-git source this can never succeed. In our case the folder name is Cyrillic, so provisioning dies even earlier, in deriveRepoDirName (apps/server/src/services/threads/worktree-paths.ts, REPO_DIR_NAME_PATTERN is ASCII-only):
system/error thread_provisioning_failed
Cannot derive repository directory name from source "/Users/<user>/Desktop/<Cyrillic folder>"
The thread lands in error before its first turn; the root thread in the same folder works fine because it uses the project default (unmanaged, resolved by resolveProjectDefaultThreadEnvironment after host.inspect_git_source reports no base branch).
What we expect
A child of a parent that runs straight in a plain, non-git folder of the same project should share that folder, the same way the parent does. Git checkouts should keep getting their own worktree. Worktree directory names should accept letters of any script (git and the file system do).
Prototype
Fork commit 4bd018d17 on feature/thread-project-dnd-and-panes in our fork:
resolveCreateThreadEnvironment takes an optional parentEnvironment (id, projectId, isGitRepo, workspaceProvisionType). When the parent's environment is unmanaged, not a git repo, belongs to the same project and is the parent thread's own environment, the child reuses it; otherwise the managed-worktree default stays.
thread-create.ts passes the parent's environment from the db.
REPO_DIR_NAME_PATTERN becomes /^[\p{L}\p{N}._][\p{L}\p{N}._-]*$/u (whitespace, leading dash, ./.. still rejected).
- Tests:
test/threads/thread-default-policy.test.ts (reuse for plain folder; worktree kept for git checkout, other project, foreign environment), test/threads/worktree-paths.test.ts (Cyrillic name).
Scenario
A user works in a project whose folder is not a git checkout (a folder of documents), on a local machine. They open a child thread of the focused thread — a second opinion from another model, or
bb thread spawn --parent-thread <id>without an explicit environment.What happens today
resolveCreateThreadEnvironmentturns the implicit host default of any child of a live parent into{ type: "managed-worktree", baseBranch: { kind: "default" } }(apps/server/src/services/threads/thread-default-policy.ts,resolveCreateThreadEnvironment, second branch).For a non-git source this can never succeed. In our case the folder name is Cyrillic, so provisioning dies even earlier, in
deriveRepoDirName(apps/server/src/services/threads/worktree-paths.ts,REPO_DIR_NAME_PATTERNis ASCII-only):The thread lands in
errorbefore its first turn; the root thread in the same folder works fine because it uses the project default (unmanaged, resolved byresolveProjectDefaultThreadEnvironmentafterhost.inspect_git_sourcereports no base branch).What we expect
A child of a parent that runs straight in a plain, non-git folder of the same project should share that folder, the same way the parent does. Git checkouts should keep getting their own worktree. Worktree directory names should accept letters of any script (git and the file system do).
Prototype
Fork commit
4bd018d17onfeature/thread-project-dnd-and-panesin our fork:resolveCreateThreadEnvironmenttakes an optionalparentEnvironment(id, projectId, isGitRepo, workspaceProvisionType). When the parent's environment isunmanaged, not a git repo, belongs to the same project and is the parent thread's own environment, the child reuses it; otherwise the managed-worktree default stays.thread-create.tspasses the parent's environment from the db.REPO_DIR_NAME_PATTERNbecomes/^[\p{L}\p{N}._][\p{L}\p{N}._-]*$/u(whitespace, leading dash,./..still rejected).test/threads/thread-default-policy.test.ts(reuse for plain folder; worktree kept for git checkout, other project, foreign environment),test/threads/worktree-paths.test.ts(Cyrillic name).