Document the two-engine Browser Run boundary and the native BPMN, Excalidraw, and TikZ units. Align catalog losses, redistribution notes, generated documentation, and release terminology with the final runtime split.
- commit
- 408b69fb4fa4c3a3c5a693b4814e5ca2f736a29f
- parent
- 850b1aaccdd9c9238353ac45cdb673a60873915d
- author
- Dami <dami.etoile@gmail.com>
| M | README.md | 5 | ++- |
| M | THIRD_PARTY_NOTICES.md | 11 | ++++--- |
| M | apps/ | 2 | +- |
| M | apps/ | 2 | +- |
| M | docs/ | 48 | ++++++++++++++++-------------- |
| M | release.sh | 2 | +- |
| M | renderers/ | 19 | ++++++------ |
| M | renderers/ | 16 | ++++++---- |
| M | renderers/ | 12 | ++++--- |
| M | renderers/ | 2 | +- |
@@ -11,8 +11,9 @@
1111 | `services/api/` | Cloudflare service for encrypted, accountless persistence |1212 | `services/shell/` | Cloudflare application shell and routing service |1313 | `renderers/catalog/` | Catalog service for renderer capabilities and health |14+| `renderers/browser-run/` | Private Browser Run execution bridge for browser-only engines |1415 | `renderers/edge/` | JavaScript and WebAssembly renderer units |15-| `renderers/client/` | Sandboxed browser renderers |16+| `renderers/client/` | Pinned browser frames used only by the Browser Run bridge |1617 | `renderers/python/` | Python renderer and translation units |1718 | `renderers/shared/` | Contracts shared across renderer runtimes |1819 | `shared/svg/` | Shared SVG normalization and presentation logic |@@ -62,7 +63,7 @@ are not the production release procedure.
6263 6364 ## Architecture6465 65-The editor runs at `diagram.zip`. Rendering is split into isolated units selected by hostname at `{engine}.render.diagram.zip`; the renderer catalog documents the contract and capabilities for all supported engines. Five renderers run in sandboxed browser frames, while the remaining renderers run in JavaScript, Python, or WebAssembly Workers.66+The editor runs at `diagram.zip`. Rendering is split into isolated HTTP units selected by hostname at `{engine}.render.diagram.zip`; the renderer catalog documents the contract and capabilities for all supported engines. Mermaid and diagrams.net execute behind a private Browser Run bridge. The other 28 renderers run in JavaScript, Python, or WebAssembly Workers. The application never executes renderer code directly.6667 6768 Server persistence is opt-in. **Publish** creates an open alias, while6869 **Encrypt & Publish** creates an encrypted alias. Anonymous drafts can use@@ -73,9 +73,9 @@ implementation:
7373 implementation and does not vendor UMLet GPL source.7474 - `licenses/erd-unlicense.txt`: the ERD parser/lowerer is an original7575 TypeScript implementation; the text records the compatibility target.76-- `licenses/excalidraw-license.txt`: the catalog references a separately77- deployed Excalidraw client renderer whose source is not present in this78- repository. Its deployment must retain its own source and notice record.76+- `licenses/excalidraw-license.txt`: Excalidraw is bundled into the dedicated77+ edge Worker. Its emitted npm dependencies and license texts are recorded in78+ `renderers/edge/artifacts/licenses/npm-runtime-NOTICE.md`.7979 8080 The Symbolator relationship is documented beside that Worker rather than in8181 the root license directory.@@ -97,8 +97,9 @@ npm run check:licenses
9797 ```9898 9999 Python units maintain deployment-specific notices beside their source.100-TikZ and diagrams.net publish source and license material directly in their101-built static asset directories.100+TikZ keeps corresponding source, transformation provenance, and license texts101+in `renderers/edge/artifacts/tikz/`. Diagrams.net publishes source and license102+material directly in its built static asset directory.102103 103104 The editor and documentation builds do not yet generate bundle-derived legal104105 notices. Their lockfiles are useful inputs to a future artifact-specific check,@@ -97,7 +97,7 @@ HTTP renderers identify their output with these response headers:
9797 | `X-Diagram-Engine-Version` | Identifies the underlying engine release. |9898 | `X-Renderer-Build` | Identifies the Diagram.zip renderer build. |9999 100-Browser renderers provide the same version identity from their catalog entry. Diagram.zip uses this identity before it assigns semantic roles.100+Every renderer provides the same version identity through its catalog entry and HTTP response. Diagram.zip uses this identity before it assigns semantic roles.101101 102102 An unknown or upgraded renderer build does not inherit an older profile automatically. It falls back to `safe-raw-1`, which supports only `raw`.103103 @@ -284,7 +284,7 @@ HTTP renderers identify their output with these response headers:
284284 | `X-Diagram-Engine-Version` | Identifies the underlying engine release. |285285 | `X-Renderer-Build` | Identifies the Diagram.zip renderer build. |286286 287-Browser renderers provide the same version identity from their catalog entry. Diagram.zip uses this identity before it assigns semantic roles.287+Every renderer provides the same version identity through its catalog entry and HTTP response. Diagram.zip uses this identity before it assigns semantic roles.288288 289289 An unknown or upgraded renderer build does not inherit an older profile automatically. It falls back to `safe-raw-1`, which supports only `raw`.290290 @@ -4,13 +4,12 @@
44 55 The repository assigns a final renderer path to all 30 catalog engines. The application does not contain a Fly.io render fallback. The catalog Worker does not contain a render proxy.66 7-Production completion requires these final checks:7+Production rollout requires these final checks:88 9-1. Deploy the UMLet Worker.10-2. Deploy the TikZ client unit.11-3. Deploy the catalog Worker without the render route.12-4. Deploy the application and documentation.13-5. Run the 30-engine production smoke test.9+1. Deploy the native BPMN, Excalidraw, and TikZ Workers.10+2. Deploy the private Browser Run bridge and the Mermaid and diagrams.net public units.11+3. Deploy the catalog Worker, application, and documentation.12+4. Run the 30-engine production smoke test.1413 1514 Pixel comparison is not a completion gate. Structural coverage is the completion gate. Each known loss must be visible in the catalog.1615 @@ -20,7 +19,7 @@ Pixel comparison is not a completion gate. Structural coverage is the completion
2019 - Each diagram type remains available.2120 - Each engine has one selected renderer path.2221 - A renderer failure must not select another renderer.23-- A client renderer must run in a script-only sandbox.22+- A browser-only renderer must execute behind the private Browser Run service.2423 - An HTTP renderer must accept only its assigned engine hostname.2524 - A render result must use the standard SVG viewer contract.2625 - A renderer must not add engine-specific application UI.@@ -43,10 +42,13 @@ Do not keep a compatibility service after an engine has a final path.
4342 4443 ```text4544 diagram.zip application46- |- client renderer frame at {engine}.render.diagram.zip4745 |- HTTP renderer at {engine}.render.diagram.zip/v1/svg4846 |- persistence Worker at diagram.zip/api/v1/*4947 `- catalog Worker at diagram.zip/render/v1/{health|catalog}48+49+Mermaid/diagrams.net HTTP unit50+ `- private Browser Run service binding51+ `- pinned renderer frame5052 ```5153 5254 The catalog Worker does not render diagrams. `POST /render/v1/svg` returns `404`.@@ -58,7 +60,7 @@ Each engine has a public renderer hostname. Engines can share one Worker deploym
5860 | Engine | Runtime | Unit or pipeline |5961 | --- | --- | --- |6062 | PlantUML | Worker WebAssembly | `plantuml-family` |61-| Mermaid | Client | `mermaid` |63+| Mermaid | Browser Run | `mermaid` through the private Browser Run bridge |6264 | GraphViz | Worker WebAssembly | `graphviz-family` |6365 | D2 | Worker WebAssembly | `d2` with the bounded grid layout |6466 | C4 PlantUML | Worker WebAssembly | `plantuml-family` through the C4 lowerer |@@ -68,20 +70,20 @@ Each engine has a public renderer hostname. Engines can share one Worker deploym
6870 | NwDiag | Worker Python | `blockdiag-family` |6971 | PacketDiag | Worker Python | `blockdiag-family` |7072 | RackDiag | Worker Python | `blockdiag-family` |71-| BPMN | Client | `bpmn` |73+| BPMN | Worker JavaScript | `bpmn` bounded BPMN DI-to-SVG renderer |7274 | Bytefield | Worker JavaScript | `bytefield` |7375 | DBML | Worker WebAssembly | `graphviz-family,dbml,graphviz` |74-| diagrams.net | Client | `diagramsnet` |76+| diagrams.net | Browser Run | `diagramsnet` through the private Browser Run bridge |7577 | Ditaa | Worker WebAssembly | `svgbob-family,svgbob` |7678 | ERD | Worker WebAssembly | `graphviz-family,erd,graphviz` |77-| Excalidraw | Client | `excalidraw` |79+| Excalidraw | Worker JavaScript | `excalidraw` with a Worker DOM/canvas shim |7880 | GoAT | Worker WebAssembly | `goat` |7981 | Nomnoml | Worker JavaScript | `nomnoml` |8082 | Pikchr | Worker WebAssembly | `pikchr` |8183 | Structurizr | Worker JavaScript and WebAssembly | `structurizr,plantuml-family,plantuml` |8284 | Svgbob | Worker WebAssembly | `svgbob-family` |8385 | Symbolator | Worker Python | `symbolator` |84-| TikZ | Client | `tikz` with the bundled TikZJax runtime |86+| TikZ | Worker WebAssembly | `tikz` with the bundled TikZJax TeX core |8587 | UMLet | Worker JavaScript | `umlet` UXF-to-SVG translator |8688 | Vega | Worker JavaScript | `vega-family` |8789 | Vega-Lite | Worker JavaScript | `vega-family,vega` |@@ -139,13 +141,13 @@ The response contains these identity headers:
139141 - `X-Diagram-Renderer`140142 - `X-Renderer-Build`141143 142-## Client unit contract144+## Browser Run contract143145 144-A client unit provides the health route, the capabilities route, and `index.html`. The frame uses the `diagram.zip:renderer:v1` message protocol.146+A browser-backed public unit provides the standard HTTP routes and calls the private Browser Run Worker through a service binding. The private service keeps a serialized Durable Object session for each engine and has no public route.145147 146-The application sets `sandbox="allow-scripts"`. It does not set `allow-same-origin`. The frame is hidden and cannot navigate the application. The frame returns an SVG result through `postMessage`.148+The Browser Run page loads the pinned engine frame and uses the `diagram.zip:renderer:v1` message protocol internally. The frame returns an SVG result to the private service; the public unit canonicalizes it before responding.147149 148-The standard diagram.zip viewer displays the returned SVG. A client unit does not provide editor controls or a separate viewer.150+The application sees only the public HTTP contract. It does not create renderer iframes or execute renderer packages.149151 150152 ## Presentation and SVG policy151153 @@ -163,8 +165,8 @@ The sanitizer removes scripts, event handlers, active embedded HTML, and externa
163165 164166 The migration uses structural checks. Each engine must meet these requirements:165167 166-- The final route or frame is available.167-- The repository fixture returns SVG or a valid client capability response.168+- The final HTTP route is available.169+- The repository fixture returns SVG.168170 - The SVG has usable dimensions.169171 - The response identifies the expected unit and pipeline.170172 - The output does not contain prohibited active content.@@ -204,9 +206,9 @@ The translator handles all five elements directly. An unknown custom Java class
204206 205207 ## TikZ boundary206208 207-TikZ runs in a dedicated client unit. The unit bundles the official TikZJax assets. The unit accepts source through the standard client protocol and returns ordinary SVG.209+TikZ runs in a dedicated WebAssembly Worker with the pinned TikZJax TeX/PGF package set. Wrangler imports the TeX module through its `CompiledWasm` rule. Each serialized request streams the compressed format dump directly into fresh Wasm memory.208210 209-The unit does not add a TikZ editor or viewer. The diagram.zip viewer displays the result.211+The unit cannot load arbitrary packages or external files. Its deterministic extraction script, unmodified corresponding TikZJax source, provenance, and GPL/LPPL terms are stored with the artifact.210212 211213 ## Fly.io removal boundary212214 @@ -235,9 +237,9 @@ Run these checks before completion:
235237 2. Run all application tests.236238 3. Run all documentation tests and the production build.237239 4. Run Wrangler dry-runs for every Worker unit.238-5. Run build and protocol checks for every client unit.240+5. Run build and protocol checks for the Browser Run bridge and both browser-backed units.239241 6. Search the application and renderer code for origin and compatibility paths.240242 7. Deploy the final units.241243 8. Run the 30-engine production smoke test.242244 9. Confirm that `POST https://diagram.zip/render/v1/svg` returns `404`.243-10. Confirm that the documentation examples use direct units or client frames.245+10. Confirm that the application and documentation examples use direct HTTP units only.@@ -226,7 +226,7 @@ run_in "$ROOT/renderers/edge" npm run deploy:python
226226 section 'private Browser Run deployment'227227 run_in "$BROWSER_RUN_DIRECTORY" "$BROWSER_RUN_DIRECTORY/node_modules/.bin/wrangler" deploy --strict --message "$RELEASE_MESSAGE" --config wrangler.jsonc228228 229-section 'client renderer deployment'229+section 'browser-backed renderer deployment'230230 for directory in "${CLIENT_DIRECTORIES[@]}"; do231231 run_in "$directory" "$WRANGLER" deploy --strict --message "$RELEASE_MESSAGE" --config wrangler.jsonc232232 done@@ -5,7 +5,8 @@ This directory contains the complete Cloudflare renderer plane for diagram.zip.
55 | Path | Purpose |66 | --- | --- |77 | `catalog/` | Health and capability catalog service; it does not render diagrams |8-| `client/` | Renderer bundles executed in sandboxed browser frames |8+| `browser-run/` | Private Browser Run service and per-engine Durable Object sessions |9+| `client/` | Pinned frames executed only by the Browser Run service |910 | `edge/` | JavaScript and WebAssembly renderer Workers |1011 | `python/` | Python renderer and translation Workers |1112 | `shared/` | Engine identities shared by the catalog and runtime units |@@ -55,13 +56,13 @@ The response headers identify the unit, build, and pipeline:
5556 - `X-Renderer-Build`5657 - `X-Diagram-Pipeline`5758 58-## Client unit contract59+## Browser Run contract5960 60-A client renderer provides the health route, the capabilities route, and a sandboxed frame. The frame uses the `diagram.zip:renderer:v1` message protocol. The frame accepts only its assigned engine.61+Mermaid and diagrams.net expose the same public HTTP unit contract as every other engine. Their public Workers validate the hostname-selected request and call the private `browser-run/` Worker through a service binding. The private Worker has no public route.6162 62-The application loads each frame with `sandbox="allow-scripts"`. The frame does not receive same-origin access. A failed client render does not switch to an HTTP renderer.63+Browser Run keeps one serialized Durable Object session per engine, launches the pinned frame, and uses the `diagram.zip:renderer:v1` message protocol internally. Idle sessions close after 60 seconds. A failed browser render does not select another renderer.6364 64-The client engines are Mermaid, BPMN, Excalidraw, diagrams.net, and TikZ.65+The Browser Run engines are Mermaid and diagrams.net. BPMN and Excalidraw use JavaScript Workers; TikZ uses a WebAssembly Worker.6566 6667 ## Dependency groups6768 @@ -79,15 +80,15 @@ Some units translate source into another engine. The pipeline header lists each
7980 8081 | Runtime | Count | Engines |8182 | --- | ---: | --- |82-| Worker JavaScript | 7 | Bytefield, Nomnoml, Structurizr, UMLet, Vega, Vega-Lite, WaveDrom |83+| Worker JavaScript | 9 | BPMN, Bytefield, Excalidraw, Nomnoml, Structurizr, UMLet, Vega, Vega-Lite, WaveDrom |8384 | Worker Python | 8 | BlockDiag, SeqDiag, ActDiag, NwDiag, PacketDiag, RackDiag, Symbolator, WireViz |84-| Worker WebAssembly | 10 | PlantUML, C4 PlantUML, GraphViz, DBML, ERD, D2, Ditaa, GoAT, Pikchr, Svgbob |85-| Sandboxed client | 5 | Mermaid, BPMN, Excalidraw, diagrams.net, TikZ |85+| Worker WebAssembly | 11 | PlantUML, C4 PlantUML, GraphViz, DBML, ERD, D2, Ditaa, GoAT, Pikchr, Svgbob, TikZ |86+| Browser Run | 2 | Mermaid, diagrams.net |8687 8788 The total is 30 of 30 engines. The Fly.io Java rendering image is not part of this renderer plane.8889 8990 ## Output policy9091 91-Every renderer returns SVG. Each HTTP unit sanitizes and decorates its output. Each client unit sanitizes its output before it sends the result to the application.92+Every renderer returns SVG through its public HTTP unit. The unit sanitizes and canonicalizes the result before it reaches the application, which applies presentation without rerunning the renderer.9293 9394 Scripts, event handlers, active embedded HTML, and external resources are not allowed. Renderer-specific losses are listed in the catalog and in each unit's capabilities response.@@ -121,7 +121,11 @@ const losses: Partial<Record<EngineId, readonly string[]>> = {
121121 'People, systems, containers, components, boundaries, core relationships, technology labels, tags, and the default C4 palette are retained semantically, but output is not pixel-compatible with native C4-PlantUML 2.7.0.',122122 ],123123 mermaid: ['External links and resource-loading elements are removed; XHTML labels retain only safe text formatting.'],124- bpmn: ['External links and resource-loading elements are removed from exported SVG.'],124+ bpmn: [125+ 'The bounded SVG renderer uses BPMN DI coordinates and a deliberately finite core symbol vocabulary; vendor-specific rendering extensions are ignored.',126+ 'Text uses deterministic browser-independent metrics and is not pixel-identical to bpmn-js.',127+ 'External resources, scripts, hyperlinks, and interactive overlays are not rendered.',128+ ],125129 graphviz: [126130 'Only SVG is in the rendering contract.',127131 'Resource-loading attributes such as image, imagepath, shapefile, fontpath, and stylesheet are rejected because the edge unit has no filesystem or network asset loader.',@@ -155,8 +159,9 @@ const losses: Partial<Record<EngineId, readonly string[]>> = {
155159 'External resources are blocked; embedded data images remain supported.',156160 ],157161 excalidraw: [162+ 'Only SVG is supported.',158163 'External resources are blocked; image data must be embedded in the scene.',159- 'Font subsetting is disabled by the sandbox policy, so exports embed the complete self-hosted font.',164+ 'The Worker uses browser-independent canvas and font metrics, so text wrapping and typography may differ from browser Excalidraw.',160165 ],161166 nomnoml: ['Only SVG is in the v2 rendering contract.'],162167 symbolator: [@@ -201,10 +206,9 @@ const losses: Partial<Record<EngineId, readonly string[]>> = {
201206 'Shadows, rounded corners, anti-aliasing, and edge separation flags are accepted for compatibility but have no effect in the Svgbob pipeline.',202207 ],203208 tikz: [204- 'Only SVG is supported.',205- 'The browser unit uses the bundled TeX/PGF package set, not a full TeX Live installation.',206- 'Layout, fonts, and SVG details can differ from the native dvisvgm renderer.',207- 'External files, shell escape, external links, and resource loads are unavailable.',209+ 'The edge unit uses the pinned TikZJax TeX/PGF package set, not a full TeX Live installation.',210+ 'External files, package downloads, shell escape, hyperlinks, and external resources are unavailable.',211+ 'Typography and SVG details may differ from the browser TikZJax unit.',208212 ],209213 umlet: [210214 'Only SVG is supported.',@@ -1,8 +1,10 @@
1-# diagrams.net client renderer1+# diagrams.net Browser Run renderer22 3-This sandboxed client unit uses the headless export runtime from diagrams.net4-29.6.1. The application code is Apache-2.0. Icon sets, stencil libraries, and5-diagram templates retain the additional upstream asset terms reproduced in3+The public diagrams.net HTTP unit calls a private Browser Run service, which4+uses this pinned headless export runtime from diagrams.net 29.6.1. The5+application never loads the frame directly. The application code is6+Apache-2.0. Icon sets, stencil libraries, and diagram templates retain the7+additional upstream asset terms reproduced in68 `vendor/assets/img/LICENSE`, `vendor/assets/shapes/LICENSE`, and79 `vendor/assets/stencils/LICENSE`.810 @@ -23,6 +25,6 @@ images and the unused mxGraph source distribution are excluded.
2325 ## Distributed notices2426 2527 `npm run build` publishes `SOURCE.md`, the Apache-2.0 text, and the upstream26-asset terms beside the client bundle. The asset terms restrict using the28+asset terms beside the Browser Run frame. The asset terms restrict using the2729 included icon and stencil libraries as software assets in Atlassian products2830 or its marketplace ecosystem. They expressly exempt end-user diagram output.@@ -33,6 +33,6 @@ for (const path of ['../dist/images/', '../dist/mxgraph/src/', '../dist/mxgraph/
3333 }3434 const frame = await readFile(new URL('../src/frame.js', import.meta.url), 'utf8')3535 for (const required of ['diagram.zip:renderer:v1', 'LoadingComplete', 'MAX_SOURCE_LENGTH', 'MAX_OUTPUT_LENGTH', 'event.source !== parent']) {36- if (!frame.includes(required)) throw new Error(`Client renderer contract is missing ${required}.`)36+ if (!frame.includes(required)) throw new Error(`Browser Run frame contract is missing ${required}.`)3737 }3838 console.log('diagrams.net client asset and protocol checks passed')