open-standards/wai/quantum-studio/README.md
Transaction Science a1bf417590 wai-quantum: a program's history, attributed, and the Studio's Versions
Feature 6 of the co-design report: every version of a program, who made
each change and how, and whose hand each line and gate is in, sealed
into the run's receipt.

- engine::versions:
  - versions in a chain, each naming its parents (none, one, or two for
    a merge), who made it (the person, the assistant, an outside agent,
    the engine, or where the program came from) and how (an edit, a
    proposal reviewed change by change, a merge);
  - a version's digest covers its parents' digests, and the recording
    host's key seals it; verify checks every digest, seal and review;
  - changes and apply: a line diff (Myers), so a proposal is taken
    change by change, and the version keeps the whole proposal;
  - blame, authorship and gate_hands: a line keeps its author until
    changed; a model's or an agent's line the person edits is in both
    hands; an undo keeps the earlier authors; a merge keeps each side's;
    gates follow their lines, at a generator's inputs;
  - attest and check_job: a job's request carries the account, the
    receipt binds it, and it is recomputed from the history;
  - call: the history by name with JSON arguments, for the page and the
    desktop app.
- The command line: history start | commit | changes | propose | merge |
  log | blame | verify; run and submit --history; verify --history.
- MCP: history_commit, history_changes, history_blame and history_log.
  An agent's edit is recorded as an outside agent's, under the name its
  client gave in initialize, whatever it says of itself.
- The Studio's Versions pane:
  - what the reader types is theirs, recorded when they pause;
  - every proposal (the assistant's program, an alternative, a generator
    from the Workbench) is offered change by change while the editor
    waits; a fix is the engine's;
  - lines of work in lanes: an older version opened and edited starts
    its own, and "Bring in" merges one change by change;
  - "Who wrote it" marks lines in the gutter and gates on the diagram;
  - the run's receipt binds the account, which the result recomputes;
  - kept in the browser, downloaded for the command line;
  - window.quantumStudio.propose for an embedding page.
- Fixes found by the Studio's test: a run shows it is running before
  the account is made, and the draft is kept as the page goes.
- CI: wai-web's native engine tests count 8, the history's included.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-26 02:02:58 -04:00

8.2 KiB
Raw Permalink Blame History

Quantum Studio

An editor for OpenQASM programs, with three places to run them:

  • this browser, through the quantum job service's engine compiled to WebAssembly, in a worker;
  • this computer, through the same engine built natively, in the desktop app;
  • the job service, over HTTP.

Every place returns the same job: the request, the method and why it was chosen, the result, and its receipt. The Studio shows them the same way and checks every receipt on the machine it runs on. The same request with the same seed gives the same counts in each place.

The editor:

  • highlights OpenQASM;
  • completes the standard gates and the program's own registers;
  • marks the engine's diagnostics on their lines;
  • draws the circuit and shows the plan as you type.

Ctrl+Enter (⌘+Enter on macOS) runs the program, and Escape cancels a run. The program and the history of runs are kept on the device. "Copy link" puts the program in a URL fragment, which no server sees.

Generators

A program that declares integer inputs (input uint n;) is a generator: its for loops and its ifs on integers write out one circuit for each value. The Studio shows a field for each input under the editor and reads the program at those values. The lint and the critique read the generator itself, so a problem or a smell keeps the generator's own line. The diagram, the plan, a run (here or on the service), the lens and the alternatives take the circuit it writes out. The values are kept in this browser, by name.

The Workbench

The Workbench searches a family of circuits for its cheapest members, and the engine judges every proposal. The program in the editor is the reference. The specification says:

  • what each member must do: prepare the same state from |0…0⟩, or be the same circuit;
  • the sizes to check at (n = 3, 5, 8);
  • the gates allowed, and whether a gate may join any pair or only neighbours on a line;
  • the cost, as weights on the critique's measures summed over the sizes;
  • the two measures the map plots.

"Start" checks the reference at every size and seeds an archive with it. The archive keeps the cheapest verified generator in each cell of the map. Three proposers write into it, and each is named on what it found:

  • the reader: "Submit the editor's program";
  • the built-in, blind search: "Search ×100", seeded edits of what the archive holds. It is the baseline an idea has to beat;
  • the model, when one is connected: "Ask the model ×3". It is told the specification and shown the cheapest found, with the costs the engine measured.

