Bento Editor And Saved Preview
Last refreshed: 2026-07-28
Runtime Boundary
ANU-14 embeds the reviewed Anuva Bento editor and player without modifying
their runtime files. CMS vendors the @anuva/bento-contract and editor
artifact at vendor/anuva-bento/1.1.0/; the unchanged player artifact is
carried beside it for one exact consumer boundary.
The provenance record pins Bento merge 8dd5c4ff8a8a9760f845b2fc43c34ae6a940e07e,
editor protocol and artifact 1.1.0, contract package 1.1.0, presentation
contract and player 1.0.0, renderer 1.0.8-anuva-renderer.1, manifest hashes,
and the packaged Signal and Paper catalog hash.
/api/bento/artifacts/{editor|player}/... is authenticated and same-origin.
Only manifest-listed paths are readable. The server verifies file size and
SHA-256 before returning a file and applies a narrow CSP, same-origin framing,
nosniff, and private cache policy. Next.js output tracing explicitly includes
both immutable artifact directories.
Editor Session
src/lib/bento/editor-session.ts is the server authority. It validates:
- authenticated user, workspace, and presentation ownership;
- the latest accepted
presentation_compilationsaggregate; - exact Bento contract and template catalog;
- any recoverable workspace/user/presentation draft; and
- each declared asset's workspace, media type, checksum, and credential-free
/assets/{stable-id}.{extension}locator.
BentoEditorHost owns the iframe lifecycle. It accepts messages only from the
exact origin and iframe window, requires editor protocol 1.1.0, checks the
reviewed editor and renderer versions and required capabilities, loads the
complete presentation once, and then issues the stable focus command for the
selected scene and surface. After the origin/source gate, a closed runtime
message validator rejects unknown commands, malformed responses/events, and
invalid save envelopes before host state changes.
The iframe has no persistence authority or credentials. It can only propose a validated complete envelope to the host.
Saves, Drafts, And Conflicts
Manual saves and 1.5-second debounced autosaves share one serialized client
queue. The server revalidates the complete envelope, presentation identity,
asset declarations, base revision, and base checksum. It first upserts a
recoverable presentation_editor_drafts record and then performs a
compare-and-swap append through createPresentationRevision.
Accepted editor saves:
- allocate a database-unique revision key;
- use a workspace/presentation/client request key for idempotency;
- append an immutable compilation revision;
- advance
presentations.latestCompilation; - record author, authoring source, trigger, and safe operation attribution; and
- mark the matching draft resolved.
A conflict never moves the accepted pointer. The proposal remains a conflicted draft with expected and current revision/checksum identities. The UI requires an explicit choice to discard the draft and load saved state or confirm that the reviewed draft should become the next revision.
AI Assistant
The Bento Assistant uses the installed Mastra structured-output API with the
repository's existing editAgent and openai/gpt-5.6-terra model
configuration. The model sees only the instruction, selected surface/slide,
stable editable targets, allowlisted asset metadata, layouts, and expected
revision.
Model output is restricted to set-text, bind-asset, and apply-layout
intents. Server code supplies actor, operation ID, correlation ID, selected
surface/slide, and expected revision. Layout proposals must match an exact
family and surface-layout pair from the packaged catalog before server code
validates every resulting AnuvaEditorOperation with the Bento contract. The
user reviews a summary before the host sends one atomic apply-operations
batch, so Bento owns final preflight and composite undo.
ai_interactions meters the call as presentationBentoEdit. Durable audit
metadata stores only instruction digest/length, target identities, correlation
ID, operation IDs/types/scopes, usage, and result state. It excludes the raw
prompt, raw response, secrets, binaries, and executable content.
Asset Delivery
Presentation documents keep package-relative /assets/... identity. The
authenticated src/app/assets/[filename]/route.ts maps the stable ID to a
workspace-owned media or voiceover record, rejects unsupported active content,
streams the object through the server without redirecting the client, and
verifies the returned bytes against the lowercase SHA-256 before responding.
Signed storage URLs remain server-side transport details and never enter the
aggregate.
Saved-Revision Preview
BentoSavedPreview loads only the latest accepted compilation. It creates
Main, Companion, and Emphasis iframes from the exact vendored player, validates
origin/source/protocol/runtime identity, and applies closed runtime validation
to every player response/event. Each iframe receives the same envelope from
its native load event; Player 1.0.0 then reports its versioned ready lifecycle
event during that command. Controls remain blocked until every player reports
asset readiness.
One host clock sends absolute seek commands to all surfaces. Reset, pause,
backwards navigation, persistent Main/Companion state, transient Emphasis
state, and fragments therefore use the aggregate's single authoritative
timeline. Dirty editor state is labelled as newer than preview until a save is
accepted.
Recovery And Security Rules
- Runtime mismatch, invalid document, missing asset, integrity failure, and protocol error clear readiness and return a recoverable error.
- Editor and player messages require exact
event.originandevent.source. - Documents cannot contain signed URLs, query credentials, collaboration endpoints, update endpoints, executable AI output, or cross-workspace media.
- Existing simple Scene Editor controls remain available. Unsaved simple scene edits must be compiled before Bento can open so generated compilation does not silently overwrite a later editor-authored revision.