docs(website): DM25 data: URI lock on the demo + first-wipe notes

DEMO_MODE.md §3.3 gets the data: URI rule (a pasted image is an upload),
§9.1 records DM25, and §10 step 5 records the first wipes: the rig half
worked, and the seed loaded no module because the runner's chown of
modules/ and logs/ failed silently. BACKEND_DESIGN.md §5.1 mirrors the rule.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
2026-10-27 13:13:54 -05:00
parent 5628bf131b
commit 8e5d2f5f4e
2 changed files with 24 additions and 1 deletions

View File

@@ -1834,7 +1834,10 @@ it.
A sentence back refuses the write `403 { code: "DEMO_LOCKED", message, errors }` with that sentence; a
hook that throws refuses too.
- **Uploads.** Any request with a `multipart/*` content type is refused app-wide, before a router or
multer sees it.
multer sees it. So is any write whose JSON body has a `data:` URI in any string (DM25): a pasted
image is an upload that did not use multipart. The string is read as a browser reads an attribute
(character references decoded, tabs and newlines removed); "metadata:" and prose such as
"Data: none, yet" pass. Matching rules are in DEMO_MODE.md §3.3.
- **Search engines.** Every response carries `X-Robots-Tag: noindex, nofollow`. `/robots.txt` is
`Disallow: /`, served ahead of the SPA's static file.
- **`GET /public/settings`** gains `demo: { resetsAt, logins }`, from the `demo_state` settings row.