@descix/frqtl-node 0.6.0-p0.1 → 0.6.0-p0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/CLAUDE.md +1 -1
  2. package/LICENSE.md +664 -0
  3. package/README.md +1 -1
  4. package/dist/dist-manifest.json +125 -125
  5. package/dist/fat/pkg-node/egpt_wasm.js +7 -7
  6. package/dist/fat/pkg-node/egpt_wasm_bg.wasm +0 -0
  7. package/dist/fat/pkg-node/package.json +1 -1
  8. package/dist/frqtl/compat/providers/wasm-engine.js +29 -31
  9. package/dist/frqtl/compat/providers/wasm-load-browser.js +2 -2
  10. package/dist/frqtl/compat/renderer/RenderFamily.js +1 -2
  11. package/dist/frqtl/compat/renderer/RenderMesh.js +2 -3
  12. package/dist/frqtl/compat/renderer/RenderShape.js +1 -1
  13. package/dist/frqtl/compat/renderer/captureStill-common.js +1 -2
  14. package/dist/frqtl/compat/renderer/display-slot.js +1 -1
  15. package/dist/frqtl/compat/renderer/providers/p5-provider.js +5 -5
  16. package/dist/frqtl/compat/renderer/providers/three-camera-contract.js +1 -1
  17. package/dist/frqtl/compat/renderer/providers/three-camera-geometry.js +4 -4
  18. package/dist/frqtl/compat/renderer/providers/three-provider.js +23 -27
  19. package/dist/frqtl/compat/renderer/renderCapabilities-common.js +2 -2
  20. package/dist/frqtl/compat/renderer/renderer-provider-contract.js +1 -1
  21. package/dist/frqtl/compat/vendor.js +2 -2
  22. package/dist/frqtl/objects/FrqtlApp.js +22 -24
  23. package/dist/frqtl/objects/ObjectFactory.js +1 -2
  24. package/dist/frqtl/objects/constants/WallBehaviors.js +5 -5
  25. package/dist/frqtl/objects/geometry/SlabFace.js +6 -6
  26. package/dist/frqtl/objects/instruments/capture-host.js +2 -2
  27. package/dist/frqtl/objects/instruments/capture.js +4 -5
  28. package/dist/frqtl/objects/instruments/hosted-eyes.js +3 -4
  29. package/dist/frqtl/objects/objects/DirectedTunnel.js +10 -11
  30. package/dist/frqtl/objects/objects/LightSource.js +22 -25
  31. package/dist/frqtl/objects/objects/QuantumEmitter.js +14 -14
  32. package/dist/frqtl/objects/objects/Tube.js +14 -14
  33. package/dist/frqtl/objects/objects/absorbRadiation.js +12 -13
  34. package/dist/frqtl/objects/objects/actionCompiler.js +52 -52
  35. package/dist/frqtl/objects/objects/controlAction.js +2 -2
  36. package/dist/frqtl/objects/objects/controlBind.js +2 -2
  37. package/dist/frqtl/objects/objects/directedRedirectProgram.js +3 -3
  38. package/dist/frqtl/objects/objects/emitterProgram.js +9 -9
  39. package/dist/frqtl/objects/objects/frqtl-control-slider.js +3 -3
  40. package/dist/frqtl/objects/objects/frqtl-control-sync.js +9 -9
  41. package/dist/frqtl/objects/objects/frqtl-control-widgets.js +2 -2
  42. package/dist/frqtl/objects/objects/frqtl-control-write-queue.js +2 -2
  43. package/dist/frqtl/objects/objects/makeControlsForObject.js +25 -29
  44. package/dist/frqtl/objects/objects/makeControlsForRenderSurface.js +2 -2
  45. package/dist/frqtl/objects/objects/slitLinerScatter.js +8 -10
  46. package/dist/frqtl/objects/objects/sustainedSource.js +15 -16
  47. package/dist/frqtl/objects/objects/tagger.js +2 -2
  48. package/dist/frqtl/objects/schema/engine-scopes.js +11 -12
  49. package/dist/frqtl/objects/schema/index.js +6 -6
  50. package/dist/frqtl/objects/schema/scopes.js +10 -10
  51. package/dist/frqtl/objects/setup/_collisionMatrixLanes.js +1 -1
  52. package/dist/frqtl/objects/setup/setupBlackbodySubstrate.js +1 -1
  53. package/dist/frqtl/objects/setup/setupCollisionMatrix.js +3 -3
  54. package/dist/frqtl/objects/setup/setupConeEmitter3D.js +7 -8
  55. package/dist/frqtl/objects/setup/setupDoubleSlit.js +20 -21
  56. package/dist/frqtl/objects/setup/setupFxSmoke.js +1 -1
  57. package/dist/frqtl/objects/setup/setupLightSourceLab.js +23 -26
  58. package/dist/frqtl/objects/setup/setupSphereEmitter3D.js +39 -40
  59. package/dist/frqtl/objects/setup/setupTunnelLab.js +17 -19
  60. package/dist/frqtl/objects/setup/setupTunnelPointExit.js +1 -1
  61. package/dist/frqtl/objects/setup/setupWaveInterference.js +4 -5
  62. package/dist/frqtl/objects/v1-replacements.js +0 -1
  63. package/dist/frqtl/parts/CameraControls.js +5 -5
  64. package/dist/frqtl/parts/CameraPath.js +1 -1
  65. package/dist/frqtl/parts/CollisionActions.js +2 -3
  66. package/dist/frqtl/parts/CollisionTypes.js +1 -2
  67. package/dist/frqtl/parts/DetectorWall.js +10 -10
  68. package/dist/frqtl/parts/FrqtlControlsPanel.js +11 -11
  69. package/dist/frqtl/parts/FrqtlVision.js +1 -1
  70. package/dist/frqtl/parts/GraphingDetectorWall.js +3 -4
  71. package/dist/frqtl/parts/LargeObject.js +7 -8
  72. package/dist/frqtl/parts/LightColor.js +2 -2
  73. package/dist/frqtl/parts/LiveChart.js +1 -1
  74. package/dist/frqtl/parts/LogicGate.js +4 -7
  75. package/dist/frqtl/parts/OvenBox.js +1 -2
  76. package/dist/frqtl/parts/PointSource.js +10 -11
  77. package/dist/frqtl/parts/SlitLightSource.js +6 -6
  78. package/dist/frqtl/parts/SlitScreen.js +14 -14
  79. package/dist/frqtl/parts/SphereEmitter.js +24 -24
  80. package/dist/frqtl/parts/Tunnel.js +17 -17
  81. package/dist/frqtl/parts/Wall.js +17 -17
  82. package/dist/frqtl/scenes/dse-one-emitter.js +1 -1
  83. package/dist/frqtl/scenes/dse-one-slit.js +2 -2
  84. package/dist/frqtl/scenes/dse-photoelectric.js +3 -3
  85. package/dist/frqtl/scenes/dse-tunnel-rebuild.js +5 -6
  86. package/dist/frqtl/scenes/dse-two-emitters.js +1 -1
  87. package/dist/frqtl/scenes/dse-two-slits.js +2 -2
  88. package/dist/frqtl/scenes/laser-buildup.js +1 -1
  89. package/dist/frqtl/scenes/mirror-3d.js +4 -4
  90. package/dist/frqtl/scenes/mirror-route.js +9 -9
  91. package/dist/frqtl/scenes/mirror.js +1 -1
  92. package/dist/frqtl/scenes/self-interference.js +1 -1
  93. package/dist/frqtl/scenes/smoking-gun.js +1 -1
  94. package/dist/frqtl/scenes/sun.js +2 -2
  95. package/dist/shim/bundle/frqnb.js +3 -3
  96. package/dist/shim/bundle/index.js +1 -1
  97. package/dist/shim/bundle/manifest.js +2 -2
  98. package/dist/shim/bundle/zip.js +1 -1
  99. package/dist/shim/controls/index.js +14 -14
  100. package/dist/shim/controls/registry.js +3 -3
  101. package/dist/shim/engine/artifact-shell.js +1 -2
  102. package/dist/shim/engine/router.js +15 -17
  103. package/dist/shim/expr/ast-schema.js +5 -5
  104. package/dist/shim/field-descriptor/index.js +7 -8
  105. package/dist/shim/frame-data/index.js +3 -3
  106. package/dist/shim/index.js +4 -4
  107. package/dist/shim/notebook/canvas-guard.js +1 -1
  108. package/dist/shim/notebook/catalog.js +2 -2
  109. package/dist/shim/notebook/format.js +26 -26
  110. package/dist/shim/notebook/kernel.js +3 -4
  111. package/dist/shim/notebook/knob.js +0 -1
  112. package/dist/shim/notebook/module-resolver.js +6 -6
  113. package/dist/shim/notebook/produced-bindings.js +1 -1
  114. package/dist/shim/notebook/setup-builder.js +9 -12
  115. package/dist/shim/notebook/vendor-importmap.js +1 -1
  116. package/dist/shim/notebook/view-builder.js +1 -1
  117. package/dist/shim/notebook/view-ctx.js +1 -1
  118. package/dist/shim/notebook/warmup.js +2 -2
  119. package/dist/shim/page-params/index.js +8 -9
  120. package/dist/shim/registry/copy-gate.js +1 -1
  121. package/dist/shim/registry/exhibits.js +4 -4
  122. package/dist/shim/registry/experiments.js +3 -3
  123. package/dist/shim/registry/walkthrough.js +21 -24
  124. package/dist/shim/render/render-stages.js +2 -2
  125. package/dist/shim/render/sun-look.js +2 -2
  126. package/dist/shim/rpc/index.js +2 -2
  127. package/dist/shim/runtime/index.js +12 -12
  128. package/dist/shim/storage/modules.js +8 -8
  129. package/llms.txt +2 -2
  130. package/package.json +4 -3
