Skip to content

Commit 5eed9ea

Browse files
ehsun-shclaude
andcommitted
Wire the canvas to the engine
Press Run and the page posts its graph to the session server and draws what comes back. Change a parameter and run again and the numbers move because the physics moved: set the fiber to 200 km and the received power drops by exactly the 24 dB the extra loss costs, while the constellation collapses, because the compensator is still set for the old span. The canvas now draws the project document itself. The blocks, wires and parameter values are no longer written into the page -- they are read from the same `.maiman` document the server accepts, exported from the graph that produced the reference numbers, and Run posts that object straight back. The picture on the canvas, the values in the inspector and the graph the engine executes are one description instead of three kept in step by hand. The hand-written copy that used to live in the page had already drifted: it was missing four of the fiber's parameters, added two commits ago. Wire colours come from the manifest of the block a wire leaves, so one cannot be drawn the wrong colour. Block captions come from the block's own parameters, so editing a value changes what the canvas says, and a measurement block shows its last reading or "--" rather than a number someone typed once. The inspector's fields were previously wired to nothing: typing in one changed the pixels and no more, which is why it accepted 128 for a field whose own label said "range 1 ... 8". They now write into the document, and out-of-range input is marked. Validation lives in both places on purpose: the engine's is the one that must be right, and this one exists so a typo is answered where it was made. When they disagree the engine wins -- PRBS order 12 is inside the declared range 7...31, so only the engine knows it is not a maximal-length polynomial, and its message arrives verbatim with the valid orders listed. Three states the page could not previously have, because it never called anything: running, failed, and stale. A failure names its kind from the status the server chose and opens the log. A graph edited since the last run marks the dock stale rather than leaving numbers on screen that answer a question no longer being asked -- reference, live and stale are three different things and a plot from four days ago must not look like one from the last click. Served, the palette is fetched from the engine that is actually running, so a component from a plugin appears without rebuilding this file. Opened from disk it falls back to the bundled reference and says so instead of animating a progress bar for something that is not going to happen. tests/test_studio.py guards the page's claims from the file: that its embedded data matches the export, that the schematic is a graph that runs, that the numbers printed beside the plots are reproducible from it, and that every block has somewhere to be drawn. This is not hypothetical -- the stale copy bit twice today, once carrying a palette two components short and once missing the project document entirely, and nothing noticed either time. 5 sabotages, 5 caught, each by the intended test. Two bugs found by using it. The dispersion diagnostic is held in s/m and read in ps/nm, a factor of 1e3 rather than one of the usual ones, and the page printed "1 ps/nm removed" for a compensator set to 1360; the encoder now sends both and a test pins them. And a TypeError thrown while rendering a result that had arrived perfectly well was reported as "session server unreachable", which sends whoever reads it to look in the wrong place. Not an editor yet. Blocks cannot be added, deleted, moved or rewired -- that is the React Flow work, and the empty state arrives with it rather than before it. 625 tests. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 640ae76 commit 5eed9ea

10 files changed

Lines changed: 1419 additions & 113 deletions

File tree

DESIGN.md

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -258,9 +258,13 @@ Two findings worth keeping:
258258
and a schematic nobody can read is not a better demonstration. At 17 blocks
259259
the current graph is already close to that ceiling.
260260
- No motion beyond the run pulse and the control transitions.
261-
- No empty, loading or error states. The session server now produces all three —
262-
a run that is still going, a graph that will not run, a component the server
263-
does not know — but the page does not yet call it, so nothing here reacts to
264-
them. Designing those states is part of wiring the canvas to the API, not
265-
ahead of it: the server's own error vocabulary (400 unreadable, 422 readable
266-
but unrunnable, 413 too large) is what they have to render.
261+
- The running, failed and stale states are now real, because the page calls the
262+
engine. A run in flight dims the canvas and swaps Run for Stop; a failure
263+
turns the engine dot red, names the kind of failure from the status the
264+
server chose (400 unreadable, 422 readable but unrunnable, 413 too large) and
265+
opens the log with the engine's own message in it; a graph edited since the
266+
last run marks the results dock stale rather than leaving numbers on screen
267+
that answer a question no longer being asked.
268+
- What is still missing is the *empty* state, because there is no way yet to
269+
empty the canvas — blocks cannot be added or deleted. It arrives with the
270+
editing, not before it.

