Guide5 min read3 sections

Creator panel workshop

docs/CREATOR_PANELS.mdSource updated 2026-10-26
Markdown
On this page 3 sections

Select one saved object in the atelier and open Panel workshop…. Build the example preview, then use the checkbox outside the frame to allow its listed suggestions for that object. Choose a button in the panel and select Review suggestion. The ordinary proposal dialog checks the complete world, previews an unsaved draft and leaves acceptance to Save changes. Discard and saved undo retain their normal behavior. Apply the saved revision to update the shared development room.

The Tool collection selector also exposes operator-installed plugin panels; The garden palette is the public-SDK reference. Their typed selected-object commands use this same review, grant and save boundary. See registration and remaining scope.

The workshop supports portable JSON panel files. Open panel validates a file before displaying its source; Download panel exports validated source. No permission is stored in the file. Changing the source, rebuilding, closing the workshop or leaving the page disposes its frame, pending suggestion and grant. A new build starts without permission. A saved revision or selected-object mismatch invalidates the binding; a newer remote draft is also checked by proposal validation and Save.

#Source contract · format 1

A panel has exactly format, title, body and actions. The title is at most 80 characters. Body nodes have a tag, optional literal text, optional children, and an action on buttons. Supported elements are section, div, h2, h3, p, small, strong and button. Text is escaped into engine-generated HTML; it never becomes markup. Custom scripts, CSS, URLs, event handlers, forms, media, raw HTML and embedded frames are not part of this format.

Buttons require a nonempty text label and a declared action ID. IDs start with a lowercase letter and contain at most 48 lowercase letters, digits or hyphens. Each action has exactly id, label, property and value. The engine binds the action to the object selected by the user. The file cannot supply an entity ID, grant, save command, authoring key or merge policy.

Supported suggestions replace position, rotation, scale or material. Rotations use radians. Transforms are absolute replacements, not relative deltas. Their arrays contain three bounded finite numbers; scale values are positive. Material suggestions contain RGB color values from zero to one, with optional roughness, metalness and emission. The usual authoring compiler performs the final world validation. A material suggestion replaces that material value, so omitted optional values use normal material defaults; it does not invent per-part imported-model overrides.

json
{
  "format": 1,
  "title": "Garden finishes",
  "body": [
    {"tag":"h2","text":"A quieter green."},
    {"tag":"p","text":"Preview this finish on the selected object."},
    {"tag":"button","text":"Try garden green","action":"garden"}
  ],
  "actions": [
    {"id":"garden","label":"Garden green finish","property":"material",
     "value":{"color":[0.19,0.37,0.27],"roughness":0.8}}
  ]
}

Fixed limits: 32 KiB UTF-8 source, 128 elements, nesting depth eight, 32 children per collection and sixteen actions. Ordinary text has a 1,024-character limit, button/action labels 80 characters. Panel contents cannot increase these limits. The file format is a declarative HTML subset. Installed plugins separately register typed authoring commands, but their panels still contain no creator JavaScript.

#Frame and message boundary

The engine creates a new srcdoc frame with sandbox="allow-scripts" before attaching it. It deliberately omits allow-same-origin, navigation, forms and popups. This gives the frame an opaque origin. Only the engine's nonce-bearing bootstrap and stylesheet execute. CSP denies all other resource types, connections, base URLs and form actions. Raw creator text is never interpolated into code or attributes. The absence of creator scripts and URL-bearing elements is part of this boundary; iframe sandbox/CSP alone are not claimed to prevent every possible self-navigation by arbitrary JavaScript.

The parent never passes its editor token, document, player state or storage to the panel. The bootstrap knows only its random 128-bit session ID, the parent origin and its precompiled button IDs. Clicks emit bounded JSON strings with exactly protocol, session, sequence and action. The parent checks the actual source window, opaque null origin, session identity, increasing sequence, declared action, active permission, current selected object and saved revision. The request contains no commands or mutable values: the host resolves those from its owned, validated panel definition.

An accepted message produces a single strict transaction for review. It does not call the authoring API or mutate ECS. Another frame with the same session string still fails the source-window check. Closed sessions reject further messages. Messages are limited to 512 characters, eight per second and 256 bounded messages per session, including malformed attempts. The trusted bootstrap additionally requires a real browser click and throttles it. That gesture check improves interaction behavior; the host permission and transaction checks remain the authority boundary.

Host permission updates contain only the session ID and a boolean, sent to the exact frame window. The opaque frame requires * as the target origin for these messages; the receiver validates event.source === parent, the expected parent origin and its session. This channel carries no secrets. Revocation disables frame buttons and clears the pending host suggestion.

The browser behavior follows the HTML iframe sandbox contract and CSP Level 3 directives. The restrictions and allowlists are defense layers for this declared format, not support for arbitrary creator JavaScript.

#Verification and remaining scope

Run npm run check, npm test and npm run test:browser:panels. The browser command also runs the existing proposal-review regressions. Acceptance evidence records the tested source, actual browser results and screenshots.

The workshop provides opt-in editor panels with scoped suggestions and installed plugin commands. It does not register gameplay HUDs, enable arbitrary HTML/JavaScript panels, grant network tools or implement asynchronous creator-script jobs. Assistant task journaling/provenance is tracked separately in CREATOR_TASKS. Browser process memory/CPU isolation is not independently qualified. Broader browser/device coverage and public untrusted creator hosting remain open. The full milestones 0–18 plan and its acceptance gates remain unchanged.

End of Panel workshop