@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
@@ -2,14 +2,14 @@
2
2
 
3
3
  /**
4
4
  * controlAction.js — OBJECTS-SIDE execution for an `action` control descriptor
5
- * (presentation pass Item 2, CEO-ratified E-P2a/E-P2b). The sibling of
5
+ * (presentation pass Item 2, E-P2a/E-P2b). The sibling of
6
6
  * `controlBind.js`, same home, same FAIL-LOUD style.
7
7
  *
8
8
  * ── Layer 1: API contract ────────────────────────────────────────────────────
9
9
  *
10
10
  * `resolveAction(action, ctx)` → `{ run() }`.
11
11
  *
12
- * Arrow ruling (mirrors the ratified bind split EXACTLY): `lib/shim/controls`
12
+ * Arrow rule (mirrors the ratified bind split EXACTLY): `lib/shim/controls`
13
13
  * owns the NAME VOCABULARY (`ControlsSchema.ACTIONS` — the data shape);
14
14
  * EXECUTION — mapping a name to a live `FrqtlApp` method and calling it
15
15
  * — is OBJECTS-SIDE and lives here, beside the panel/overlay/sync sugar that
@@ -2,14 +2,14 @@
2
2
 
3
3
  /**
4
4
  * controlBind.js — OBJECTS-SIDE execution for a scalar control descriptor's
5
- * `bind: {object, prop}` (WS gym-controls-as-sugar, FULL CONVERGENCE build,
5
+ * `bind: {object, prop}` (gym-controls-as-sugar, FULL CONVERGENCE build,
6
6
  * Stage i item 2).
7
7
  *
8
8
  * ── Layer 1: API contract ────────────────────────────────────────────────────
9
9
  *
10
10
  * `resolveBind(bind, ctx, channel)` → `{ set(value), get() }`.
11
11
  *
12
- * Arrow ruling (§5 converged): `lib/shim/controls` owns the `bind` DATA SHAPE
12
+ * Arrow rule (§5 converged): `lib/shim/controls` owns the `bind` DATA SHAPE
13
13
  * only (`{object, prop}`, both non-empty strings — `ControlsSchema.BIND_KEYS`).
14
14
  * EXECUTION — resolving `bind.object` to a live handle, dispatching by
15
15
  * `channel`/object-kind, and routing through the real property accessors — is
@@ -18,7 +18,7 @@
18
18
  * This is a HOST TICK-FN COMPONENT in the SAME sense as `emitterProgram.js` — an
19
19
  * engine-agnostic function composed entirely from generic primitives
20
20
  * (`universe.random()`, `universe.setFrameProperty()`), NOT a native op-program (the
21
- * op-vocabulary's `FN_NAMES` has no `cos`/`sin` — theorist-established FN_NAMES gap,
21
+ * op-vocabulary's `FN_NAMES` has no `cos`/`sin` — an established FN_NAMES gap,
22
22
  * report §2(b)). UNLIKE `emitterProgram.js` (which registers itself onto
23
23
  * `universe.experimentTickFunctions` and runs during Phase A, BEFORE that tick's own
24
24
  * collision/collect), this component must run AFTER `doTick()` returns — it needs
@@ -44,7 +44,7 @@
44
44
  * `[angleRad-spreadRad, angleRad+spreadRad]`. `0` (default) = fully directed,
45
45
  * zero spread (every redirected frame gets the EXACT same angle) — byte-identical
46
46
  * opt-out for a pure-directed beam.
47
- * @param {number} [spec.polarSpreadRad=0] - 3D EXTENSION (ws-dse-3d, theorist §4
47
+ * @param {number} [spec.polarSpreadRad=0] - 3D EXTENSION (§4
48
48
  * option (c) — "extend the redirect to draw a direction on the unit SPHERE,
49
49
  * azimuth + polar"): an independent isotropic-spread draw for the POLAR angle
50
50
  * (elevation out of the XY plane), `phi = (random()*2-1)*polarSpreadRad`. `0`
@@ -92,7 +92,7 @@
92
92
  var speed = (fixedSpeed !== null)
93
93
  ? fixedSpeed
94
94
  : (Math.sqrt(fd.vx * fd.vx + fd.vy * fd.vy) || 1);
95
- // 3D EXTENSION (ws-dse-3d): phi (polar, elevation out of the XY
95
+ // 3D EXTENSION: phi (polar, elevation out of the XY
96
96
  // plane) draws ONLY when polarSpreadRad is non-zero — otherwise
97
97
  // phi stays exactly 0, making this byte-identical to the pre-3D
98
98
  // 2-axis formula (cos(0)=1 -> vx=cos(theta)*speed,
@@ -8,7 +8,7 @@
8
8
  * `universe.random()`, `universe.makeLeafFrame(...)`, and `universe.injectFrame(...)`. Both engines
9
9
  * (WASM canonical + the JS reference) expose those primitives identically, so this ONE function is
10
10
  * the single source of emit behavior — replacing the former dual per-engine `registerEmitter`
11
- * implementations (compat/providers + EGPTfrqtl.js).
11
+ * implementations (compat/providers + the JS reference engine).
12
12
  *
13
13
  * DRAW-ORDER CONTRACT (golden-locked on WASM — do not reorder):
14
14
  * per emitted leaf: random()→x, random()→y, [random()→angle if randomDirection],
@@ -17,7 +17,7 @@
17
17
  * makeLeafFrame draws 0 there (charge is passed in) — engines may diverge
18
18
  * (WASM is canonical); only the WASM goldens are asserted.
19
19
  *
20
- * OPT-IN 3D z-SPREAD (WS-DSE-3D Bite B0): `em.zMin`/`em.zDepth` default to `null` — when
20
+ * OPT-IN 3D z-SPREAD: `em.zMin`/`em.zDepth` default to `null` — when
21
21
  * both are absent, ZERO additional draws execute and this tick-fn is byte-identical to the
22
22
  * contract above (every existing 2D caller — QuantumEmitter, PointSource — is unaffected).
23
23
  * When a caller opts in (`em.zMin` a number), ONE additional `random()` draw executes AFTER
@@ -26,7 +26,7 @@
26
26
  * (a THIRD setFrameProperty call, never inserted into the locked x/y/[angle]/[charge] sequence).
27
27
  * `makeLeafFrame` has no z argument — no engine change, this composes existing primitives.
28
28
  *
29
- * OPT-IN 3D ISOTROPIC SCATTER (ws-dse-3d AC1, CEO drive #2 round-2 ruling): `em.zIsotropy`
29
+ * OPT-IN 3D ISOTROPIC SCATTER: `em.zIsotropy`
30
30
  * (default falsy) — when BOTH `em.randomDirection` AND `em.zIsotropy` are true, the
31
31
  * random-direction draw becomes a full unit-SPHERE direction (azimuth + polar angle,
32
32
  * TWO draws replacing the 2D branch's ONE) instead of a 2D-plane circle, and the drawn
@@ -39,7 +39,7 @@
39
39
  * directly for active / velocity / burst-size / source-rect changes — there is no provider
40
40
  * setEmitter* ABI. The tick-fn closes over emState so those mutations take effect live.
41
41
  *
42
- * DSE LAB (2026-07-13, CEO-chartered systematic controls): `em.everyNTicks` (opt-in,
42
+ * DSE LAB (systematic controls): `em.everyNTicks` (opt-in,
43
43
  * default null/undefined = fire every active tick, byte-identical to every existing
44
44
  * caller) throttles firing to once every N ticks — a LIVE, per-tick-read cadence knob
45
45
  * (mutate `em.everyNTicks` directly on the live emState any time; no re-init). This is
@@ -73,11 +73,11 @@
73
73
 
74
74
  var vx = em.vx;
75
75
  var vy = em.vy;
76
- var vzOut = null; // ws-dse-3d AC1: set only by the zIsotropy branch below
76
+ var vzOut = null; // set only by the zIsotropy branch below
77
77
  if (em.randomDirection) {
78
78
  if (em.zIsotropy) {
79
- // ws-dse-3d AC1 ("velocity z-symmetry consistent with its
80
- // profile"): a real-depth-armed ISOTROPIC point source scatters
79
+ // Velocity z-symmetry consistent with its
80
+ // profile: a real-depth-armed ISOTROPIC point source scatters
81
81
  // on the unit SPHERE (azimuth + polar), not just the XY plane —
82
82
  // mirrors directedRedirectProgram.js's own polarSpreadRad>0
83
83
  // sphere draw. OPT-IN (em.zIsotropy defaults false) — zero extra
@@ -136,8 +136,8 @@
136
136
 
137
137
  // OPT-IN 3D z-SPREAD (see module docstring). em.zMin is null for every
138
138
  // existing 2D caller — this branch is dead code (0 extra draws) unless a
139
- // caller explicitly opts in (PointSource `opts.zMin`/`opts.zDepth`, WS-DSE-3D).
140
- // ws-dse-3d AC1: shares the SAME qid lookup with the zIsotropy vz write
139
+ // caller explicitly opts in (PointSource `opts.zMin`/`opts.zDepth`).
140
+ // Shares the SAME qid lookup with the zIsotropy vz write
141
141
  // below (never a second getFrameQuantumId call for the same handle).
142
142
  var zMinArmed = (em.zMin !== null && em.zMin !== undefined);
143
143
  if (zMinArmed || vzOut !== null) {
@@ -2,7 +2,7 @@
2
2
 
3
3
  /**
4
4
  * frqtl-control-slider.js — the SINGLE scalar-control widget
5
- * (WS gym-controls-as-sugar Bite 3 Stage 2, Layer B).
5
+ * (gym-controls-as-sugar, Layer B).
6
6
  *
7
7
  * ── Layer 1: API contract ────────────────────────────────────────────────────
8
8
  *
@@ -74,7 +74,7 @@
74
74
  * value on drag; its (possibly-Promised) return refreshes the displayed
75
75
  * value/text.
76
76
  * @returns {{dispose: () => void, setValue: (value:number, valueText?:string) => void}}
77
- * `setValue` (WS gym-controls-as-sugar FULL CONVERGENCE build, Stage ii item 5
77
+ * `setValue` (gym-controls-as-sugar FULL CONVERGENCE build, Stage ii item 5
78
78
  * — the `ControlSync` reconciliation target) is DISPLAY-ONLY: it writes the
79
79
  * slider's `.value` DOM property and the value label directly and NEVER
80
80
  * fires `onInput`/`onChange` (setting an `<input>`'s `.value` property does
@@ -103,7 +103,7 @@ function mount(hostEl, opts) {
103
103
  // execute — this file deliberately has zero dependency on registries/
104
104
  // controlBind.js (Layer B: "the widget knows nothing about transports").
105
105
  // Dragging it would otherwise silently do nothing (the exact class of
106
- // bug WS gym-controls-as-sugar FULL CONVERGENCE fixed in the panel).
106
+ // bug the gym-controls-as-sugar FULL CONVERGENCE build fixed in the panel).
107
107
  // Route a bind-only descriptor through frqtl-controls-panel.js instead
108
108
  // (mode:'in-app'/'iframe', which DOES resolve bind execution), or mount
109
109
  // this widget via the opts.initial/onInput decoupled path with onInput
@@ -2,7 +2,7 @@
2
2
 
3
3
  /**
4
4
  * frqtl-control-sync.js — TRIGGERED-PULL reconciliation across N widgets
5
- * driving the SAME declared-once control (WS gym-controls-as-sugar FULL
5
+ * driving the SAME declared-once control (gym-controls-as-sugar FULL
6
6
  * CONVERGENCE build, Stage ii item 4).
7
7
  *
8
8
  * ── Layer 1: API contract ────────────────────────────────────────────────────
@@ -10,14 +10,14 @@
10
10
  * `makeControlSync(opts) → { register(id, widget)->unregisterFn, pull()->Promise,
11
11
  * notify(trigger), dispose() }`.
12
12
  *
13
- * The North Star (§5 CEO design constraint) is STUDIO live drive-and-placement
13
+ * The North Star (§5 design constraint) is STUDIO live drive-and-placement
14
14
  * — multiple users/widgets "batting a sun around" the SAME control. A single
15
15
  * widget mutating a value is NOT reconciliation; N widgets (a page slider, a
16
16
  * panel row, a standalone widget, a REMOTE panel over an iframe) must all
17
17
  * REFLECT the SAME canonical state after ANY of them writes. `ControlSync`
18
18
  * is the PULL side of that: it periodically (per its configured `trigger`)
19
19
  * re-reads every registered control's CURRENT value (via the existing
20
- * `listControls` verb — Bite-3 RPC, reused unmodified: `frqtl-controls-panel.js`'s
20
+ * `listControls` verb — the RPC, reused unmodified: `frqtl-controls-panel.js`'s
21
21
  * `listControls` now refreshes bind-based descriptors from LIVE state before
22
22
  * serializing, see that file's own docstring) and calls `widget.setValue(value,
23
23
  * valueText)` on every OTHER registered widget for that control id — a
@@ -48,7 +48,7 @@
48
48
  *
49
49
  * A configured `trigger:'tick'`/`'pause'` that never receives its matching
50
50
  * `notify()` call within `opts.devWarnMs` (default 3000ms) logs ONE
51
- * `console.warn` (architect's DEV-WARN — the page forgot its one-line wiring;
51
+ * `console.warn` (DEV-WARN — the page forgot its one-line wiring;
52
52
  * this is a development aid, never a thrown error — a sync with a forgotten
53
53
  * trigger is inert, not broken).
54
54
  *
@@ -60,15 +60,15 @@
60
60
  * responder already share (DRY: a THIRD consumer of one implementation, not
61
61
  * a re-derived listing).
62
62
  *
63
- * `opts.handle` (remote, over an iframe/postMessage — "the EXISTING Bite-3
64
- * RPC"): pulls via `handle.call('listControls', [name])` — the identical RPC
63
+ * `opts.handle` (remote, over an iframe/postMessage — the EXISTING
64
+ * RPC): pulls via `handle.call('listControls', [name])` — the identical RPC
65
65
  * primitive `frqtl-controls-panel.js`'s `mount({mode:'iframe'})` already
66
66
  * builds via `lib/shim/rpc`. `ControlSync` does not care which — both
67
67
  * resolve to a `Promise<Array<{id,label,min,max,step,value,valueText}>>`.
68
68
  *
69
69
  * Exactly one of `opts.registry` / `opts.handle` is required.
70
70
  *
71
- * ── CEO performance constraints (build requirements, not suggestions) ────────
71
+ * ── Performance constraints (build requirements, not suggestions) ────────────
72
72
  *
73
73
  * - rAF-coalesced: `notify()` schedules AT MOST one pending pull per
74
74
  * animation frame, however many times it is called within that frame.
@@ -203,7 +203,7 @@ function makeControlSync(opts) {
203
203
  var arr = widgetsById[d.id];
204
204
  if (!arr || !arr.length) { return; } // no widget registered for this id — nothing to reconcile
205
205
  // Skip-if-unchanged: ONE comparison per control id, shared across
206
- // every widget registered under it (CEO performance constraint).
206
+ // every widget registered under it (performance constraint).
207
207
  if (lastValueById[d.id] === d.value) { return; }
208
208
  lastValueById[d.id] = d.value;
209
209
  arr.forEach(function (w) { w.setValue(d.value, d.valueText); });
@@ -211,7 +211,7 @@ function makeControlSync(opts) {
211
211
  });
212
212
  }
213
213
 
214
- // ── DEV-WARN (architect's ruling): a configured tick/pause trigger that
214
+ // ── DEV-WARN: a configured tick/pause trigger that
215
215
  // never receives its matching notify() within the grace window means the
216
216
  // page forgot its one-line wiring. Cleared the FIRST time notify() fires
217
217
  // for the configured trigger (even a single call proves it's wired).
@@ -25,7 +25,7 @@
25
25
  * `slider` hands straight to `frqtl-control-slider.js` — the ONE slider-rendering
26
26
  * implementation, unchanged. This table adds only the widgets that did not exist:
27
27
  * toggle/checkbox (a scalar 0/1 rendered as a switch — NOT a new kind, per the
28
- * schema's standing ruling), text (the string kind), and button (the action kind).
28
+ * schema's rule), text (the string kind), and button (the action kind).
29
29
  * `frqtl-controls-panel.js`'s renderRows consults THIS table instead of hardcoding
30
30
  * the slider, so a second resolution authority never comes into existence.
31
31
  *
@@ -97,7 +97,7 @@ function _settle(promiseLike, onValue, onError) {
97
97
  });
98
98
  }
99
99
 
100
- /** A checkbox over a SCALAR 0/1 (the schema's "a toggle IS a scalar" ruling). */
100
+ /** A checkbox over a SCALAR 0/1 (the schema's "a toggle IS a scalar" rule). */
101
101
  function _mountToggle(hostEl, initial, onInput, styleAsSwitch) {
102
102
  var row = _row();
103
103
  var box = document.createElement('input');
@@ -2,7 +2,7 @@
2
2
 
3
3
  /**
4
4
  * frqtl-control-write-queue.js — the WRITE-side symmetric primitive to
5
- * `frqtl-control-sync.js`'s PULL-side coalescing (WS Studio Controls
5
+ * `frqtl-control-sync.js`'s PULL-side coalescing (Studio Controls
6
6
  * Realignment S4, design §2.3.4 — "add the symmetric primitive: an
7
7
  * rAF-coalesced, last-write-wins-per-frame-per-control-id write queue").
8
8
  *
@@ -39,7 +39,7 @@
39
39
  * from a per-page opt-in" reasoning as those four siblings (see the
40
40
  * manifest's own comment block for the S3 precedent).
41
41
  *
42
- * ── FAIL-LOUD condition (architect, non-negotiable) ─────────────────────────
42
+ * ── FAIL-LOUD condition (non-negotiable) ────────────────────────────────────
43
43
  *
44
44
  * A throwing accessor write mid-drag MUST PROPAGATE — never be silently
45
45
  * swallowed under last-write-wins coalescing. `flush()`/`flushSync()` below
@@ -1,8 +1,8 @@
1
1
  /* Copyright 2023-2026 by Essam Abadir */
2
2
 
3
3
  /**
4
- * makeControlsForObject.js — the schema→controls FACTORY (WS Studio Controls
5
- * Realignment, Bite S2, "the factory spine").
4
+ * makeControlsForObject.js — the schema→controls FACTORY (Studio Controls
5
+ * Realignment S2, "the factory spine").
6
6
  *
7
7
  * ── Layer 1: API contract ────────────────────────────────────────────────────
8
8
  *
@@ -17,7 +17,7 @@
17
17
  * sibling) — this factory NEVER synthesizes an `onChange` closure (see the
18
18
  * "no-onChange-synthesis" scope note below; it is a hard constraint, not an
19
19
  * oversight, and it is WHY several field types below are DISPLAY-ONLY rather
20
- * than live controls in this bite).
20
+ * than live controls).
21
21
  *
22
22
  * @param {*} wrapper — the live object to introspect:
23
23
  * - LargeObject/QuantumEmitter/PointSource/DetectorWall/SlitScreen/Box/OvenBox/
@@ -88,8 +88,7 @@
88
88
  * dependency. DEPENDENCY INJECTION (accepting `normalizeControlDescriptor` via
89
89
  * `ctx`/`opts` instead of importing it) was the escape hatch IF `verify-arrows`
90
90
  * rejected the import — it did not, so this file imports directly, same as its
91
- * schema/index.js precedent. (`make verify` run confirms — see the Bite S2
92
- * build report.)
91
+ * schema/index.js precedent.
93
92
  *
94
93
  * ── Layer 2: physics behavior ────────────────────────────────────────────────
95
94
  *
@@ -100,13 +99,13 @@
100
99
  * factory-generated control produces the IDENTICAL effect as hand-writing the
101
100
  * same `{kind, id, bind}` literal.
102
101
  *
103
- * ── Scope decisions this bite makes explicit (read before extending) ────────
102
+ * ── Scope decisions made explicit here (read before extending) ──────────────
104
103
  *
105
104
  * 1. NO onChange synthesis (dispatch constraint) — every live control's write
106
105
  * path is `bind:{object, prop}` ONLY. This is SAFE for every numeric field
107
106
  * (JSON/WASM round-trips a JS number losslessly either way) and safe for
108
107
  * every STRING-valued enum/flags field (see #2) — but it is UNSAFE for two
109
- * field shapes, which are therefore DISPLAY-ONLY in this bite, not scalar/
108
+ * field shapes, which are therefore DISPLAY-ONLY, not scalar/
110
109
  * enum live controls (documented per-branch below, not silently degraded):
111
110
  * (a) a `boolean`-typed field with `engineVisible !== false` — its value
112
111
  * reaches the engine ABI via `setFrameProperty`'s
@@ -131,7 +130,7 @@
131
130
  * back through a bare bind would write `'NONE'` into a field the
132
131
  * engine expects as the NUMBER `0`. Needs either an onChange
133
132
  * translator (forbidden here) or a `resolveBind`-side value-mapping
134
- * extension — an architect decision, not a factory guess.
133
+ * extension — a design decision, not a factory guess.
135
134
  * Both are named, tested exceptions — NOT a silent drop. See
136
135
  * `_booleanHandler`/`_enumHandler`/`_flagsHandler`/`_writableHandler` below.
137
136
  * 2. `rect-array` fields (`QuantumEmitter.source_rects`) become N DISPLAY
@@ -139,8 +138,7 @@
139
138
  * contract (`lib/shim/controls` `BIND_KEYS = ['object','prop']`) has no
140
139
  * array-index addressing; a correct per-entry live write needs either
141
140
  * `bind.index` (a shim-contract extension) or an onChange closure
142
- * (forbidden). Flagged per-entry in the `description` field, and in the
143
- * Bite S2 build report for S3/S4/architect follow-up.
141
+ * (forbidden). Flagged per-entry in the `description` field.
144
142
  * 3. `QuantumEmitter`/`PointSource`'s singular `rect` field has NO live getter
145
143
  * on the wrapper today (a PRE-EXISTING gap — `AuthorView.jsx`'s current
146
144
  * Inspector reads `obj['rect']` too and gets the identical `undefined`).
@@ -159,10 +157,9 @@
159
157
  * DO get live `enum`/`flags` controls here (their values are identity-mapped
160
158
  * strings, safe per #1's rule) — but per design §2.3.5, a live edit only
161
159
  * mutates the RENDER-layer JS wrapper mirror; it does NOT recompile/repush
162
- * the running op-program. That gap is CEO call #7's `recompile` write class,
160
+ * the running op-program. That gap is the `recompile` write class,
163
161
  * explicitly deferred to S4 — this factory does not attempt it.
164
- * 6. **Bind-executable-kind gate (S3, architect ruling `ruling_studio_controls_
165
- * s2_factory.md` watch-out #1 — MANDATORY, closes an S2-documented KNOWN
162
+ * 6. **Bind-executable-kind gate (S3 — MANDATORY, closes an S2-documented KNOWN
166
163
  * GAP).** `controlBind.js`'s `resolveBind` only EXECUTES a bind for a
167
164
  * registry-resolved kind in `{Frame, LargeObject, backdrop}`, plus the
168
165
  * `bind.object === 'universe'` sentinel (this factory's `kind === 'Universe'`)
@@ -193,11 +190,11 @@ import { ObjectSchema as _ObjectSchemaNode } from '../schema/index.js';
193
190
  import * as _ControlsSchemaNode from '../../../shim/controls/index.js';
194
191
 
195
192
 
196
- // ── Nullable-override sentinel (W0-D, CEO 2026-07-23) ───────────────────────────
193
+ // ── Nullable-override sentinel (W0-D) ───────────────────────────────────────────
197
194
  // A LIVE per-leaf render-intent OVERRIDE field (SphereEmitter.renderShape,
198
195
  // .renderColor) defaults to NULL — "no key, byte-identical, scheme-driven default"
199
196
  // (the SU1 guarantee: a non-null default would stamp every leaf and move a golden).
200
- // Its control must still be EDITABLE (the CEO's "renderShape/Color is not changeable
197
+ // Its control must still be EDITABLE (the "renderShape/Color is not changeable
201
198
  // in the Inspector" defect), so a null-valued live override renders a control seeded
202
199
  // with this reserved sentinel meaning "unset / scheme default". The consuming
203
200
  // Inspector maps the sentinel BACK to null on write (AuthorView commitField/
@@ -256,7 +253,7 @@ function _resolveBounds(field, value) {
256
253
  }
257
254
 
258
255
  function _label(field) {
259
- // An optional display `label` (Bite 5b) overrides the field NAME for the
256
+ // An optional display `label` overrides the field NAME for the
260
257
  // control's shown label WITHOUT renaming the schema field (the codegen/capture
261
258
  // key stays `field.name`). e.g. leafDimension → "Emit Dimension", the global
262
259
  // shape capability → "Default Shape". Absent → the name, as before (byte-identical).
@@ -287,7 +284,7 @@ var FIELD_VALUE_OVERRIDES = {
287
284
  return [w.x - d / 2, w.y - d / 2, d, d];
288
285
  }
289
286
  },
290
- // SphereEmitter (Bite 4b): `rect` is the WRITE-ONLY reposition adapter — its
287
+ // SphereEmitter: `rect` is the WRITE-ONLY reposition adapter — its
291
288
  // direct getter is undefined (so captureProps skips it; `center` is the captured
292
289
  // position authority). Seed the Inspector's live rect vector from `center` so the
293
290
  // field still shows/edits a position (edit → updateObjectProperty → setCenter).
@@ -395,7 +392,7 @@ function _enumHandler(field, env) {
395
392
  var keys = Object.keys(valuesObj);
396
393
  var value = _readValue(env, field.name);
397
394
  if (typeof value !== 'string' || keys.indexOf(value) === -1) {
398
- // W0-D (CEO 2026-07-23): a LIVE enum whose value is null/unset — the
395
+ // W0-D: a LIVE enum whose value is null/unset — the
399
396
  // SphereEmitter.renderShape override, kept null for byte-identity (SU1) — still
400
397
  // renders an EDITABLE control, seeded with the '(default)' sentinel option
401
398
  // representing "unset / scheme default". Picking a real key writes the string
@@ -447,7 +444,7 @@ function _flagsHandler(field, env) {
447
444
  // override is genuinely UNSET (scheme-driven fullness→ROYGBIV) until the user picks
448
445
  // a color, at which point setRenderColor stamps the chosen [r,g,b]. (A true
449
446
  // "return to unset" gesture needs a companion clear affordance — out of the minimal
450
- // scope; see the W0-D2 note in the deliverable.)
447
+ // scope.)
451
448
  var NULL_RGB_DEFAULT_SWATCH = [255, 255, 255];
452
449
 
453
450
  /**
@@ -470,7 +467,7 @@ function _rgbHandler(field, env) {
470
467
  var value = _readValue(env, field.name);
471
468
  var isValid = _isValidForField(field, value, env.kind);
472
469
  if (!isValid) {
473
- // W0-D2 (CEO 2026-07-23): a LIVE rgb override whose value is null/unset — the
470
+ // W0-D2: a LIVE rgb override whose value is null/unset — the
474
471
  // SphereEmitter.renderColor override, kept null for byte-identity (SU1) — still
475
472
  // renders an EDITABLE color control seeded with the neutral default swatch, so
476
473
  // the field is not a dead "–" in the Inspector. Picking a color writes [r,g,b]
@@ -646,13 +643,12 @@ function _demoteToDisplay(field, env, result) {
646
643
  ' (DISPLAY ONLY — kind "' + env.kind + '" is not in controlBind.js\'s bind-execution ' +
647
644
  'allowlist {Frame, LargeObject, backdrop, Universe}; resolveBind FAILS LOUD for any ' +
648
645
  'other kind rather than silently no-op through an accessor path that would not reach ' +
649
- 'this object\'s real state. Demoted per the S3 architect gate — see ' +
650
- '.claude/agent-memory/frqtl-architect/ruling_studio_controls_s2_factory.md watch-out #1.)'
646
+ 'this object\'s real state.)'
651
647
  }]
652
648
  };
653
649
  }
654
650
 
655
- // ── Conditional visibility (Collision LEXICON v2, architect §1b) ────────────────
651
+ // ── Conditional visibility (Collision LEXICON v2, §1b) ──────────────────────────
656
652
  //
657
653
  // ONE declarative `visibleWhen` predicate + ONE evaluator — the general substrate for a
658
654
  // field that shows only when a SIBLING field holds a value (bounceDirection only for a
@@ -743,7 +739,7 @@ function makeControlsForObject(wrapper, ctx, opts) {
743
739
  'explicit TYPE_DISPATCH entry in makeControlsForObject.js (even a documented display/skip). ' +
744
740
  '(FAIL-LOUD — never a silent drop.)');
745
741
  }
746
- // ── Explicit per-field LIVE attribute (Bite 4b) ──────────────────────
742
+ // ── Explicit per-field LIVE attribute ────────────────────────────────
747
743
  // `live:false` → a read-only DISPLAY row regardless of type (boot-level /
748
744
  // reload-to-change / derived fields — SphereEmitter's is2D, fundamentalDimension,
749
745
  // emissionBox, …). captureProps STILL captures the value; the Inspector just
@@ -766,7 +762,7 @@ function makeControlsForObject(wrapper, ctx, opts) {
766
762
  if (result.kind === 'control' && field.live !== true && BIND_EXECUTABLE_KINDS.indexOf(kind) === -1) {
767
763
  result = _demoteToDisplay(field, env, result);
768
764
  }
769
- // Pass `visibleWhen` THROUGH onto the emitted entry (architect §1b) — a live,
765
+ // Pass `visibleWhen` THROUGH onto the emitted entry (§1b) — a live,
770
766
  // sibling-dependent RENDER concern the Inspector evaluates at render time; NOT a
771
767
  // generation-time skip (unlike internal:true). Attached AFTER normalization so the
772
768
  // control descriptor's own contract is unchanged (normalize never sees it).
@@ -787,7 +783,7 @@ function makeControlsForObject(wrapper, ctx, opts) {
787
783
 
788
784
  var MakeControlsForObject = {
789
785
  makeControlsForObject: makeControlsForObject,
790
- // The ONE conditional-visibility evaluator (Collision LEXICON v2, architect §1b) —
786
+ // The ONE conditional-visibility evaluator (Collision LEXICON v2, §1b) —
791
787
  // the AuthorView Inspector filter calls THIS beside its existing internal-field drop,
792
788
  // never a hand-rolled per-field branch.
793
789
  evalVisibleWhen: evalVisibleWhen,
@@ -803,9 +799,9 @@ var MakeControlsForObject = {
803
799
  // SAME gate list this factory enforces, never a hand-copied duplicate —
804
800
  // see scope note #6 / BIND_EXECUTABLE_KINDS above.
805
801
  BIND_EXECUTABLE_KINDS: BIND_EXECUTABLE_KINDS,
806
- // ── Reuse seam for makeControlsForRenderSurface.js (WS Studio Controls ────
807
- // Realignment §7 r2, architect condition: "REUSES makeControlsForObject's
808
- // TYPE_DISPATCH — the big DRY win", NOT a third hand-parallel conversion).
802
+ // ── Reuse seam for makeControlsForRenderSurface.js (Studio Controls ───────
803
+ // Realignment §7 r2: REUSES makeControlsForObject's
804
+ // TYPE_DISPATCH — the big DRY win, NOT a third hand-parallel conversion).
809
805
  // Exposes ONLY the per-field-type handlers a renderCapabilities() descriptor
810
806
  // uses (`number`, `enum`, `boolean`, `string`) — deliberately NOT the full
811
807
  // TYPE_DISPATCH map: the rest bake in Frame/Universe-specific assumptions (the
@@ -2,7 +2,7 @@
2
2
 
3
3
  /**
4
4
  * makeControlsForRenderSurface.js — the RENDER-side factory twin of
5
- * `makeControlsForObject.js` (WS Studio Controls Realignment, Bite S5a).
5
+ * `makeControlsForObject.js` (Studio Controls Realignment S5a).
6
6
  *
7
7
  * ── Layer 1: API contract ────────────────────────────────────────────────────
8
8
  *
@@ -19,7 +19,7 @@
19
19
  *
20
20
  * Each renderCapabilities() entry is a `lib/shim/field-descriptor`-shaped
21
21
  * field descriptor (`{name, type, constraint, unit, default, description}` —
22
- * §7 r2 CEO call C1's shared vocabulary): `type:'number'` → a `scalar`
22
+ * §7 r2 C1's shared vocabulary): `type:'number'` → a `scalar`
23
23
  * control; `type:'enum'` → an `enum` control; a render-only `type:'boolean'`
24
24
  * → a 0/1 `scalar`; `type:'string'` (an OPEN-ID asset id) → no control. The
25
25
  * conversions REUSE `makeControlsForObject.js`'s OWN handlers (exposed as
@@ -4,8 +4,8 @@
4
4
  * slitLinerScatter.js — the ONE authority for the double-slit edge-diffraction
5
5
  * liner's collision op-program (behavior × resetLocalTime, ORTHOGONAL).
6
6
  *
7
- * DSE LAB (2026-07-13, CEO-chartered systematic controls): "behavior × reset are
8
- * ORTHOGONAL controls" — this file composes the velocity-tail (`behavior`) and the
7
+ * DSE LAB (systematic controls): behavior × reset are
8
+ * ORTHOGONAL controls — this file composes the velocity-tail (`behavior`) and the
9
9
  * `local_time=0` reset independently, so every (behavior, resetLocalTime) combo is
10
10
  * reachable, INCLUDING combos that had no name before (`bounce`+reset,
11
11
  * `ejectY`+reset, `ejectYReflect`+reset). The pre-existing compound `slitScatter`
@@ -21,10 +21,10 @@
21
21
  * ## Ground-truth (pkg-node instrumentation, EXPERIMENT LOOP delivery report)
22
22
  * The liner's compiled `RANDOM_XY` op DOES fire; its OWN writes are `vx=random()`
23
23
  * (ALWAYS non-negative) and `vy=random()*2-1` (already symmetric) — the sign bias
24
- * the CEO's original hypothesis named (vy) was actually in `vx`, which the engine's
24
+ * the original hypothesis named (vy) was actually in `vx`, which the engine's
25
25
  * 2D diagonal wave-kick (`frame.rs` `axy` branch, `dy_perp=(vx>0?+1:-1)*is_heads`)
26
26
  * keys its transverse-Y sign off; `is_heads` is coherently biased by the SAME
27
- * `local_time=0` phase-lock mechanism (`compute_spin`) the theorist found driving
27
+ * `local_time=0` phase-lock mechanism (`compute_spin`) found driving
28
28
  * the separately-escalated 3D z-asymmetry. `local_time=0` is deliberate — it is
29
29
  * what CREATES the y-interference fringes for the un-amended collision — hence
30
30
  * this file's variants for visual/statistical A/B comparison, not a "fix."
@@ -121,10 +121,8 @@ import { CollisionTypes } from '../../parts/CollisionTypes.js';
121
121
  * The `ejectY` NAME is historical (the DSE liner is a horizontal strip that always ejects
122
122
  * on Y); a vertical corridor (`Tunnel` axis 'y') passes 'left'/'right' through the SAME
123
123
  * builder. Documenting the true domain, not widening it — no code change.
124
- * @param {boolean} [hasRealDepth=false] - ws-dse-3d AC2 (CEO drive #2 round-2
125
- * ruling: "It is immediately obvious that the reflections on one of the
126
- * axes is missing... immediately obvious that we are not using the same
127
- * objects with the same contracts"): when true, `randomXY`/`symmetric`
124
+ * @param {boolean} [hasRealDepth=false] - (a real-depth tunnel scatters on
125
+ * all three axes, through the same objects and contracts): when true, `randomXY`/`symmetric`
128
126
  * (the two SCATTER behaviors — a wall-normal-agnostic velocity redraw, not
129
127
  * a physical y-wall reflection) ALSO append `set frame.vz = random()*2-1`
130
128
  * — the SAME `randomSigned()` term already used for `vy` — so a scatter
@@ -133,7 +131,7 @@ import { CollisionTypes } from '../../parts/CollisionTypes.js';
133
131
  * (Y-specific by design, the DSE liner's own cavity-eject convention) are
134
132
  * UNCHANGED regardless of this flag — reflecting vz off a Y-normal wall
135
133
  * would be physically wrong (this is a TOP/BOTTOM face; NEAR/FAR is
136
- * handled correctly already by native BOUNCE, see the round-1 deliverable).
134
+ * handled correctly already by native BOUNCE).
137
135
  * Default `false` — byte-identical for every existing caller (`SlitScreen.js`'s
138
136
  * own 2D liner construction, which never passes this).
139
137
  * @returns {Array<Object>} the FULL composed ops array (eject-prefix + tail +
@@ -206,7 +204,7 @@ import { CollisionTypes } from '../../parts/CollisionTypes.js';
206
204
  * exclusive with opts.behavior/opts.resetLocalTime).
207
205
  * @param {string} [opts.behavior] - explicit composable behavior (LIVE controls).
208
206
  * @param {boolean} [opts.resetLocalTime] - explicit composable reset (LIVE controls).
209
- * @param {boolean} [opts.hasRealDepth=false] - ws-dse-3d AC2 — see
207
+ * @param {boolean} [opts.hasRealDepth=false] - see
210
208
  * `buildLinerProgram`'s own param doc. Default false — byte-identical for
211
209
  * every existing caller.
212
210
  */
@@ -1,9 +1,9 @@
1
1
  /* Copyright 2023-2026 by Essam Abadir */
2
2
 
3
3
  /**
4
- * sustainedSource — the ONE hand-placed-quantum source surface (ws-dse-3d, CEO
5
- * ruling 2026-07-14: "Tunnel Lab and LightSource Lab share ONE source surface
6
- * and differ only in declared composition"). REPLACES two independently
4
+ * sustainedSource — the ONE hand-placed-quantum source surface (Tunnel Lab and
5
+ * LightSource Lab share ONE source surface and differ only in declared
6
+ * composition). REPLACES two independently
7
7
  * hand-rolled injector tick-fns (`setupTunnelLab.js`'s and
8
8
  * `setupLightSourceLab.js`'s own, admitted by the latter's own comment to
9
9
  * "mirror setupTunnelLab.js byte-for-byte") with ONE authority that both labs,
@@ -16,7 +16,7 @@
16
16
  * discipline (root CLAUDE.md "Engineering Culture"): the owner (this file)
17
17
  * exports the field list + defaults; every consumer calls `normalizeSourceSpec`
18
18
  * to get a FULL bag (never hand-re-enumerates a subset), so a field omission is
19
- * structurally impossible to silently diverge on (the exact bug this bite
19
+ * structurally impossible to silently diverge on (the exact bug this
20
20
  * fixes: one injector stamped `wavelength`, the other didn't, and nothing
21
21
  * forced them to agree). `sustained-source.test.mjs` is driven off this exact
22
22
  * exported list — adding a field here without a matching test entry is a CI
@@ -29,10 +29,10 @@
29
29
  * injectors independently derived), draws a velocity per `spec.velocityProfile`,
30
30
  * and calls `makeLeafFrame`/`injectFrame`/`setFrameProperty` — the SAME
31
31
  * generic primitives every hand-placed-quantum experiment already uses (G-EMIT-2,
32
- * `docs/internal/engine/ENGINE_BOUNDARY_MODEL.md`). Used for BOTH a one-shot burst (LightSource's
32
+ * the engine boundary model). Used for BOTH a one-shot burst (LightSource's
33
33
  * own construction-time placement) and a recurring burst (`buildSustainedSource`'s
34
34
  * tick-fn) — "the one injector then stamps quantum properties ... in exactly ONE
35
- * place" (the architect's own worked-example blueprint, Section 4 item 1).
35
+ * place" (the worked-example blueprint, Section 4 item 1).
36
36
  *
37
37
  * `buildSustainedSource(universe, innerRect, capNegX, hasRealDepth, specPartial)`
38
38
  * builds+registers a recurring Phase-A host tick-fn (mirrors `emitterProgram.js`'s
@@ -54,8 +54,7 @@
54
54
  * Invariant #6 `mass = max(1, capacity/wavelength)`). `null` (default) =
55
55
  * engine default (`mass = capacity`, i.e. fullness=1, top of the ROYGBIV
56
56
  * ramp). THIS is the field whose divergence (one injector set it, the other
57
- * didn't) produced the CEO's "different particle colors" report — see
58
- * `docs/physics/COLOR_RENDER_LEARNINGS.md` and the ws-dse-3d investigation.
57
+ * didn't) produced "different particle colors".
59
58
  * @property {number|null} charge - Per-frame charge override (0=Positive,
60
59
  * 1=Negative). `null` (default) = random draw per quantum.
61
60
  * @property {'beam'|'spray'} velocityProfile - `'beam'` (default) = collimated
@@ -63,7 +62,7 @@
63
62
  * `vy=vz=0` always, a deliberately directed/phase-locked stream). `'spray'` =
64
63
  * a biased random fan (`spraySpec`) — `setupTunnelLab.js`'s own original
65
64
  * uniformization-demo shape. Named, selectable, NEVER divergent hand-code
66
- * (architect Section 3 finding E).
65
+ * (Section 3 finding E).
67
66
  * @property {number} speed - `'beam'` profile only: speed magnitude.
68
67
  * @property {number} orientationRad - `'beam'` profile only: direction,
69
68
  * radians (`0` = +X).
@@ -79,9 +78,9 @@
79
78
  * @property {boolean} zIsotropy - When real depth is armed AND
80
79
  * `velocityProfile==='spray'`: draw `vz = (random()*2-1)*spraySpec.vyRange`
81
80
  * (the SAME half-range as the vy spread) — the 3D-SYMMETRIC EMISSION fix
82
- * (ws-dse-3d, theorist §4 option (a): "draw vz symmetric to the vy spread").
81
+ * (§4 option (a): vz is drawn symmetric to the vy spread).
83
82
  * `'beam'` profile is UNAFFECTED regardless of this flag (`vy=vz=0` stays —
84
- * collimation is deliberate; theorist §4 option (b): the beam's isotropic
83
+ * collimation is deliberate; §4 option (b): the beam's isotropic
85
84
  * TRANSVERSE WAVE already does the 3D work, measured y≈z). Default `true`.
86
85
  * @property {number|null} level - `makeLeafFrame`'s `level` override (rarely
87
86
  * used; `LightSource.js`'s own `options.particle.level`). `null` (default).
@@ -203,14 +202,14 @@
203
202
  var s = spec.spraySpec;
204
203
  vx = s.vxMin + universe.random() * s.vxRange;
205
204
  vy = s.vyMin + universe.random() * s.vyRange;
206
- // 3D-SYMMETRIC EMISSION (ws-dse-3d, theorist §4 option (a)): draw
205
+ // 3D-SYMMETRIC EMISSION (§4 option (a)): draw
207
206
  // vz symmetric to the vy spread, SAME half-range, only when real
208
207
  // depth is armed AND the caller opted into zIsotropy (default
209
208
  // true) — makes the injected fan 3D-isotropic instead of pinning
210
209
  // z-momentum at zero forever (the measured z/y=0.18-0.23 flatness
211
- // root cause — architect Section 2e, tester Section C).
210
+ // root cause — Section 2e, Section C).
212
211
  vz = (hasRealDepth && spec.zIsotropy) ? (universe.random() * 2 - 1) * s.vyRange : 0;
213
- } else { // 'beam' — collimated; vy=vz=0 stays (deliberate, theorist §4 option (b))
212
+ } else { // 'beam' — collimated; vy=vz=0 stays (deliberate, §4 option (b))
214
213
  vx = Math.cos(spec.orientationRad) * spec.speed;
215
214
  vy = Math.sin(spec.orientationRad) * spec.speed;
216
215
  vz = 0;
@@ -283,8 +282,8 @@
283
282
  * capacityAtDimension(dim) — the ONE authority for "capacity of a leaf at
284
283
  * fundamental dimension `dim`" (Engine Invariant #6: `width=2^dim,
285
284
  * capacity=width²`). Both tunnel-lab and lightsource-lab derive their
286
- * `MAX_USEFUL_WAVELENGTH` slider ceiling from this (CEO drive #2 ceiling
287
- * fix, ws-dse-3d AC4 — "same MAX_USEFUL_WAVELENGTH clamp authority") —
285
+ * `MAX_USEFUL_WAVELENGTH` slider ceiling from this (the ceiling
286
+ * fix — same MAX_USEFUL_WAVELENGTH clamp authority) —
288
287
  * never a hand-typed "16" in either factory.
289
288
  * @param {number} dim
290
289
  * @returns {number}