# Double Slit → Rosetta → QFT One environment, three engines, **individually runnable**. This dogfood proves the unified-notebook capability end-to-end: - **imperative cells** — nothing runs on load; you click Run per cell. - **typed object-bag handoff** — a cell declares what it consumes (`in`) and produces (`out`); the kernel wires named outputs to named inputs and marks consumers *stale* (never auto-runs them). - **a live physics canvas alongside math** — the double-slit simulation mounts only when you Run its canvas cell, and at most one canvas runs at a time. The loose through-line: an interference pattern *is* information; we encode it (Rosetta), and we factor a number whose period extraction is the "quantum" step of Shor's algorithm (QFT) — all classical, all here. ## 1. The double slit The canvas below DECLARES the canonical double-slit experiment (`setup="./setups/double-slit.js#setupDoubleSlit"` + `stage="480x480"` + `seed="42"`); the shim synthesizes the builder boilerplate (import → ensureEngine → FrqtlApp → setup → mount) and runs it in the realm. It does **not** start on notebook load — click **Run** to mount and start it. The canvas also declares `produceAfter="600"`: before committing the `hist` binding (§2) the shim warms the realm 600 deterministic ticks so particles cross the stage and accumulate at the detector — so the histogram (and the §3 chart) shows **real** fringe data rather than an empty tick-0 snapshot. The runner stays **realm-internal** (it is never a kernel binding); realm-produced data reaches downstream cells via the realm→kernel binding seam (§2). Switch to another notebook and back, Run again — the pane disposes the prior runner first, so there is never a duplicate RAF loop. The canvas also declares `liveChart="detectorHistogram"`: a **same-cell** live accumulation chart renders **inside this canvas's own realm**, beneath the sim, and **fills as the sim runs** (the original-gallery model). It subscribes to the realm's **local** tick stream (`handle.on('tick')`), polls the same `detectorHistogram` projector, and redraws ~10×/s — so you watch the fringes build live. This is **orthogonal** to `produces=`: the live chart draws continuously and commits **nothing**, while `produces="hist"` derives the histogram **once** and commits the `hist` kernel binding the §3 chart consumes. Because the live chart lives in the realm, its data **never** crosses the renderer↔realm boundary. /* setupDoubleSlit — THIN ADAPTER over the canonical setup factory * (WS gym-controls-as-sugar Bite 0: this cell used to hand-copy the physics — * a divergent fork of lib/frqtl/objects/setup/setupDoubleSlit.js that had * already drifted onto a stale `universe.init(...)` positional-argument call the * engine now FAIL-LOUDs on. The canonical factory is imported by BARE SPECIFIER * (a relative path here would 404 — see lib/shim/notebook/frqtl-setups-importmap.js); * this cell only bridges the notebook builder's `(frqtl, universe, options)` call * shape to the factory's `(universe, options)` shape — ZERO physics here. This * is the SAME canonical factory the gallery-double-slit notebook drives — * one experiment identity.) */ import { setupDoubleSlit as _setupDoubleSlit } from '@frqtl/setups/double-slit'; export function setupDoubleSlit(frqtl, universe, options) { return _setupDoubleSlit(universe, options); } ## 2. Pull the interference histogram (the realm→kernel binding seam) The canvas above DECLARES its setup (`setup="./setups/double-slit.js#setupDoubleSlit"`) **and** what it produces (`produces="hist"`); the shim synthesizes the builder and runs it **realm-internal** — the runner is **never** a kernel binding (WS-NOTEBOOK-SHIM-MANAGED-BUILDER C9). After the runner mounts, the realm DERIVES a **serializable** detector histogram from the live runner via the one frozen-handle projector (`detectorHistogram(runner)`, default `produceVia`) and commits it as the `hist` binding through the single binding-commit authority `kernel.commitViewOutputs` (WS-NOTEBOOK-REALM-KERNEL-BINDING). The committed value is a plain `{ binKey: count }` object — a live runner can never cross the seam (it FAILS LOUD at the serializability gate). The `hist`-consuming cells below now resolve once you Run the canvas; before it has produced, they still FAIL LOUD ("`hist` not yet produced") — by design, never a silent empty result. ## 3. Chart the fringes The chart cell consumes `hist` and renders the interference fringes as a bar chart (Chart.js). It FAILs LOUD naming the producing cell if `hist` is not yet produced — it never silently draws an empty chart, and never auto-runs the upstream cell. (`hist` arrives via the realm→kernel binding seam — see §2.) ## 4. Encoding the pattern (Rosetta) Now we cross lanes — `frqtl` → `math`. This cell consumes `hist` (produced in the frqtl lane) and builds a Rosetta `Codec` over the histogram counts: a typed pipeline `HostFloats → EGPTReal → HostFloats` with an explicit `claim`. Running it captures per-stage `snapshots` (the object-bag-per-stage trace) — the same provenance discipline the notebook kernel generalizes. This is the `hist → chain` cross-lane handoff. // Cross-lane handoff: hist (frqtl) → a Rosetta Codec (math). const { math, display } = caps; // `hist` arrives via the realm→kernel binding seam as a SERIALIZABLE plain // { binKey: count } object (a live runner / Map can never cross the seam). Read its // counts from the plain object's values (NOT Map.values()). const hist = inputs.hist; const counts = (hist && typeof hist === 'object') ? Object.keys(hist).map((k) => Number(hist[k])) : []; // Pad to a non-empty array so the chain always has something to encode. const payload = counts.length ? counts : [0]; const codecRuntime = math.codec; // { registry, Codec, buildCodecDsl, EncodingClasses } const dsl = codecRuntime.buildCodecDsl( codecRuntime.registry, codecRuntime.Codec, codecRuntime.EncodingClasses ).dsl; // A minimal typed round-trip chain over the histogram values. dsl.input('HostFloats', { payload, format: 'fp64' }); dsl.push('HostFloatsToEGPTReal'); dsl.push('EGPTRealToHostFloats'); // Codec.run THROWS MissingClaimError unless a claim was declared first // (architect ground-truth correction #4). dsl.claim('round-trip-exact', { reference: 'round-trip-exact', tolerance: 'exact' }); const built = dsl.build(); const codec = built.codec; const chain = codec.run(built.headEncoding); // RunResult { snapshots, output, trace } display(`Rosetta chain ran: ${chain.snapshots.length} snapshots ` + `(input → EGPTReal → host floats); claim="${chain.claimMeta && chain.claimMeta.name}".`); return { chain }; // Display the per-stage snapshots (the object-bag-per-stage trace) + the // round-trip verdict. Ties the Rosetta paradigm to the notebook paradigm: // named typed handoff, captured at every stage. const { display } = caps; const chain = inputs.chain; const kinds = chain.snapshots.map(s => (s && s.constructor && s.constructor.kind) || '?'); display(`stages: ${kinds.join(' → ')}`); const head = chain.snapshots[0]; const tail = chain.output; const roundTrips = (head && typeof head.equals === 'function') ? head.equals(tail) : false; display(`round-trip (head.equals(output)): ${roundTrips ? 'OK (exact)' : 'differs'}`); ## 5. The QFT benchmark This `math`-lane cell drives the **same** `FraqtlSession` the QFT showcase notebook drives (`math.FraqtlSession.auto()` → `session.run(N)`) — reuse, not fork. It factors the 39-bit semiprime `549755813701 = 712321 × 771781` (the period-extraction "quantum" step of Shor's algorithm, run classically here). N and the 594-core-year comparison come from the single baseline authority `math.benchmarks.qftBaseline` — no inlined figures. This cell is deliberately **not** wired to the others: not every cell must chain. const { math, display } = caps; const b = math.benchmarks && math.benchmarks.qftBaseline; if (!b) { throw new Error('math.benchmarks.qftBaseline absent — figures live in ONE authority (FAIL-LOUD).'); } const N = b.benchmarkRun.N; // the SAME semiprime, from the authority const session = math.FraqtlSession.auto(); const t0 = performance.now(); const result = session.run(N); const elapsedMs = (typeof result.elapsed_ms === 'number') ? result.elapsed_ms : (performance.now() - t0); const expected = b.benchmarkRun.factors; const got = (result.factors || []).slice().sort((x, y) => x - y); const want = expected.slice().sort((x, y) => x - y); const ok = got.length === want.length && got.every((v, i) => v === want[i]); display(ok ? `FACTORS VERIFIED on ${math.activeMathBackend}: ${N} = ${result.factors.join(' x ')} ` + `in ${elapsedMs.toFixed(0)} ms — vs the published ${b.studyCompute.coreYears} core-years of supercomputer compute.` : `MISMATCH: got [${result.factors}], expected [${expected}].`); const qft = { N, factors: result.factors, ok, elapsedMs, backend: math.activeMathBackend }; return { qft }; ## What this validates Interference → encoding → factoring, in one notebook, on one execution surface, every cell individually runnable, the physics canvas never auto-triggered. This is the capability bar for the CODE + GALLERY merge: the same native `` format and the same on-demand kernel carry markdown, math, live physics, and charts side by side.