diff --git a/docs/architecture-invariants.md b/docs/architecture-invariants.md index c206fa74..66051e88 100644 --- a/docs/architecture-invariants.md +++ b/docs/architecture-invariants.md @@ -166,7 +166,7 @@ A file path an agent prints is a link on both surfaces it can appear on, and cli ### Filesystem path picker -**Filesystem path picker** (Link Existing "Browse" button + the extended mobile keyboard's `📁 Path` key): a lazy one-directory-at-a-time browser over `GET /api/filesystem/browse`, with `GET /api/filesystem/preview` serving the tapped file. It starts at the active session's working directory (falling back to `/mnt/d`), hides dot entries, and inserts the chosen path **without** Enter so the prompt is not submitted. The companion `⌫ All` key clears only the current unsent prompt buffer and must never emit the agent's `/clear` command. +**Filesystem path picker** (Link Existing "Browse" button + the extended mobile keyboard's `📁 Path` key): a lazy one-directory-at-a-time browser over `GET /api/filesystem/browse`, with `GET /api/filesystem/preview` serving the tapped file. It starts at the active session's working directory (falling back to the Codeman Cases root, then `/mnt/d`, then the first root), hides dot entries, and inserts the chosen path **without** Enter so the prompt is not submitted. The companion `⌫ All` key clears only the current unsent prompt buffer and must never emit the agent's `/clear` command. ⚠️ **This is a second file-serving surface, so it carries the same confinement burden as [Attachments](#attachments) and does not inherit it automatically.** Traversal is allowlisted to Home, `CASES_DIR`, `/mnt/d`, or extra roots explicitly configured via `CODEMAN_FILE_PICKER_ROOTS`; sensitive trees are blocked and symlink escapes are rejected after `realpath` resolution rather than before. Without the realpath step a symlink inside an allowed root would walk straight out of it. `preview` reuses the shared conversion cache and the **global** `document-conversion-limiter`, which is what stops N concurrent large-document previews from forking N multi-minute converter processes. Content types are pinned: images and PDF inline, DOCX/PPTX through the converters, and Markdown/TXT/JSON as inert `text/plain` (never `text/html`, which would be stored XSS on our own origin). Size caps are 2MB for text and 50MB for binary/document previews. diff --git a/src/web/routes/file-routes.ts b/src/web/routes/file-routes.ts index 9cad66cf..b578d576 100644 --- a/src/web/routes/file-routes.ts +++ b/src/web/routes/file-routes.ts @@ -574,8 +574,8 @@ async function resolveFilesystemPickerPath( // With no explicit path (the "Link Existing" case picker, which passes no // sessionId and an empty initialPath until the user has typed something), // land on the shared cases root rather than falling through to whichever - // root happens to be first. `Home` is only nested under `Codeman Cases` on - // the native default (~/codeman-cases); a Docker deployment binds them at + // root happens to be first. `Codeman Cases` sits inside `Home` only on the + // native default (~/codeman-cases); a Docker deployment binds them at // unrelated host paths (CODEMAN_APPDATA_PATH vs CODEMAN_CASES_PATH), so a // Home-first fallback opened the picker somewhere with no cases in sight — // and, worse, made an OLD case folder left behind by a since-changed