Let full links change project files directly¶
Status: accepted
ADR 0114 governs how long a lobby link stays valid; this record governs what a full lobby link may do to the project's files.
Current decision¶
A workspace lobby is the project's view, so a full or owner link can browse, read, upload and remove the project's files from the browser, and a room's full link can add a prompt's attachments to the project. These are direct changes by the link holder. They do not go through the model, its permission checks, or ApplyPatch review. A view link sees no project files at all.
Uploads land in any listed folder of the project, not in a confined drop
folder such as work://shared/. An upload creates a new file and never
replaces one. Removal moves a file to the trash. The project's own listing,
minus .mevedel/ components at every depth, is the only authority for which paths a browser may name;
the browser never supplies a path the listing does not show. In a Git
project that listing includes each untracked, unignored Git repository
cloned inside it, by that repository's own listing.
Rationale¶
A project can be pure whiteboard and chat, with no code to protect, and still
need reference data that every session reads. Those files belong where the
sessions look for project material: the project tree. A drop folder under
.mevedel/ would be hidden from the tree, committed as versioned working
material, and a second place for workspace files beside the project itself.
Routing every browser upload or removal through the model was the alternative. It would keep one mutation path and an audit trail in the transcript, but it spends a model turn, and a session, on moving bytes the person already chose, and it fails exactly when no session is running. The direct path keeps the model's mutation tracking intact for model edits; it adds a second, narrow writer whose every change a human made explicitly.
Nested clones were added when a project that existed to share two cloned
reference repositories showed none of their files. Git reports an untracked
nested repository as one directory entry and project-files drops it, while
the model's search tools read those files; the browser then hid exactly the
material the sessions were reading. Asking each clone for its own listing
keeps that clone's ignore rules, and a clone the project ignores stays hidden.
The private-state exclusion applies before descending into clones as well as
to ordinary and merged-submodule paths. A root-only prefix filter exposed nested
workspace credentials and permissions through the same listing-based file
authority; matching whole path components closes that hole without hiding
ordinary nested project files.
Consequences¶
A full lobby link, which ADR 0114 already makes a long-lived bearer, now also
carries write access to the project tree. Anyone it is handed on to can add
files and remove them without a permission prompt. The bounds are: no
overwrite, no folder removal, no hidden upload names or ignored paths, no .mevedel/
state, at most 16 MiB per upload, and removal to the trash, which keeps the
bytes. Existing listed dotfiles, such as .gitignore, remain readable and
removable; the leading-dot restriction applies to new upload names, not the
project's existing files. The same bounds cover files inside nested clones; a clone the host
mounts read-only refuses the change itself. A file with unsaved changes in Emacs cannot be removed. Rotating the
lobby credentials revokes the access.
A model that read a file before a browser removed or added one sees the change the way it sees any outside edit: on its next read.
Decision history¶
The first proposal confined uploads to work://shared/ and left changes to
existing project files to the model. It was dropped once whiteboard-and-chat
projects made the project root the natural home for reference data, and the
drop folder's costs -- invisible in the tree, committed by default, a second
location -- outweighed the narrower write surface.