Repository navigation
Design review: start threads without a project (upstream #13612) #963
Description
Activity
Design review
Design review: start threads without a project
Reviewed against Pylon
00884406f7d8c59c3ee98a617ba8a1eb64661a04, upstream6b286ae8a20ef2e18fa70b09e92f66edd859128b(#13612), and39405f1992(#14532).Upstream behavior
“No project” is a UI abstraction over an ordinary persisted project.
apps/server/src/ws.tsaddsprojects.ensureScratch, which creates or reuses one project at<server baseDir>/scratch. It dispatches existingproject.createandproject.meta.updatecommands. Concurrent creation resolves through the existing unique active workspace-root invariant.Each new Scratch thread receives a plain subdirectory named from the date, prompt words, and thread ID. Its path occupies the existing
worktreePathfield, so providers, terminals, and file browsing use that directory. It is not a Git worktree.Contract additions are
ProjectEnsureScratchResult, an authenticated operate-scope RPC, optionalServerConfig.scratchWorkspaceRoot, andchat.newWithoutProject. Project IDs remain required; no persistence migration or new event type is introduced. Scratch is unavailable when the server data directory lies inside a Git checkout or repository detection fails.Web/desktop entry points include
NoProjectsHero.tsx,CommandPalette.tsx,DraftHeroHeadline.tsx, andmod+alt+n. Draft project changes preserve the composer.useThreadActions.tsexcludes Scratch folders from Git worktree deletion; deleting a thread retains its files.The mobile follow-up is material:
NewTaskRouteScreen.tsxremoves Scratch-only scopes from ordinary project rows and renders one “No project” row above the list. When there are no ordinary projects, it offers the empty-state action instead.NewTaskDraftScreen.tsxuses a neutral heading;NewTaskContextPickerScreens.tsxensures the destination machine’s Scratch project before retargeting a draft. Workspace selection is suppressed throughnew-task-flow-provider.tsx.Current Pylon behavior
Pylon’s contracts require project IDs, and its new-task picker requires a project. There is no Scratch RPC or advertised Scratch root. Existing non-Git projects and
worktreePathrouting provide much of the execution plumbing.apps/server/src/orchestration/decider.tsalready enforces project workspace uniqueness. However, Pylon has richer rollback, workspace ownership, cleanup, and Prime recovery behavior. A non-nullworktreePathcannot become sufficient evidence of Git isolation.There is also an environment-selection discrepancy to resolve: upstream web’s actual
useScratchProject.tspreserves the current machine and only chooses an unambiguous sole offering machine when none is current; mobile falls back to the first eligible machine.Options
- Don’t adopt. Retain project-first web, desktop, and mobile flows. No contracts, migrations, decider/projection, remote/tunnel, or provider changes. Low risk and negligible implementation size; users must add a folder before starting.
- Adapt Scratch projects. Adopt both commits’ final UX and additive contracts, preserving existing events/projections and required project IDs. Put allocation and recovery behind a server-owned service with explicit ownership and retry handling. All three clients participate; folders and credentials remain on the selected environment for local, remote, and tunnel access. Prime and other adapters receive an ordinary cwd through existing admission paths. Medium risk; roughly 1–2 engineering weeks including lifecycle coverage.
- Make projects genuinely optional. Add nullable project identity and explicit workspace identity across commands, events, projections, clients, and provider consumers. This requires historical replay compatibility and Pylon-numbered migrations; the current manifest ends at 67. Remote routing still requires an environment. High risk and several weeks; unnecessary for the requested UX.
Recommendation
Adapt Scratch projects, subject to maintainer decisions on machine selection and file retention. Include #14532 immediately.
Before adoption, address directory allocation occurring before command acceptance: replaying a request can allocate another directory even when dispatch ultimately returns an existing command receipt. Define how retained folders are discoverable and how Scratch behaves after configuration changes, project deletion, or server downgrade.
Phase implementation as server allocation/recovery and contracts, then shared client targeting, then web/desktop/mobile entry points. Keep multi-model Git fan-out from #964 unavailable for Scratch. Name-only project creation is a separate alternative, not an automatic conversion of Scratch files.
Verification plan
Cover concurrent ensure calls, deleted-folder restoration, allocation collisions, traversal-like IDs, interrupted/repeated bootstrap, and data directories inside Git. Verify both project↔Scratch draft transitions, machine switching, attachments, terminal/file cwd, deletion retention, reconnect, and mixed-version environments. Exercise Prime native/ACP and other supported providers; reject unsupported Git/rollback operations explicitly. Wait on worker drains and receipts.
Actual verification
Ran
git showfor both commits,rgsearches,git rev-parse HEAD, andgit status --short; HEAD matched the assigned base and status was clean.gh issue view 963 --repo pylon-code/pylonfailed because GitHub was unreachable. No tests, builds, browser sessions, or edits were performed.Read-only design review (Codex via relay, coordinated by Claude Opus 5.5) against Pylon
00884406f7. Decisions stay with the maintainer.
Maintainer asked (2026-10-01) to consider this as Pylon product work with its own design review, not a straight port.
Upstream:
6b286ae8a2(pingdotgg/t3code#13612, 23 files, +1081/-100) lets a user start a chat with no project/folder attached. It arrived after the frozen cycle #961 bound and belongs to the next upstream cycle, where this issue owns its disposition.Questions for the design: what workspace/cwd a projectless thread runs in for each provider (Claude, Codex, Prime, ACP), how checkpoints/diffs/terminal behave, sidebar grouping on web/desktop/mobile, remote/tunnel environments, and migration/projection impact (Pylon renumbered migrations; never reuse upstream numbering).
Exit: a recorded decision (adopt with adaptations / design differently / decline) linked from the upstream review index.