A proposal is verified only when it reads, keeps the rules and passes the check at every size. Each kept entry is sealed with this browser's key (the desktop app's, in the app). Clicking a point shows its cost, how it was checked, its seal and where it came from; "Open in editor" puts it in the editor. The archive is kept in this browser and comes back with the page. "Download" saves the specification and its archive side by side (NAME.json and NAME.archive.json), so wai-quantum discover verify NAME.json checks every seal. In the desktop app a search also counts its seconds and the joules its process spent.

Versions

The Versions pane records each change to the program and who made it:

  • what the reader types is theirs, recorded once they pause, before a run, and before anything else changes the program;
  • a proposal is its proposer's: the assistant's program, an alternative (the engine's or the model's), a generator opened from the Workbench;
  • a fix is the engine's;
  • an example, a file, a link or an earlier run is where the program came from.

A proposal is taken change by change. Its changes are listed with their lines, each with a box, and the program waits until the reader chooses. Only the changes taken reach the program. The version keeps the whole proposal and which changes were taken, so a rejected one stays readable.

Lines of work. The versions are drawn as lines of work. "Open" puts an older version in the editor, and what is changed from it starts a line of its own. "Bring in" shows another line's head change by change against the program, and the changes taken are recorded as a merge of both.

Whose hand. "Who wrote it" marks each line in the editor's gutter and each gate on the diagram: the reader, the assistant, an agent, the engine, where it came from, or a model's line the reader then edited, which is in both hands. The pane shows each contributor's gates and lines.

On the receipt. A run's request carries the account of the version in the editor: its digest, and the gates and lines in each hand. The receipt binds it, and the result shows "written by" and the account recomputed here from the versions. The versions are kept in this browser, each sealed with its key (the desktop app's, in the app). "Download" saves program.qasm and program.history.json, which wai-quantum history verify program.qasm checks.

An embedding page can offer a program as someone's proposal with window.quantumStudio.propose(qasm, {kind, name}, note); it resolves once the reader has chosen.

The assistant

The Assistant pane talks to a language model on this machine: any server with the chat-completions interface and tool calls, such as the JouleClaw runtime or a llama.cpp server. The address goes under "Model…" and is http://127.0.0.1:8080/v1 by default. Nothing leaves the machine unless the address points elsewhere. In the desktop app the app makes the call itself, so no browser origin rule stands in the way.

The engine is the model's tool, not an afterthought:

  • Its tools are the Studio's engine: read the program, lint, draw, plan and run. Its first turn must call one of them, so every answer starts from the engine.
  • Every program it proposes is checked before it is offered. The engine reads it here. One that does not parse goes back to the model once, with the engine's reason, to be corrected. One that parses is run, with the settings the model used, so the counts it quoted are the counts shown. Then "Apply" puts it in the editor.
  • It may state only figures the engine returned. A figure in its prose that no tool returned is marked "Not from a run".
  • Answers are plain text. LaTeX a model writes anyway is shown as Unicode.

node test/assistant-live.mjs URL drives the assistant against a real model server and prints what it did. It is not part of CI, which has no model.

Hosting it

Build it with npm ci && node build.mjs. That writes dist/:

File What it is
studio.js the interface, bundled
worker.js the engine's worker
studio.css the Studio's styles
tokens.css the site's design tokens, for when it stands alone
index.html the page that stands alone

A host mounts the Studio on an element:

<div id="studio"
     data-engine-pkg="/quantum-ide/pkg/wai_quantum_ide.js"
     data-worker="/quantum-studio/worker.js"
     data-service="/quantum-jobs"></div>
<script type="module" src="/quantum-studio/studio.js"></script>

data-embedded tells the Studio the host page has its own heading, so the Studio's name is not a second h1. data-engine-pkg names the engine's browser package: wai-web built with the feature quantum_engine. node build.mjs --pkg DIR copies such a package into dist/pkg/ for index.html. On the desktop, window.__TAURI__ is present and the Studio uses the native engine instead.

Testing it

node build.mjs --pkg PATH/TO/PKG && node test/studio.test.mjs

The test runs the Studio in the installed browser:

  • lint, draw and plan as the program is typed;
  • a run in the browser, with its receipt checked there;
  • an error marked on its line;
  • a rotation run on the state vector;
  • the same job on the live service giving the counts run here, shot for shot;
  • Ctrl+Enter;
  • the program and the history surviving a reload;
  • the assistant, against a scripted model server: a tool call run on the engine, a proposal the engine cannot read sent back with its reason, the corrected one checked and run before it is offered, and Apply;
  • the layout at a phone's width.

STUDIO_SKIP_SERVICE=1 leaves the service step out. It saves screenshots of both colour schemes in test/screenshots/.