Staged attachments live in git-excluded .xum/user-attachments and are lost by snapshot archive
- Dominant language
- TypeScript
- Stars
- 2k
- Forks
- 134
- Avg merge
- 14h 57m
- Merged PRs (30d)
- 307
Description
### Context
Workspace attachment staging writes uploads into the git-excluded `.xum/user-attachments` directory inside the checkout. PR #3940 pairs staging with archive admission (synchronous guard + preflight counter), which closes the live race between an in-flight upload and a model-driven snapshot archive.
### Problem (Codex review round 19, P2 — placement leg)
Snapshot archives capture tracked/untracked *git-visible* state and then remove the managed worktree. Because `.xum/user-attachments` is git-excluded:
- A **completed** upload is absent from the snapshot, so after unarchive the persisted chat/draft attachment path points at a file that no longer exists.
- This is not a race — it is data placement: any staged attachment in a snapshot-archived workspace is silently lost.
### Suggested directions
1. Store staged attachments outside the checkout (e.g. under the session dir, like other durable per-workspace artifacts), leaving a stable path that survives worktree removal/recreation; or
2. Include `.xum/user-attachments` in the snapshot capture and restore it on unarchive; or
3. On archive, migrate staged attachments referenced by persisted chats/drafts into the session dir and rewrite references.
Option 1 is likely cleanest for new writes but needs a migration/compat story for existing persisted paths (upgrade↔downgrade rule).
### References
- Staging: `WorkspaceService.stageAttachment` → `stageWorkspaceAttachment` (`.xum/user-attachments`)
- Snapshot capture: `worktreeArchiveSnapshotService`
- Review thread: PR #3940, round 19 (`src/node/services/workspaceService.ts`)
---
_Generated with [`mux`](https://github.com/coder/mux) • Model: `anthropic:claude-fable-5` • Thinking: `xhigh`_
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.