The editor was only open to somebody with an account. A guest now picks
a demo project on the sign-in screen and gets the whole editor on a copy
held in the tab. The server writes nothing for a guest, so there is no
guest session, no guest folder and no quota to keep.
- Demo copies are frozen copies like a release, in data/demos/. An
administrator makes, updates and removes one with "Demo copy..." in
the project's main menu. GET demos and GET demos/{token} need no
session. An empty project is just a demo that is empty.
- Demo material: an administrator offers an uploaded file with "Offer
as demo" in the pickers (PATCH {demo}, data/demo-files.json). Every
list carries it with demo: true, for accounts and guests alike.
Signed out, a list holds the demo material alone, without the owner.
- An offered file is only an administrator's to delete. A file a demo
copy names counts as used, like one a release names.
- The guest's project lives in MemoryProjectStore. Every store that
would write refuses in the tab before a request is made, and the
autosave is not attached at all.
- The main menu drops projects, snapshots and release for a guest. The
pickers drop Upload and Delete, a dropped or pasted file is refused,
and a recording is saved as a download.
- The toolbar says the work is not saved. The Account menu holds
"Sign in..." instead of Logout and the password.
- A guest's demo never goes into the address: a reload brings the
sign-in screen back, not the copy. Found by e2e 70.
- GET plugins needs no session any more, since a demo may switch one
on. It only reads the server's own modules.
Tests:
- e2e 70 (atx): ALL PASSED, 13 checks. Counter-test with the guest
autosave sent to the server: 70f and 70g red on the PUT.
- tests/core/guest.test.ts: 9 tests. PHP: demos 20, files 46,
rights 80 checks (the matrix asks every new route).
- Gate (atx): CHECK EXIT 0, 314 files, 4852 tests.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Uploaded images, fonts and sounds belonged to nobody. Every account
saw every file in the pickers, and only an administrator could
delete one, through the API alone. Now every account uploads into a
folder of its own, sees its own files and nobody's, and can delete a
file of its own that no project uses.
- Files are stored as data/<kind>/<folder>/<sha256>.<ext>, and the
folder is part of asset.file. A name without a folder belongs to
nobody.
- The folder is a random 12-character name kept in users.json and
given with the first upload. Renaming an account moves no file, and
a released game's URLs carry no account name.
- The list shows the caller's own files and nobody's. An
administrator sees all, each with owner and deletable.
- DELETE takes the name with its folder. It answers 403 unless the
file is the caller's or the caller is an administrator, and 409
while a project, snapshot or release of any account names it
(FileUsage). The 409 names the caller's own projects only.
- The pickers have a Delete button. The first press asks, the second
deletes, and a refusal shows the server's reason.
- A deleted account's folder stays and only administrators see it.
- tools/migrate-file-owners.php moved every used file into the folder
of the account using it (a copy each for two accounts) and rewrote
projects, snapshots and releases. A project's revision goes up, so
an open editor gets a conflict instead of saving old names back.
- Font families are named after the hash alone, so a folder never
ends up in a CSS family name.
Run on stein2 on 2026-10-07, backup in
/root/config-backup-20261007/data-before-344: 25 files used,
27 copies, 8 projects, 53 snapshots and 1 release rewritten, 30
unused files stay nobody's. Afterwards all 600 references resolve to
a file in their owner's folder.
Found while building: the Delete button cut its new label to "Del…"
because a button does not measure itself again on a new text. The
picker now lays its button row out again.
Tests:
- PHP files.test.php (new): 46 checks, counter-check 3 red
- Unit core + editor: 220 files, 3403 tests
- e2e 34 (melektaus-atx): ALL PASSED - 67 checks (2 new)
- Gate (melektaus-atx): CHECK EXIT 0, 256 files, 3977 tests
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>