@@ -56,7 +56,7 @@ export const PROSE_CELL_TYPES = Object.freeze(['markdown']);
56
56
  * Cell type. `markdown` renders prose. `js` executes via the Runtime lane
57
57
  * (`math` or `frqtl`). `module` is user-code reachable by import (not runnable).
58
58
  * `canvas` mounts a live physics realm. `chart` renders a data view. `view` runs
59
- * ARBITRARY user code in the realm (WS-NOTEBOOK-VENDOR-VIEW Phase 2b) — the
59
+ * ARBITRARY user code in the realm — the
60
60
  * user module (`module="<name>#<export>"`) imports vendored libs via the 2a
61
61
  * import-map and renders into a DOM `mount`. `liveChart=` is a blessed PRESET
62
62
  * over this same `view` substrate.
@@ -73,7 +73,7 @@ export const PROSE_CELL_TYPES = Object.freeze(['markdown']);
73
73
  * @property {string[]} out
74
74
  * Binding names this cell PRODUCES (committed to the kernel's binding store on success).
75
75
  * @property {string} bind
76
- * For `canvas` cells: RETIRED runner binding name (WS-NOTEBOOK-SHIM-MANAGED-BUILDER).
76
+ * For `canvas` cells: RETIRED runner binding name.
77
77
  * A canvas that carries BOTH `setup` and a legacy `bind`/`out` runner ref is an
78
78
  * unconverted cell and FAILS LOUD at both hosts (C7 migration guard). The runner is
79
79
  * now realm-internal, never a kernel binding.
@@ -82,7 +82,7 @@ export const PROSE_CELL_TYPES = Object.freeze(['markdown']);
82
82
  * For `canvas` cells: RETIRED (the opaque setup-factory name) — a `spec` on a canvas
83
83
  * FAILS LOUD at both hosts (factory-retire C3).
84
84
  * @property {string} setup
85
- * For `canvas` cells: the setup declaration (WS-NOTEBOOK-SHIM-MANAGED-BUILDER).
85
+ * For `canvas` cells: the setup declaration.
86
86
  * `<module-name>` is a `type="module"` cell's `name`. Its grammar depends on `shape`
87
87
  * and is owned by lib/shim/notebook/setup-builder.js parseSetupDeclaration: a factory
88
88
  * canvas is `'<module-name>#<factoryName>'` (the name REQUIRED), a recipe canvas is
@@ -92,7 +92,7 @@ export const PROSE_CELL_TYPES = Object.freeze(['markdown']);
92
92
  * Empty for all other cell types.
93
93
  * @property {string} shape
94
94
  * For `canvas` cells: OPTIONAL setup-form discriminator naming which SHAPE the
95
- * declared `setup` module takes (Bite 5c — frqtl-notebook recipe fix). Two forms:
95
+ * declared `setup` module takes (the frqtl-notebook recipe fix). Two forms:
96
96
  * - `'factory'` (DEFAULT when omitted): the module export is a setup FACTORY
97
97
  * `fn(frqtl, universe, options)` — the shim synthesizes
98
98
  * `runner.setup((u,o) => fn(frqtl, u, o), opts)` (the pre-existing gallery form,
@@ -119,7 +119,7 @@ export const PROSE_CELL_TYPES = Object.freeze(['markdown']);
119
119
  * all other cell types.
120
120
  * @property {boolean} render3d
121
121
  * For `canvas` cells: OPTIONAL — request the three.js 3D renderer + perspective
122
- * camera for this canvas (WS gym-controls-as-sugar Bite 0 ADDENDUM, 2026-07-03).
122
+ * camera for this canvas.
123
123
  * Selected through the ONE renderer-selection mechanism (the boot module's
124
124
  * bootRealm, lib/frqtl/experiments/_shared/boot.js) — NOT a new renderer
125
125
  * mechanism. The host (notebook-pane) threads this into `realm-frqtl.js`'s
@@ -131,20 +131,20 @@ export const PROSE_CELL_TYPES = Object.freeze(['markdown']);
131
131
  * `false` for all other cell types.
132
132
  * @property {Object<string,number|string>} renderOptions
133
133
  * For `canvas` cells: OPTIONAL render-INTENT knob assignments parsed from
134
- * `"key=value,…"` (WS gym-controls-as-sugar fix-loop #6 Finding B, 2026-07-04) —
134
+ * `"key=value,…"` (gym-controls-as-sugar fix-loop #6 Finding B, 2026-07-04) —
135
135
  * the notebook-cell channel for the SAME render-intent writes a scene file states
136
136
  * itself (e.g. lib/frqtl/scenes/collision-matrix-3d.js's
137
137
  * `exp.render({ shape: 'sphere', colorScheme: 'roygbiv' })`, a ferry to
138
138
  * `runner.setRenderOptions`). PURE PARSE — reuses the identical `_parseOpts`/
139
139
  * `_joinOpts` machinery as `opts` (same `kind:'opts'`), but is a DISTINCT,
140
140
  * SEPARATE key — never folded into `opts`. This is deliberate channel
141
- * separation (architect ruling): `opts` feeds the setup
141
+ * separation: `opts` feeds the setup
142
142
  * FACTORY as physics-knob arguments (`frqtl.knob` → `options` param);
143
143
  * `renderOptions` feeds `runner.setRenderOption()` calls AFTER `runner.setup()`
144
144
  * returns — a render-knob write must never be mixed into the physics-knob bag.
145
145
  * Empty → `{}`; omitted on serialize when empty. Empty for all other cell types.
146
146
  * @property {string} cameraPreset
147
- * For `canvas` cells: OPTIONAL named camera-orbit preset (WS gym-controls-as-sugar
147
+ * For `canvas` cells: OPTIONAL named camera-orbit preset (gym-controls-as-sugar
148
148
  * fix-loop #6 Finding B) — the notebook-cell channel for a standalone page's
149
149
  * `runner.cameraControl.setPreset('<name>')` call (e.g. a 3D page's
150
150
  * `window._egptFx.cameraPreset = 'down-barrel'`, applied by `fx-experiment.js`
@@ -163,7 +163,7 @@ export const PROSE_CELL_TYPES = Object.freeze(['markdown']);
163
163
  * cell types.
164
164
  * @property {string[]} produces
165
165
  * For `canvas` cells: the serializable binding name(s) the canvas COMMITS to the
166
- * kernel after the realm-internal runner mounts (WS-NOTEBOOK-REALM-KERNEL-BINDING).
166
+ * kernel after the realm-internal runner mounts.
167
167
  * The realm DERIVES each value at runtime via the frozen handle (`produceVia`) and
168
168
  * the host commits it via `kernel.commitViewOutputs`. Parsed with `_splitNames`
169
169
  * (→ `string[]`); empty → `[]`; omitted on serialize when empty. On parse a canvas's
@@ -178,7 +178,7 @@ export const PROSE_CELL_TYPES = Object.freeze(['markdown']);
178
178
  * @property {string} produceAfter
179
179
  * For `canvas` cells: OPTIONAL integer-string tick count to WARM UP the realm
180
180
  * (deterministic `handle.step()` loop) BEFORE deriving the produced binding
181
- * (WS-NOTEBOOK-BASELINE FIX B). The runner mounts at tick ~0 where no particle has
181
+ * The runner mounts at tick ~0 where no particle has
182
182
  * reached the detector yet — deriving immediately commits an EMPTY histogram. Warming
183
183
  * up `produceAfter` ticks lets particles cross the stage and accumulate at the detector
184
184
  * so the committed binding (and the downstream chart) shows REAL data. ONE config
@@ -186,7 +186,7 @@ export const PROSE_CELL_TYPES = Object.freeze(['markdown']);
186
186
  * the host default warmup. Empty for all other cell types.
187
187
  * @property {string} liveChart
188
188
  * For `canvas` cells: OPTIONAL frozen-handle `call()` projector name the live
189
- * SAME-CELL accumulation chart polls each throttle tick (WS-NOTEBOOK-SAMECELL-LIVE-CHART).
189
+ * SAME-CELL accumulation chart polls each throttle tick.
190
190
  * The blessed value is `'detectorHistogram'` (the one frqtl producer) — it reuses the
191
191
  * SAME projector vocabulary as `produceVia`. UNLIKE `produces`, `liveChart` commits
192
192
  * NOTHING to the kernel: it draws CONTINUOUSLY inside the canvas's OWN realm off the
@@ -205,7 +205,7 @@ export const PROSE_CELL_TYPES = Object.freeze(['markdown']);
205
205
  * boot (`frqtl` | `chart` | a BYO name). `_realmNameForCell` ALREADY honors this:
206
206
  * an explicit `cell.realm` wins, else the cell TYPE selects the blessed pre-load.
207
207
  * PURE PARSE — empty → `''` (omitted on serialize; the host falls back to the
208
- * type-default `frqtl`). WS-NOTEBOOK-VENDOR-VIEW Phase 2b.
208
+ * type-default `frqtl`).
209
209
  * @property {string} module
210
210
  * For `view` cells: the user render module declaration `'<module-name>#<exportName>'`,
211
211
  * mirroring the canvas `setup` shape. `<module-name>` is a `type="module"` cell's
@@ -213,13 +213,13 @@ export const PROSE_CELL_TYPES = Object.freeze(['markdown']);
213
213
  * export (zero/multiple → FAIL-LOUD at the view-builder synthesis helper, never
214
214
  * guess; C5 mirror). The shim runs the named export IN THE REALM with the view
215
215
  * `ctx`. PURE PARSE — empty → `''` (omitted on serialize). Empty for non-`view`
216
- * cell types. WS-NOTEBOOK-VENDOR-VIEW Phase 2b.
216
+ * cell types.
217
217
  * @property {string} subscribe
218
218
  * For `view` cells: OPTIONAL cross-cell — the cellId of ANOTHER canvas whose tick
219
219
  * stream this view observes. PARSED + round-tripped now for format stability, but
220
220
  * the cross-cell WIRING is DEFERRED (§3.4 of the design): the same-cell path is the
221
- * primary 2b deliverable. PURE PARSE — empty → `''` (omitted on serialize). Empty
222
- * for non-`view` cell types. WS-NOTEBOOK-VENDOR-VIEW Phase 2b.
221
+ * primary 2b path. PURE PARSE — empty → `''` (omitted on serialize). Empty
222
+ * for non-`view` cell types.
223
223
  * @property {Object<string,number|string>} opts
224
224
  * For `canvas` cells: driving-knob assignments parsed from `"key=value,…"`.
225
225
  * PURE PARSE only — validation is `lib/shim/notebook/knob.js`'s authority. Empty → `{}`.
@@ -521,7 +521,7 @@ export function parse(html) {
521
521
  ' — legal types (CELL_TYPES): ' + CELL_TYPES.join(', ') + ' (FAIL-LOUD).'
522
522
  );
523
523
  }
524
- // WS-NOTEBOOK-REALM-KERNEL-BINDING: a canvas's `produces` names are the
524
+ // A canvas's `produces` names are the
525
525
  // serializable bindings it COMMITS to the kernel after the realm-internal
526
526
  // runner mounts. They are FOLDED INTO `out` here (a produced binding IS an
527
527
  // output binding the cell commits) so producer-discovery + the topo run-order
@@ -548,51 +548,51 @@ export function parse(html) {
548
548
  out: foldedOut,
549
549
  bind: a.bind || '',
550
550
  spec: a.spec || '',
551
- // WS-NOTEBOOK-VENDOR-VIEW Phase 2b: view-cell declaration (realm/module/subscribe).
551
+ // View-cell declaration (realm/module/subscribe).
552
552
  // PURE PARSE — kept verbatim; the host validates (FAIL-LOUD). View-only in
553
553
  // practice; empty for every other cell type so the attrs are omitted on
554
554
  // serialize (round-trip idempotent).
555
555
  realm: a.realm || '',
556
556
  module: a.module || '',
557
557
  subscribe: a.subscribe || '',
558
- // WS-NOTEBOOK-SHIM-MANAGED-BUILDER: the canvas DECLARES its setup +
558
+ // The canvas DECLARES its setup +
559
559
  // runner config; the shim synthesizes the builder from these. Only
560
560
  // meaningful for type="canvas"; empty for every other type so the
561
561
  // attribute is omitted on serialize (round-trip idempotent).
562
562
  setup: a.setup || '',
563
- // Bite 5c: the setup-form discriminator ('factory' | 'recipe'). PURE PARSE
563
+ // The setup-form discriminator ('factory' | 'recipe'). PURE PARSE
564
564
  // — kept verbatim; the setup-builder synthesis helper validates it (empty →
565
565
  // 'factory'; unknown → FAIL-LOUD). Canvas-only in practice; empty for every
566
566
  // other cell type so the attribute is omitted on serialize (idempotent).
567
567
  shape: a.shape || '',
568
568
  stage: a.stage || '',
569
569
  seed: a.seed || '',
570
- // WS gym-controls-as-sugar Bite 0 ADDENDUM: request the three.js 3D
570
+ // Request the three.js 3D
571
571
  // renderer for this canvas (mirrors `collapsed`'s bool-attr parse —
572
572
  // only the literal "true" sets it; absent/anything else → false,
573
573
  // omitted on serialize, idempotent round-trip). Canvas-only in
574
574
  // practice.
575
575
  render3d: a.render3d === 'true',
576
- // WS gym-controls-as-sugar fix-loop #6 Finding B: render-INTENT knobs
576
+ // gym-controls-as-sugar fix-loop #6 Finding B: render-INTENT knobs
577
577
  // (`runner.setRenderOption` key/value pairs) — reuses `_parseOpts`
578
578
  // (SAME kind:'opts' parser as `opts`, but a channel-separate key; see
579
579
  // the @property doc above). Canvas-only in practice.
580
580
  renderOptions: _parseOpts(a.renderOptions),
581
- // WS gym-controls-as-sugar fix-loop #6 Finding B: named camera-orbit
581
+ // gym-controls-as-sugar fix-loop #6 Finding B: named camera-orbit
582
582
  // preset (`runner.cameraControl.setPreset` call) — PURE PARSE, kept
583
583
  // verbatim as a string (mirrors `seed`). Canvas-only in practice.
584
584
  cameraPreset: a.cameraPreset || '',
585
- // WS-NOTEBOOK-REALM-KERNEL-BINDING: the serializable binding(s) this canvas
585
+ // The serializable binding(s) this canvas
586
586
  // commits + the frozen-handle call that derives each. Canvas-only; empty for
587
587
  // every other cell type so the attrs are omitted on serialize (idempotent).
588
588
  produces: declaredProduces,
589
589
  produceVia: a.produceVia || '',
590
- // WS-NOTEBOOK-BASELINE FIX B: integer-string warmup tick count. PURE PARSE —
590
+ // Integer-string warmup tick count. PURE PARSE —
591
591
  // kept verbatim as a string (mirrors `seed`); the host parses + clamps it
592
592
  // (numeric validation is the host's authority, not this pure parser). Empty
593
593
  // for every other cell type so the attr is omitted on serialize (idempotent).
594
594
  produceAfter: a.produceAfter || '',
595
- // WS-NOTEBOOK-SAMECELL-LIVE-CHART: the SAME-CELL live accumulation chart's
595
+ // The SAME-CELL live accumulation chart's
596
596
  // projector name + kind. PURE PARSE — kept verbatim as strings (mirrors
597
597
  // `produceVia`/`seed`); the host validates the projector against the blessed set
598
598
  // and the kind against `bar|line` (FAIL-LOUD). They commit NOTHING to the kernel
@@ -652,7 +652,7 @@ function _cellOpenTag(cell) {
652
652
  if (kind === 'names') {
653
653
  str = _joinNames(key === 'out' ? outOnly : key === 'produces' ? producesArr : cell[key]);
654
654
  } else if (kind === 'opts') {
655
- // Generalized to `cell[key]` (WS gym-controls-as-sugar fix-loop #6 Finding B):
655
+ // Generalized to `cell[key]` (gym-controls-as-sugar fix-loop #6 Finding B):
656
656
  // a hardcoded `cell.opts` here was harmless while `opts` was the ONLY
657
657
  // kind:'opts' key, but would have silently serialized `opts`'s content
658
658
  // under a SECOND opts-kind key's tag (`renderOptions`) once one was added —
@@ -378,10 +378,9 @@ export class NotebookKernel {
378
378
  * keep document order. A dependency cycle → FAIL-LOUD throw (no safe order).
379
379
  * NEVER auto-runs; NEVER mutates bindings.
380
380
  *
381
- * FRQTL-MAINT(runall-excludes-chart-cells) — FIXED (ws-artifact-showcase Bite
382
- * A2, FRAQTL issue #61). The RUNNABLE map used to be `{js, canvas}` only —
381
+ * FRQTL-MAINT(runall-excludes-chart-cells) — FIXED. The RUNNABLE map used to be `{js, canvas}` only —
383
382
  * `runAll()` reported `total:N ran:N` while silently never running `chart`/
384
- * `view` cells (tester finding 2026-07-03, `double-slit-rosetta-qft.html`),
383
+ * `view` cells (`double-slit-rosetta-qft.html`),
385
384
  * even though a manual per-cell Run on the same cell works (it routes through
386
385
  * the pane's realm-cell runner, `opts.runner`, not `runCell`). `chart`/`view`
387
386
  * cells DO declare `in`/`out` bindings today (`_resolveChartRecipe` FAIL-LOUD
@@ -391,7 +390,7 @@ export class NotebookKernel {
391
390
  * whichever cell produces the binding it reads, exactly like a `js` consumer.
392
391
  * The pane's `opts.runner` (lib/components/notebook-pane/index.js `runAll()`)
393
392
  * already special-cased `chart` alongside `canvas` — it was only ever missing
394
- * `view`, fixed in the same bite.
393
+ * `view`, fixed in the same change.
395
394
  *
396
395
  * @returns {Array<object>} ordered cell objects (each has `{ id, type, lane, body, in, out }`).
397
396
  * @throws {Error} if a cycle is detected in the declared `in`/`out` graph.
@@ -2,7 +2,6 @@
2
2
 
3
3
  /**
4
4
  * Notebook knob — the SINGLE authority for the canvas-cell driving knob
5
- * (WS-NOTEBOOK-D GAP2).
6
5
  *
7
6
  * A canvas cell may carry an `opts="<key>=<value>,…"` attribute (parsed to a
8
7
  * `{key: Number}` map by lib/shim/notebook/format.js — a pure module that does
@@ -1,12 +1,12 @@
1
1
  /* Copyright 2023-2026 by Essam Abadir */
2
2
 
3
3
  /**
4
- * Notebook cell-as-module resolver — the IN-MEMORY blob closure (WS-NOTEBOOK-IMPORT
5
- * B2; architect build-gate ruling C + VETO-CLASS constraint #1).
4
+ * Notebook cell-as-module resolver — the IN-MEMORY blob closure (B2;
5
+ * build-gate C + VETO-CLASS constraint #1).
6
6
  *
7
7
  * Named ESM export. PURE module — NO Runtime/Bus/DOM/engine imports. It is
8
8
  * host-neutral (it must NOT assume CodeEditorPane or any pane exists — model-gate
9
- * ruling 6): the blob-minting + dynamic-import are injected by the caller
9
+ * rule 6): the blob-minting + dynamic-import are injected by the caller
10
10
  * (Runtime.runCell in the browser; a test stub in node).
11
11
  *
12
12
  * ── What it does ─────────────────────────────────────────────────────────────
@@ -118,8 +118,8 @@ export function splitImportsAndBody(code) {
118
118
 
119
119
  // Rewrite every relative specifier in `source` to the blob URL of the resolved
120
120
  // sibling (looked up in blobUrlByKey) — BOTH static `from '…'` clauses (import/
121
- // export) AND dynamic `import('…')` call expressions (WS gym-controls-as-sugar
122
- // Bite 0a REMEDIATION, Finding 2: the synthesized builder now DEFERS its
121
+ // export) AND dynamic `import('…')` call expressions (gym-controls-as-sugar
122
+ // REMEDIATION, Finding 2: the synthesized builder now DEFERS its
123
123
  // module-cell import to a dynamic `await import(...)` placed AFTER
124
124
  // `frqtl.ensureEngine()` — see setup-builder.js — so the relative specifier
125
125
  // this rewrite must resolve can appear inside the function BODY, not only the
@@ -242,7 +242,7 @@ export function buildModuleClosure(modules, mintBlobUrl) {
242
242
  * invokes `mod.default(caps, inputs)`.
243
243
  *
244
244
  * The rewrite runs on the FULL `code` (imports AND body) BEFORE splitting —
245
- * WS gym-controls-as-sugar Bite 0a REMEDIATION, Finding 2: the synthesized
245
+ * REMEDIATION, Finding 2: the synthesized
246
246
  * builder's module-cell reference is now a DYNAMIC `await import('<module>')`
247
247
  * placed inside the body (after `frqtl.ensureEngine()`, deliberately deferring
248
248
  * evaluation — see setup-builder.js), so a relative specifier needing
@@ -2,7 +2,7 @@
2
2
 
3
3
  /**
4
4
  * produced-bindings — the PURE derive-the-serializable-binding helper for the
5
- * realm→kernel binding seam (WS-NOTEBOOK-REALM-KERNEL-BINDING). NO DOM / engine /
5
+ * realm→kernel binding seam. NO DOM / engine /
6
6
  * Runtime / Bus import, so a test exercises it with a fake handle WITHOUT a browser.
7
7
  *
8
8
  * A DECLARED canvas commits its `produces` binding(s) by DERIVING each value from the
@@ -3,7 +3,6 @@
3
3
  /**
4
4
  * setup-builder — the SOLE authority that synthesizes the canonical experiment
5
5
  * BUILDER source from a `canvas` cell's declarative configuration
6
- * (WS-NOTEBOOK-SHIM-MANAGED-BUILDER).
7
6
  *
8
7
  * Named ESM export. PURE module — NO DOM / engine / Runtime / Bus import (C8). It
9
8
  * is host-neutral and node-testable: hosts (the notebook-pane in-app) import this
@@ -52,7 +51,7 @@
52
51
  * caller never ships a builder that 404s the relative import downstream.
53
52
  *
54
53
  * ── C14: the module import is DYNAMIC and runs AFTER ensureEngine (ordering
55
- * guarantee, WS gym-controls-as-sugar Bite 0a REMEDIATION, Finding 2) ─────────
54
+ * guarantee, REMEDIATION, Finding 2) ───────────────────────────────────────────
56
55
  *
57
56
  * A canonical setup factory's browser-classic export branch captures window.*
58
57
  * game-layer globals (LargeObject, SlitScreen, PointSource, …) into closure vars
@@ -250,7 +249,7 @@ export function parseSeed(seed) {
250
249
  * @param {boolean} [decl.render3d] — the cell's display declaration: a factory canvas's runner is
251
250
  * built 3D (`is3D: true`); a recipe canvas states 3D itself (`exp.createScene`).
252
251
  * @param {string|number} [decl.seed] — runner RNG seed (C4); empty → FrqtlApp default.
253
- * @param {Object<string,number|string>} [decl.renderOptions] — WS gym-controls-as-sugar
252
+ * @param {Object<string,number|string>} [decl.renderOptions] — gym-controls-as-sugar
254
253
  * fix-loop #6 Finding B: render-INTENT key/value pairs applied via
255
254
  * `runner.setRenderOption(key, value)` calls, ONE per key, emitted AFTER
256
255
  * `runner.setup(...)` — mirroring the proven page-side order
@@ -258,12 +257,12 @@ export function parseSeed(seed) {
258
257
  * A SEPARATE channel from `decl.opts` (never merged — `opts` are physics-factory
259
258
  * arguments; `renderOptions` are renderer-property-bag writes). `{}` → no calls
260
259
  * emitted (byte-identical to a canvas with no `renderOptions` attr).
261
- * @param {string} [decl.cameraPreset] — WS gym-controls-as-sugar fix-loop #6 Finding B:
260
+ * @param {string} [decl.cameraPreset] — gym-controls-as-sugar fix-loop #6 Finding B:
262
261
  * a named camera-orbit preset applied via the CAPABILITY-CHECKED
263
262
  * `runner.cameraControl && runner.cameraControl.setPreset(name)` (skipped when the active
264
263
  * renderer has no camera control — the page-side `if (cam) { cam.setPreset(...) }` idiom;
265
264
  * a camera that does not offer the preset THROWS). Empty/absent → no call emitted.
266
- * @param {string} [decl.shape] — the setup-form discriminator (Bite 5c): `'factory'`
265
+ * @param {string} [decl.shape] — the setup-form discriminator: `'factory'`
267
266
  * (DEFAULT when empty/absent) or `'recipe'`. Any OTHER value → FAIL-LOUD (never a
268
267
  * silent fallback). See the two-form note below.
269
268
  * @param {string} [decl.outName] — realm-internal output name; default `'_run'`.
@@ -273,7 +272,7 @@ export function parseSeed(seed) {
273
272
  * @throws {Error} FAIL-LOUD on a missing module / unknown export / zero-or-multiple
274
273
  * exports with no `#export` / malformed stage|seed / an unknown `shape`.
275
274
  *
276
- * ── Two setup forms — the `shape` discriminator (Bite 5c) ─────────────────────
275
+ * ── Two setup forms — the `shape` discriminator ───────────────────────────────
277
276
  *
278
277
  * A declared canvas's `setup` module takes ONE of two shapes; the CELL_ATTR `shape`
279
278
  * (owner: lib/shim/notebook/format.js) declares which, and this authority synthesizes
@@ -309,9 +308,7 @@ export function parseSeed(seed) {
309
308
  * the owner anyway. `RecipeContext` used to return null instead — that null reached
310
309
  * `exp.build` as an opaque property-access TypeError, which is what #73 reported.
311
310
  *
312
- * ── C15: the caller MUST force the runtime's cell-as-module path (WS
313
- * gym-controls-as-sugar Bite 0a fix-loop #3 — tester regression finding
314
- * 2026-07-03) ──────────────────────────────────────────────────────────────
311
+ * ── C15: the caller MUST force the runtime's cell-as-module path ────────────
315
312
  *
316
313
  * `Runtime.runCell` decides JS-vs-module-blob routing by SNIFFING the cell body
317
314
  * for a STATIC top-level `import` (`lib/shim/notebook/module-resolver.js`
@@ -345,7 +342,7 @@ export function parseSeed(seed) {
345
342
  */
346
343
  export function synthesizeBuilderSource(decl) {
347
344
  decl = decl || {};
348
- // Bite 5c: the setup-form discriminator. Empty/absent → 'factory' (the pre-existing
345
+ // The setup-form discriminator. Empty/absent → 'factory' (the pre-existing
349
346
  // gallery form, byte-identical). 'recipe' → RecipeContext/buildExperiment. Any other
350
347
  // value FAILS LOUD — never a silent guess.
351
348
  var shape = (decl.shape == null || decl.shape === '') ? 'factory' : String(decl.shape).trim();
@@ -389,7 +386,7 @@ export function synthesizeBuilderSource(decl) {
389
386
  var factoryCfgParts = decl.render3d ? cfgParts.concat(['is3D: true']) : cfgParts;
390
387
  var cfgLiteral = '{ ' + factoryCfgParts.join(', ') + ' }';
391
388
 
392
- // WS gym-controls-as-sugar fix-loop #6 Finding B: render-INTENT lines, emitted
389
+ // gym-controls-as-sugar fix-loop #6 Finding B: render-INTENT lines, emitted
393
390
  // AFTER runner.setup() (mirrors the proven page-side order in fx-experiment.js:
394
391
  // setup() → setRenderOption(renderDefaults) → cameraControl.setPreset()). Each
395
392
  // `renderOptions` key becomes its OWN `runner.setRenderOption('<k>', <v>);` call
@@ -419,7 +416,7 @@ export function synthesizeBuilderSource(decl) {
419
416
  // The canonical template (the §0 builder shape). Both shapes:
420
417
  // - boot the engine FIRST (ensureEngine),
421
418
  // - THEN dynamically import the editable in-notebook module by name (C1) — WS
422
- // gym-controls-as-sugar Bite 0a REMEDIATION, Finding 2: a canonical setup
419
+ // REMEDIATION, Finding 2: a canonical setup
423
420
  // factory's browser-classic branch captures window.* game-layer globals
424
421
  // (LargeObject, SlitScreen, …) into closure vars AT MODULE-EVALUATION TIME. A
425
422
  // STATIC top-level `import` of the module cell is resolved+evaluated as part
@@ -1,7 +1,7 @@
1
1
  // Copyright 2023-2026 by Essam Abadir
2
2
  // lib/shim/notebook/vendor-importmap.js — the ONE pure import-map generator.
3
3
  //
4
- // WS-NOTEBOOK-VENDOR Phase 2a (§2a.3). Maps the committed vendor manifest
4
+ // Phase 2a (§2a.3). Maps the committed vendor manifest
5
5
  // (lib/frqtl/assets/vendor/manifest.json) → a browser `<script type="importmap">`
6
6
  // payload `{ imports: { <spec>: <url> } }`, so a realm cell's builder/view module
7
7
  // can `import * as d3 from 'd3'` and the realm's native module loader resolves the
@@ -2,7 +2,7 @@
2
2
 
3
3
  /**
4
4
  * view-builder — the SOLE authority that synthesizes the canonical VIEW-ENTRY source
5
- * from a `view` cell's declarative configuration (WS-NOTEBOOK-VENDOR-VIEW Phase 2b).
5
+ * from a `view` cell's declarative configuration.
6
6
  *
7
7
  * Named ESM export. PURE module — NO DOM / engine / Runtime / Bus import. It is
8
8
  * host-neutral and node-testable: hosts (the notebook-pane in-app) import this one
@@ -2,7 +2,7 @@
2
2
 
3
3
  /**
4
4
  * view-ctx — the SOLE authority that assembles the `view` cell CONTEXT object handed
5
- * to a user render module's export (WS-NOTEBOOK-VENDOR-VIEW Phase 2b).
5
+ * to a user render module's export.
6
6
  *
7
7
  * Named ESM export. PURE module — NO DOM / engine / Runtime / Bus import. It is a
8
8
  * THIN convenience WRAPPER over the EXISTING frozen ViewHandle + the realm→kernel
@@ -2,7 +2,7 @@
2
2
 
3
3
  /**
4
4
  * warmup — the PURE warm-up-before-derive helper for the realm→kernel binding seam
5
- * (WS-NOTEBOOK-BASELINE FIX B). NO DOM / engine / Runtime / Bus import, so a test
5
+ * NO DOM / engine / Runtime / Bus import, so a test
6
6
  * exercises it with a fake handle WITHOUT a browser.
7
7
  *
8
8
  * THE PROBLEM IT SOLVES: a DECLARED canvas that `produces` a binding mounts its
@@ -24,7 +24,7 @@
24
24
  * `produceAfter` (a malformed authored attr) FAILS LOUD here — never silently
25
25
  * clamped-to-zero, which would re-introduce the empty-histogram bug under a typo.
26
26
  *
27
- * FOLLOW-UP (CEO interactive review): the live `on('tick')` same-cell chart and
27
+ * FOLLOW-UP (interactive review): the live `on('tick')` same-cell chart and
28
28
  * arbitrary-import path supersede this static one-shot warmup. This module is the
29
29
  * baseline only.
30
30
  */
@@ -2,9 +2,8 @@
2
2
 
3
3
  /**
4
4
  * lib/shim/page-params — the URL-param routing-table contract for canonical
5
- * experiment pages (WS gym-controls-as-sugar Bite 3 item 0 — "the CEO ruled the
6
- * param contract gets designed properly now and built WITH Bite 3", FINAL
7
- * design circulated + converged).
5
+ * experiment pages (gym-controls-as-sugar item 0 — the param contract designed
6
+ * properly and built with the controls).
8
7
  *
9
8
  * Peer of `lib/shim/frame-data`, `lib/shim/expr/ast-schema`, `lib/shim/controls` —
10
9
  * same layout convention: a closed vocabulary exported as named ES-module exports,
@@ -18,8 +17,8 @@
18
17
  * - `lib/frqtl/experiments/_shared/boot.js` reads `renderer`, `engine` and the
19
18
  * HOST-COMPOSITION token `chrome`.
20
19
  *
21
- * A `reader` need not be a `_shared` boot file: `stepping` (ws-walk-unification
22
- * Bite 1) is read by ONE experiment page's own inline sketch, because it is a
20
+ * A `reader` need not be a `_shared` boot file: `stepping`
21
+ * is read by ONE experiment page's own inline sketch, because it is a
23
22
  * per-universe PHYSICS option that page ferries into its own `universe.init()`
24
23
  * — the registry's job is that the KEY NAME has exactly one owner, wherever the
25
24
  * single reader lives (see that entry's own note for the hoist rule when a
@@ -43,7 +42,7 @@
43
42
  * read exactly once, at page boot, from the URL. There is deliberately NO
44
43
  * `normalize()` here — the tables are frozen static data, not runtime input to
45
44
  * validate. The two contracts are ADJACENT (both are consumed by the same
46
- * experiment pages, and Bite-3's controls-panel work will touch both) but are
45
+ * experiment pages, and the controls-panel work touches both) but are
47
46
  * NEVER unified into one schema/kind-union.
48
47
  *
49
48
  * Usage:
@@ -98,7 +97,7 @@ var PAGE_PARAMS = Object.freeze([
98
97
  key: KEYS.STEPPING,
99
98
  reader: 'lib/frqtl/experiments/single-source-interference/index.html',
100
99
  forward: true
101
- // ws-walk-unification Bite 1 (architect circulation ruling §2). `stepping`
100
+ // Circulation §2: `stepping`
102
101
  // selects the WAVE-WALK STEPPING SAMPLER for one universe —
103
102
  // 'fixed' (deterministic error-accumulator walk, the engine's serde default)
104
103
  // vs 'average' (the historic per-axis Bernoulli walk). It is a PER-UNIVERSE
@@ -155,14 +154,14 @@ var PAGE_PARAMS = Object.freeze([
155
154
  * rule (read them side by side — this is not "some hosts hide chrome,
156
155
  * others don't" as a per-host preference; it is one test with two different
157
156
  * answers):
158
- * - The GYM (`CompareView.jsx`, WS gym-controls-as-sugar Bite 2 ruling):
157
+ * - The GYM (`CompareView.jsx`):
159
158
  * OMITS `chrome=` entirely (full chrome renders in-iframe). The GYM's own
160
159
  * host chrome is deliberately minimal (Run/Pause/camera/rates only) — it
161
160
  * does NOT replicate the physics-parametric controls (temperature,
162
161
  * wavelength, density sweeps, …) every experiment declares, so hiding the
163
162
  * experiment's own chrome would strictly REMOVE capability from the GYM
164
163
  * user with no host-side equivalent to fall back on.
165
- * - Studio (`AuthorView.jsx`, Bite 4 "Studio adoption"): SETS
164
+ * - Studio (`AuthorView.jsx`, "Studio adoption"): SETS
166
165
  * `chrome=canvas`. Studio's own chrome already replicates-or-supersets
167
166
  * the experiment's control surface for its purposes: a Design/Run/Pause
168
167
  * topbar, an Effects palette (backdrop/water toggles), and a fully
@@ -16,7 +16,7 @@
16
16
  * re-enumerate its keys — it walks every string leaf for placeholder text. With `{ table: false }`
17
17
  * a table paragraph is refused outright.
18
18
  *
19
- * What a caption SAYS is the CEO's pass, never a gate here: this module checks shape only.
19
+ * What a caption SAYS is an editorial pass, never a gate here: this module checks shape only.
20
20
  *
21
21
  * @module copy-gate
22
22
  */
@@ -5,8 +5,8 @@
5
5
  * roster scene the GYM plays, and the showcase copy around them (the intro card, the through-line
6
6
  * and the one invitation). It is the ONE owner of every word of that copy.
7
7
  *
8
- * EXHIBITS is the ONE source for the front-page tiles, their GYM deep links and the scene card
9
- * (CEO 2026-10-03): nine rows in front-page order, each
8
+ * EXHIBITS is the ONE source for the front-page tiles, their GYM deep links and the scene card:
9
+ * nine rows in front-page order, each
10
10
  * `{ kind, id, mode, title, tile, what, why, how, controls, still }`.
11
11
  * - `kind` is 'rung' (a walk-through rung, lib/shim/registry/walkthrough.js) or 'experiment'
12
12
  * (a canonical experiment page, lib/shim/registry/experiments.js); `id` resolves there.
@@ -160,8 +160,8 @@ export const SHOWCASE_INTRO = Object.freeze({
160
160
  assertShowcaseIntro(SHOWCASE_INTRO);
161
161
 
162
162
  // The authored roster, front-page order. `title` and `tile` are the published front-page tile copy
163
- // (egpt-frqtl site/index.html #proof at 5d2f019: each tile's <b> and its sentence), verbatim;
164
- // `what`, `why`, `how`, `controls` and each `still.alt` are the CEO-passed captions.
163
+ // (the egpt-frqtl front page's #proof tiles: each tile's <b> and its sentence), verbatim;
164
+ // `what`, `why`, `how`, `controls` and each `still.alt` are the authored captions.
165
165
  const ROSTER = [
166
166
  {
167
167
  kind: 'rung', id: "dse-tunnel-rebuild", mode: "3d",
@@ -11,7 +11,7 @@
11
11
  * cat : category label
12
12
  * jsOnly : true if the experiment requires JS-engine-only APIs
13
13
  *
14
- * Ordering (G1 — WS-IMPOSSIBLE-GALLERY):
14
+ * Ordering (G1):
15
15
  * Experiments listed in the exhibit manifest appear FIRST, in manifest order.
16
16
  * Remaining experiments follow in their original declaration order.
17
17
  * This ordering is consumed by SimPane's dropdown via the existing prop path
@@ -41,7 +41,7 @@
41
41
  * the named infra ids: a dev-tier page is absent from the npm/CDN package, but
42
42
  * present in the GYM (both the dev IDE and the shipped static deploy).
43
43
  *
44
- * ── The public set is the NEW-SUGAR content ONLY (CEO 2026-07-27) ────────────
44
+ * ── The public set is the NEW-SUGAR content ONLY ─────────────────────────────
45
45
  * EVERY row below is `tier:'dev'`: none of these pages has been rebuilt on the
46
46
  * current sugar objects (SphereEmitter / v2 `Wall` / `Tunnel` / LiveChart /
47
47
  * GraphingDetectorWall), so none is public and none ships. The PUBLIC gallery
@@ -71,7 +71,7 @@ export const EXPERIMENT_TIERS = Object.freeze({
71
71
  * labs is for. Omit `tier` for a public experiment.
72
72
  * wasmOnly: 3D experiment; the JS reference is a frozen 2D fixture, so Compare runs
73
73
  * WASM-only (JS-reference pane disabled). See CompareView filter.
74
- * is3D : the ONE mount-time 3D-render authority (E-W0a, CEO 2026-07-23). TRUE iff
74
+ * is3D : the ONE mount-time 3D-render authority (E-W0a). TRUE iff
75
75
  * the experiment page unconditionally boots a 3D display — its runner is
76
76
  * `new FrqtlApp({ is3D: true, … })` on the three display — the ground-truth
77
77
  * signal, NOT wasmOnly (orthogonal: collision-matrix is wasmOnly+2D). STUDIO