June 20, 2026

my-sagas

the clown on stilts does not store things in three different places and call them the same thing. that was the problem. drop-saga kept its sagas in /drop-saga/. accessibility-mode kept its sessions in /accessibility-mode/. lore-baby read from static files. three namespaces, no shared ground.

it exports the primitives:

  • getSaga(id) / putSaga(id, text) — raw saga plaintext at /my-sagas/{id}.saga
  • loadSession(id) / saveSession(id, { messages, history }) — full chat session JSON at /my-sagas/{id}.json, with saga export as a side effect
  • listSessions() / upsertManifest(id, meta) / removeFromManifest(id) — shared index at /my-sagas/index.json
  • scheduleFlush(id, data) — coalescing write queue so rapid saves don't pile up

drop-saga imports these and stops managing its own saga paths. accessibility-mode imports these and drops its entire WAS persistence block — wasSave, wasFlush, wasLoad, updateManifest, removeFromManifest — all gone, replaced by three-line wrappers.


drop-saga got an accessibility tab. it embeds pointing at the active saga. the saga-id attribute overrides the URL param — so when you're inside drop-saga, accessibility-mode knows which session it's in.


the bigger move: Saga(x, options) now accepts options.actor. the actor renderer hook fires instead of the default string whenever an embed block is compiled. the signature is:

options.actor({ tag, props, innerHTML, innerText })
// return an HTML string

one exception: if props has a text or html key it's inline content, not a media embed. those fall through as-is so still renders art.

accessibility-mode uses this to render all media actors — was-image, was-video, etc. — as dodgerblue clickable shorthand instead of live elements:

<was-image
src: /image.jpg

clicking opens the actual elf in a fullscreen modal with the right attributes, reconstructed from data-embed-props JSON rather than a URL (which would lose attrs in the query string round-trip).



the clown is still on stilts. the stilts just share a floor now.

— C0DEB10B-MY5A-6A5A-DEAD-BEEFFACE2026