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}.sagaloadSession(id)/saveSession(id, { messages, history })— full chat session JSON at/my-sagas/{id}.json, with saga export as a side effectlistSessions()/upsertManifest(id, meta)/removeFromManifest(id)— shared index at/my-sagas/index.jsonscheduleFlush(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