Repository navigation
Build deterministic BLOCH state-space lab - #1
Conversation
Reviewer's GuideImplements a deterministic, offline Bloch-sphere laboratory that maps Bloch vectors to an octahedral grid and LUT, records hash-chained state-space frames, provides replay/geometry/audio tooling, and packages the lab for GitHub Pages with tests and documentation. Sequence diagram for deterministic recording, verification and sonificationsequenceDiagram
actor User
participant App
participant Recorder
participant BlochCore
participant BlochVisuals
participant BlochAudio
participant BlochHash
User->>App: click STEP
App->>Recorder: step()
Recorder->>Recorder: recordCurrent(flagsByPoint)
Recorder->>BlochHash: domainHash(DOMAINS.frame,core)
Recorder-->>App: latestFrames()
App->>BlochVisuals: drawLut(lutCanvas,recorder)
App->>BlochVisuals: drawStateSpace(stateCanvas,recorder)
App->>BlochVisuals: SphereView.render(recorder)
User->>App: click VERIFY
App->>Recorder: exportDocument(currentFormanMode)
App->>BlochCore: verifyDocument(document)
BlochCore-->>App: {ok,headHash}
App->>BlochCore: replayDocument(document,formanMode)
BlochCore-->>App: {ok,recorder,document}
User->>App: click LISTEN
App->>BlochAudio: renderRecording(recorder.frames,options)
BlochAudio->>BlochHash: sha256Hex(wav)
BlochAudio-->>App: {wav,receipt}
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Sorry @EmergentMonk, your pull request is larger than the review limit of 150000 diff characters
There was a problem hiding this comment.
Pull request overview
This PR introduces a dependency-free, offline (file://) BLOCH “state-space lab” that deterministically maps Bloch-sphere trajectories onto an octahedral 2D grid/LUT, records hash-chained integer frames with exact replay/export, and adds geometry + audio diagnostics, docs, tests, and GitHub Pages deployment.
Changes:
- Add deterministic core engine (octahedral mapping, LUT generation, recorder/frame hashing, replay/verification, geometry witnesses, binary BLSF export).
- Add offline browser UI + deterministic WAV sonification/export and static “no network” contract checks.
- Add documentation, fixtures, CI verification workflow, and Pages deployment workflow.
Reviewed changes
Copilot reviewed 22 out of 24 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
tests/static.test.js |
Static offline/runtime contract checks (no network APIs/assets, script order, SPDX, no deps). |
tests/index.html |
Browser harness page for known-answer tests. |
tests/core.test.js |
Node deterministic tests covering hashing, mapping, replay, binary ABI, geometry, audio determinism. |
tests/browser-tests.js |
In-browser known-answer tests runner and results rendering. |
style.css |
Full offline UI styling for the lab. |
README.md |
Expanded documentation: purpose, boundaries, usage, exports, determinism and claim limits. |
package.json |
Minimal Node scripts for syntax checking and tests; no dependencies. |
NOTICE.md |
Attribution and lineage notes. |
js/visuals.js |
Canvas renderers for sphere/LUT/state/mesh/contours. |
js/hash.js |
Canonical safe-integer JSON + synchronous SHA-256 and domain hashing. |
js/bloch-core.js |
Deterministic engine: mapping/LUT, manifold dynamics, frame hashing, replay, geometry witnesses, BLSF encoding. |
js/bloch-audio.js |
Deterministic trajectory sonification, WAV encoding, audio receipts. |
js/app.js |
Browser controller/UI wiring, import/export, playback, verification, audio rendering. |
index.html |
Offline lab shell (controls + panels) with classic script loading order. |
fixtures/sample-trajectory.csv |
Example import dataset for local CSV ingestion. |
fixtures/ronin-zero-profile.json |
Pinned profile fixture used by tests to lock parameters. |
docs/MODEL.md |
Mathematical + replay/determinism contract documentation. |
docs/BLSF.md |
Binary frame format specification. |
CITATION.cff |
Citation metadata for research use. |
assets/bloch-state-space-preview.svg |
Rendered preview asset for README/Pages. |
.nojekyll |
Pages configuration helper. |
.gitignore |
Ignore exported artifacts and node_modules/. |
.github/workflows/verify.yml |
CI: syntax checks + deterministic tests. |
.github/workflows/pages.yml |
CI: verify then deploy static site to GitHub Pages. |
Comments suppressed due to low confidence (1)
js/bloch-core.js:1072
verifyDocument()callsHash.domainHash()directly. If the input document contains non-canonical values (e.g., floats,NaN, or other unsupported types),domainHash()will throw and bubble out ofverifyDocument(). Since this API otherwise returns{ ok, reason }objects, the throw is an inconsistent failure mode and can crash non-UI callers.
const core = Object.assign({}, document);
const supplied = core.recordingSha256;
delete core.recordingSha256;
const expected = Hash.domainHash(DOMAINS.recording, core);
if (supplied !== expected) return { ok: false, reason: "recording-hash" };
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const to = normalize(point); | ||
| const angle = angleBetween(from, to); | ||
| if (angle < 1e-15) return [0, 0, 0]; | ||
| const direction = subtract(to, scale(from, dot(from, to))); | ||
| return scale(normalize(direction, cross(from, [0, 0, 1])), angle); |
| const core = Object.assign({}, frame); | ||
| const supplied = core.frameSha256; | ||
| delete core.frameSha256; | ||
| const expected = Hash.domainHash(DOMAINS.frame, core); | ||
| if (supplied !== expected) { |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 432c77c390
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| || this.config.importedSamples.find(function (sample) { | ||
| return sample.point === point; | ||
| }) |
There was a problem hiding this comment.
Reject imported points without an initial sample
When a point's first imported row occurs after sequence 0, this fallback selects that future sample and records it as the point's sequence-0 state. Since the importer permits such sparse datasets, this silently moves observations backward in time and changes forecasts, geometry, and hashes; require an initial sample for every point or define non-fabricating pre-sample behavior instead.
Useful? React with 👍 / 👎.
| recorder = result.recorder; | ||
| byId("scenario").value = recorder.config.scenario; |
There was a problem hiding this comment.
Restore the imported Forman mode
When the imported recording's Forman mode differs from the dropdown's current value, replay correctly validates using the artifact's mode, but this control-sync block never updates forman-mode. The next render recomputes and displays geometry using the stale selection, and subsequent export or verification produces a different receipt, so the UI no longer represents the recording it just reported as imported successfully.
Useful? React with 👍 / 👎.
| }); | ||
| byId("forman-mode").addEventListener("change", function () { | ||
| dirty = true; | ||
| setStatus("GEOMETRY PROFILE CHANGED · recording identity unchanged", "neutral"); |
There was a problem hiding this comment.
Report that Forman mode changes recording identity
Changing this selector leaves the frame-chain head unchanged, but it does change the recording identity: exportDocument() commits the mode-specific geometry bundle before computing recordingSha256. The current status therefore gives users incorrect provenance information whenever they switch between weighted and unweighted geometry.
Useful? React with 👍 / 👎.
| - name: Verify static lab | ||
| run: npm test |
There was a problem hiding this comment.
Gate Pages deployment on the syntax checks
In the Pages workflow, deploy depends only on this job, but npm test merely reads js/visuals.js and js/app.js as text and never parses them. A syntax error in either browser file can therefore pass this gate and be deployed; the separate verify.yml workflow runs independently and cannot prevent this deployment, so this job should also run npm run check.
Useful? React with 👍 / 👎.
| const target = projected.z >= 0 ? front : back; | ||
| if (previous && previous.front !== (projected.z >= 0)) { | ||
| target.push([projected.x, projected.y]); | ||
| } | ||
| target.push([projected.x, projected.y]); |
There was a problem hiding this comment.
Split wireframe curves into separate visible segments
Whenever a closed latitude or longitude crosses the front/back depth boundary, the hemisphere containing the sampling start is represented by two disjoint runs. Appending both runs to one front or back array makes line() connect them with a straight chord across the intervening hemisphere, so the Bloch sphere wireframe displays spurious lines; retain separate subpaths at each depth transition instead.
Useful? React with 👍 / 👎.
| if (dirty) renderAll(); | ||
| else sphere.render(recorder); | ||
| globalThis.requestAnimationFrame(animation); |
There was a problem hiding this comment.
Stop rendering the sphere continuously while idle
Once dirty becomes false, the application still redraws the full high-DPI sphere, wireframe, and trajectory on every animation frame, including while playback is paused and no pointer interaction is occurring. This causes continuous CPU/GPU use from the moment the page opens; redraw only when recorder or view state changes, with pointer and wheel handlers marking the sphere dirty.
Useful? React with 👍 / 👎.
| const sampleRate = [22050, 44100, 48000].indexOf(Number(options.sampleRate)) >= 0 | ||
| ? Number(options.sampleRate) | ||
| : 44100; | ||
| const groups = sequenceGroups(frames).slice(-512); |
There was a problem hiding this comment.
Preserve the full trajectory in audio exports
For recordings longer than 512 sequences, this unconditional slice silently discards every earlier sequence and sonifies only the tail, even though the WAV feature is presented as an export of the recorded trajectory and the receipt commits the full source frame count and head. Long experiments therefore produce an incomplete audio artifact without an explicit range selection; render all sequences or make the truncation and rendered source range explicit.
Useful? React with 👍 / 👎.
What changed
file://BLOCH state-space laboratory.Why
This implements the workflow described by 罔 rō'nin (@theronin42):
Bloch sphere → 2D grid → LUT → time-indexed state space → replay → extrapolationThe implementation makes the critical distinction explicit: the natural zero is the tangent deviation
e = 0around a moving reference trajectory; it is not the fixed Bloch north-pole state|0⟩.Model boundary
This is a deterministic classical state-space model and visualization instrument. It does not claim quantum-hardware control, physical qubit error correction, a fault-tolerance threshold, or experimental validation. The recovery rule is fixed; there is no syndrome decoder, training, adaptive tuning, or hidden network dependency.
Validation
npm test— 18/18 deterministic core and format tests passnpm run check— JavaScript syntax checks passgit diff --check— cleanSummary by Sourcery
Introduce a deterministic offline Bloch-sphere laboratory with octahedral LUT mapping, encoded state-space frames, replay/extrapolation, geometry diagnostics, sonification, and GitHub Pages deployment.
New Features:
Enhancements:
Build:
CI:
Deployment:
Documentation:
Tests: