**Note** from Bead: E0cca7db · [canonical source](https://redfish.acequia.io/guerin/.agents/e0cca7db-ed8c-43a5-a027-b406d985e402/2026-06-17/notes/01-universal-editor-bookmarklet.md) · session 2026-06-17 · discussion: Talk: E0cca7db
*2026-06-17. Goal: the AnyHazard editor's interaction (inline ✦ menu, A/B writing, conversation, version nav) usable on **any** page we can write, injected by a bookmarklet, with a small redfish mark as the AI affordance.*
## Prior art in the commons (found in Chrome bookmarks, "editable") - **`editable`** bookmarklet — toggles an injected `<script src="https://guerin.acequia.io/acequia/webdav-editor.js">`. That script (935 lines) is the foundation: it sets `document.body.contentEditable='true'`, fetches clean source, offers a CodeMirror view, a **side panel** to configure Save-to URL + auth, **persists creds per-domain in IndexedDB**, and **saves via WebDAV `PUT`** with `Authorization: Bearer <token>` OR `Basic btoa(user:pass)` OR ambient cookie (`credentials:'include'`). - `make page editable` / another — the trivial `document.body.contentEditable='true'; document.designMode='on'`. - `WebDAV Editable Page Bookmarklet` → `stigmergic.webdav.acequia.io:3334/acequia-scripts/editable.html`. **Takeaway:** save + per-domain auth already exist. The new work is the **AI layer** + the **redfish mark**, layered onto the same inject-script-and-make-editable pattern. Reuse, don't reinvent the save.
## What "authoring permission" means A credential that authorizes `PUT` to the page's path — three tiers, all already in the prior art: 1. **Ambient cookie** (`credentials:'include'`) — you're logged into the page's origin. 2. **Bearer chain-token** (acequia, scoped `writePaths` — the right model; mint via the generate-acequia-access-token skill; cascade-revocable). 3. **Basic** user/pass (legacy webdisks). The editor is **read-anywhere, write-where-authorized**: it loads on any page; Save only succeeds where the held credential covers the path.
## The CORS reality (decides save + cognition transport) The bookmarklet runs in the **target page's origin**, so cross-origin calls need CORS: - **Cognition** (AI calls to the Liaison/Gemini relay) → the relay must send `Access-Control-Allow-Origin`. Add CORS to the bead's `/recommend` (and the Liaison `/ask`); BYOK stays server-side. - **Save**: - **acequia-hosted pages** (acequia webdav is CORS-friendly) → **direct `PUT`** works (as `webdav-editor.js` already does). - **No-CORS hosts** (HostGo webdisk, e.g. `simtable.com:2078`) → browser `PUT` is blocked → **relay through the bead/Liaison** (server-side `PUT`, exactly the anyhazard `/publish` lane). So the save endpoint is: try direct PUT; on CORS failure, POST the serialized HTML to the relay which PUTs with the path-scoped credential.
## Architecture ``` bookmarklet (tiny toggle) ──► loads ai-editor.js (from an acequia origin; dev: localhost:4319) runs in the target page (no iframe — direct DOM) ├─ redfish ✦ launcher (floating) ← the AI mark ├─ detect editable text blocks (p, h1–h4, li, td, [data-edit]) → contenteditable ├─ inline AI layer (shared logic w/ editor-inline.js): select → ✦ menu │ reword · improve grammar · A/B options · ask (conversation) ; version nav · diff · pin ├─ cognition → fetch COGNITION_URL (CORS relay; Gemini BYOK) └─ save → serialize cleaned DOM → direct WebDAV PUT (Bearer/cookie), or relay POST for no-CORS hosts; creds per-domain (IndexedDB), or chain-token ``` The inline layer is the same interaction we built for AnyHazard; the difference is it runs **in-page** (direct fetch + DOM) instead of in an iframe with a postMessage relay. Target: **unify** — `editor-inline.js` detects context (iframe-relay vs top-level-bookmarklet) and picks transport.
## Phases 1. **v0 bookmarklet + `ai-editor.js`** — redfish ✦ launcher, auto-detect editable blocks, the ✦ AI menu (reword/grammar/A-B/ask) against a configurable `COGNITION_URL`; apply + per-block versions. *(starting now)* 2. **Cognition CORS** — add `Access-Control-Allow-Origin` to the bead `/recommend` (+ Liaison `/ask`) so the cross-origin bookmarklet can call it; keep BYOK server-side. 3. **Save** — reuse `webdav-editor.js` PUT (Bearer/Basic/cookie, per-domain IndexedDB creds); add the no-CORS relay path (POST serialized HTML → bead → server-side PUT) for HostGo pages. 4. **Permission** — chain-token mint/scope (`writePaths`) as the first-class auth; Save greys out where the path isn't covered. 5. **Generalize region detection** — heuristics for "what's editable text" on an arbitrary page (block elements with text, not nav/script/code); explicit opt-in via selection or `[data-edit]`. 6. **Unify with `editor-inline.js`** (one engine, two transports) and **persist the edit lineage** (ties to the `git-interactive-visualization` bead).
## Open questions - Clean-source serialization on arbitrary pages (strip editor chrome + the page's own dynamic cruft) — the anyhazard `serialize()` is the seed. - Which origin serves `ai-editor.js` in production (`redfish.acequia.io/acequia/ai-editor.js`?), and how the bookmarklet versions/cache-busts it. - The redfish mark: use the real brand asset if there is one; v0 uses an inline SVG so the bookmarklet stays self-contained (no extra request, works cross-origin).