README.md

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ link in this simulator descends from.*
3535
> each channel's phase at twice the rate its own does, sliding past under walk-off derived from
3636
> the dispersion — and triplets of channels mix to put light where nobody launched it.
3737
>
38-
> The session server is in: `python -m maiman.server` puts the engine behind an HTTP API and a
39-
> browser can build a link, post it, and get real numbers back. What is still missing is the
40-
> editor — the canvas that lets you draw the graph instead of describing it. See the
38+
> The interface runs: `python -m maiman.server`, open the page, press Run, and the numbers come
39+
> from the engine. What is still missing is the *editing* — the canvas draws a fixed schematic,
40+
> so you can change what a block does but not which blocks there are. See the
4141
> [roadmap](#roadmap).
4242
>
4343
> This is not yet a useful simulator. It is a foundation with the expensive decisions made and
@@ -48,18 +48,34 @@ link in this simulator descends from.*
4848

4949
## The interface
5050

51-
**The engine is behind an API; the canvas is not wired to it yet.** The schematic, the component
52-
palette, the parameter panel and every number in the results dock come from a real engine run,
53-
exported by [`examples/export_ui_data.py`](examples/export_ui_data.py). What has changed is that
54-
those numbers no longer have to be exported ahead of time — see
55-
[the session server](#the-session-server) below. What has not changed is the page: it still draws
56-
one fixed schematic, and making it an editor is the next piece of work.
51+
**It runs.**
5752

5853
python -m maiman.server
5954

60-
serves it at `http://127.0.0.1:8765/`, or open
61-
[`docs/ui-mockup.html`](docs/ui-mockup.html) directly to click through it. See
62-
[DESIGN.md](DESIGN.md) for why it looks like this.
55+
then open `http://127.0.0.1:8765/`. Press Run and the page posts its graph to the engine and draws
56+
what comes back: the constellation, the measurements, the block captions, and a log in which every
57+
line is a fact from the response. Change a parameter in the inspector and run again, and the
58+
numbers move because the physics moved — set the fiber to 200 km and the received power drops by
59+
exactly the 24 dB the extra loss costs, while the constellation collapses, because the dispersion
60+
compensator is still set for the old span.
61+
62+
**The canvas draws the project document itself.** The blocks, the wires and the parameter values
63+
are not written into the page. They are read from the same `.maiman` document the server accepts,
64+
exported from the graph that produced the reference numbers, and Run posts that object straight
65+
back. So the picture on the canvas, the values in the inspector and the graph the engine executes
66+
are one description instead of three kept in agreement by hand — the hand-written copy that used
67+
to live in the page had already drifted, and was missing four of the fiber's parameters.
68+
69+
**What it is not yet: an editor.** You can select a block, change its parameters and run. You
70+
cannot add a block, delete one, move one, or draw a wire — the canvas is still a fixed schematic.
71+
That is the React Flow work, and it is the next piece.
72+
73+
The page also still opens straight off disk with nothing running, which is how it should be read
74+
if you only want to look. It says which mode it is in rather than leaving it to be inferred: a
75+
badge in the results dock reads **live** when the numbers came from this session's last run,
76+
**stale — graph edited** when the graph has changed since, and **reference** when they came from
77+
the run baked into the file. Numbers from four days ago and numbers from the last click must never
78+
look alike. See [DESIGN.md](DESIGN.md) for why the rest of it looks like this.
6379

6480
![The Maiman Studio schematic editor on its paper ground](docs/images/studio-paper.png)
6581

@@ -639,7 +655,7 @@ time window, and results are reproducible.
639655
| **1 — MVP: linear link** *(essentially done)* | ✅ PRBS → NRZ → laser → MZM → fiber (α + CD) → PIN → filter → eye/Q/BER, validated end to end. **Python only, no GUI.** | ~2–3 months |
640656
| **1.5 — Nonlinear & amplified**| Adaptive-step SSFM, Kerr, EDFA with ASE, OSNR, PMD, APD | ~2 months |
641657
| **2 — Coherent transceiver**| Gray-coded M-QAM to 256, IQ modulator with bias and quadrature error, 90° hybrid, balanced detection, blind carrier phase recovery, dual polarization with a blind butterfly equaliser, root-raised-cosine shaping and matched filtering, differential quadrant encoding, receiver-side dispersion compensation over spans to 1000 km, EVM/MER, constellation diagram, validated against closed-form SER | ~3 months |
642-
| **3 — GUI & WDM** | ✅ Wavelength-selective filters, an OSA, coupled-channel propagation (XPM with walk-off, FWM), and the session server. React Flow graph editor · 400G/800G references, CuPy back-end | ~6 months |
658+
| **3 — GUI & WDM** | ✅ Wavelength-selective filters, an OSA, coupled-channel propagation (XPM with walk-off, FWM), the session server, and a browser that runs the graph and edits its parameters. React Flow canvas — add, wire and move blocks · 400G/800G references, CuPy back-end | ~6 months |
643659
| **4 — PIC** | Waveguides, ring resonators, MMI, MZI via integration with an existing S-matrix solver; PDK import ||
644660

645661
¹ One developer, part-time. Estimates, not commitments.

docs/images/studio-graphite.png

-859 Bytes
Loading

docs/images/studio-paper.png

-774 Bytes
Loading

0 commit comments

Comments
 (0)