You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 3c51f11
Browse filesBrowse the repository at this point in the historyBrowse files
docs(diagrams): what the review round changed, and what was run again
RICH-DIAGRAMS.md after the #104 review round.
What it now says about the feature: which call counts as a diagram's repair
(its title or its nodes, as the ladder reads them); that a reopened chat shows
what the live one showed — prose and pictures in the order they were written,
one diagram one card, a replaced drawing gone from both; that a replaced
drawing is not handed back to the model; that the full-size view is modal and
is opened by a button of its own; that a saved SVG carries no links; and that
a name arriving from outside is never used to index a plain object by itself.
One new known limit: a repaired diagram is drawn live where its first attempt
was waiting, and a reopened session shows it at the call that got it right.
And the numbers, as run on this tree: 270 tests in the twelve diagram suites
(from 252), 186 checks in the browser (from 155), 19 in the real editor (from
17), the gate on macOS and in the Linux container, the suites with every timer
delayed, and 69 single-edit mutations against this round's changes, all caught
after two gaps were closed. The first mutation set was not run again, and the
doc says so. The count of suite files in the whole gate is gone from the
sentence about it: it goes stale with every branch that adds a test file.
Copy file name to clipboardExpand all lines: docs/RICH-DIAGRAMS.md
+55-18Lines changed: 55 additions & 18 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -217,10 +217,24 @@ per run (three bounces across all diagrams, after which every call is final). A
217
217
waiting on its repair when the run ends — the model gave up, hit its step limit, or was stopped — is
218
218
settled from its last attempt before `agentDone`, so no placeholder is left spinning.
219
219
220
+
**Which call repairs which diagram.** The next call is the waiting diagram's repair when it has the
221
+
same title, or at least half the same node ids — as the ladder *reads* them, not as they arrived.
222
+
A corrected spec is the same diagram whether it comes as an object, as JSON text with a trailing
223
+
comma, inside a `{"spec": …}` envelope or with `name` for `title`. A call for a different diagram
224
+
settles the one that was waiting, from its last attempt, and is a first attempt of its own. Drawing
225
+
the same title again later in a run is a redraw: the new drawing replaces the earlier one.
226
+
220
227
**Storage.** The final record — spec, status, fixes, notes — is written to the session's event log
221
228
after the turn. Reopening a chat replays records; no model is asked anything, and a valid record
222
229
comes back exactly as it was stored.
223
230
231
+
A reopened chat shows what the live one showed. A message that says something, draws, and says more
232
+
is replayed — and exported as Markdown — in that order: prose, picture, prose, under one speaker
233
+
label. A drawing that a later one replaced stays on file (the log is append-only) but is not
234
+
replayed; the live chat removes its card when the redraw arrives. One diagram is one card either
235
+
way: a repair fills the placeholder its first attempt left, a redraw stands where the model drew it
236
+
again, and a different diagram never takes over a card that shows another.
237
+
224
238
A session file is input too — it can be edited, cut short, or written by an older build — so a
225
239
stored spec is checked like a model's: by the host when the session is loaded (before a link can be
226
240
opened or a file exported from it) and by the webview before it is drawn. The check is
@@ -248,6 +262,13 @@ zero-width and bidirectional-override characters before it is stored.
248
262
if one does, and a suite checks it.
249
263
- A linked node carries `data-lc-link` = its node id. A click sends that id; the host looks the
250
264
path up in its own record and resolves it again. A path is never taken from the page.
265
+
- A name that arrives from outside is never used to index a plain object on its own. A model id, a
266
+
tool call's id, a schema version and a word written for `shape` are all text somebody else chose,
267
+
and `constructor` and `__proto__` are on every object: looked up carelessly, a version called
268
+
`toString` "was" a schema and a model called `__proto__` wrote to the prototype all objects share.
269
+
The counters read and write own entries only, a version must be one of the numbers this editor
270
+
reads, the synonym tables are asked for their own words, and the page's table of cards has no
271
+
prototype. A test feeds those names through each.
251
272
252
273
**The host accepts four actions, not two.** The spec lists `openLink` and `export`. Its own UX
253
274
section also puts a Retry button on degraded diagrams and promises a text fallback when rendering
@@ -271,11 +292,11 @@ title after secret redaction.
271
292
| --- | --- |
272
293
| While streaming | A placeholder card appears when the call starts; the title fills in as soon as it has streamed; the picture replaces it |
273
294
| Code links | A small file icon; click or Enter opens the file at the symbol (document symbols, then a text search, then the line); hover shows the path |
274
-
| Zoom and pan | Diagrams larger than the column are scaled to fit; click opens a full-panel view with zoom, pan, fit and Esc |
275
-
| Toolbar |Copy source, save SVG, save PNG, open as Mermaid, insert into a Markdown file |
295
+
| Zoom and pan | Diagrams larger than the column are scaled to fit. The toolbar's Full size button — or a click on the picture — opens a full-panel view with zoom, pan, fit and Esc. That view is modal: the page behind it is inert, Tab stays inside it, and closing it returns the focus to where it was|
296
+
| Toolbar |Full size, copy source, save SVG, save PNG, open as Mermaid, insert into a Markdown file |
276
297
| Repair states | "auto-fixed" badge with a details popover; degraded banner listing each loss, plus Retry |
| Accessibility | The title is the accessible name; a text outline (nodes, then edges, in reading order) is attached for screen readers; linked nodes are focusable |
299
+
| Accessibility | The title is the accessible name; a text outline (nodes, then edges, in reading order) is attached for screen readers; linked nodes are focusable and open with Enter or Space, in the chat and in the full-size view. The picture itself is not a control — Full size is a button of its own — so a linked node is never a control inside another. In a saved SVG a linked node keeps its file icon and tooltip but is not a link: a file has nothing to open it with |
279
300
| Fallback | Two ways rendering can be unavailable, one answer. If painting throws, the page draws the spec with characters itself. If the diagram modules never loaded, the page asks the host, which draws it from its own record. Either way it is the same layout on a character grid, fitted to the card's width, in a monospaced block, under a line saying that a text version is being shown. Source stays one click away |
280
301
281
302
The text fallback is made of plain ASCII — a shortened label ends in three dots there, not an
@@ -310,7 +331,9 @@ answers in prose.
310
331
summarized range becomes `[draws a diagram: <title>]` in the summary input, and the summary is
311
332
followed by one stub line per diagram (`diagram: <title>, 4 nodes, id d-17`). From then on the
312
333
model is also offered `get_diagram`, which returns the full spec by id. Resuming a session whose
313
-
history was shortened does the same.
334
+
history was shortened does the same. A drawing that a later one replaced gets no stub — the model
335
+
is handed back what the user can see — and asked for by its old id, `get_diagram` answers with
336
+
the id of the drawing that took its place.
314
337
-**Retention** (an open question). A spec is kept as long as its session file is. There is no
315
338
separate expiry.
316
339
-**Repair tokens.** The repair pass is an ordinary agent turn, so it is counted, metered and
@@ -378,6 +401,10 @@ on the default models, then use it for a week and read the counters.
378
401
narrow frames. None has a line *through* an unbacked name, and none of the gallery diagrams needs
379
402
a backing at any width from 320 px up. Making room instead costs width: grouped top-to-bottom
380
403
random specs are 0.6% wider on average and at most 121 px. The suite fails above 10% backed.
404
+
-**Where a repaired diagram stands.** While the run is live, a repaired diagram is drawn where its
405
+
first attempt was waiting. A reopened session shows it at the call that got it right — below
406
+
anything the model wrote between the two. The cards are the same; the place can differ by that
407
+
much.
381
408
-**Text fallback width.** Character widths follow the common Unicode ranges, not the whole
382
409
standard; an unusual script or a font with its own ideas can still put a box edge one cell out.
383
410
-**Time to picture is unmeasured in a real editor.** Layout is fast; font loading, DOM work and
@@ -391,28 +418,38 @@ on the default models, then use it for a week and read the counters.
391
418
392
419
Verified:
393
420
394
-
- 12 suites, 252 tests (`test/diagram*.test.js`), including a 1,500-spec layout fuzz, the corpus,
421
+
- 12 suites, 270 tests (`test/diagram*.test.js`), including a 1,500-spec layout fuzz, the corpus,
395
422
SVG snapshots in both palettes, the gallery at chat-panel widths, the real `runAgent` loop with a
396
-
scripted provider, and the host functions sliced out of `extension.js` against a `vscode`
397
-
stand-in.
398
-
- The whole gate (`./scripts/test-extensions.sh`, 62 suite files) on macOS arm64 with Node 24, and
399
-
on Linux (Ubuntu 22.04 arm64, Node 18) in a container with no network and a read-only checkout.
400
-
The diagram suites also pass with every timer delayed by 15 ms.
423
+
scripted provider, the host functions sliced out of `extension.js` against a `vscode` stand-in,
424
+
and the page's own card bookkeeping run against a stand-in for the few DOM calls it makes.
425
+
- The whole gate (`./scripts/test-extensions.sh`) on macOS arm64 with Node 24, and on Linux (Ubuntu
426
+
22.04 arm64, Node 18) in a container with no network and a read-only checkout. The diagram suites
427
+
also pass with every timer delayed by 15 ms.
401
428
-`scripts/diagram-browser-check.js`: the real `chat.html` in headless Chrome under the real CSP —
402
-
light and dark, hostile labels, links, exports, a painter that throws, and the page with no
403
-
diagram modules at all — 155 checks, with no CSP violation and no resource request. Each step
404
-
waits for its result rather than for a length of time.
429
+
light and dark, hostile labels, links, exports, a painter that throws, the full-size view's
430
+
focus, and the page with no diagram modules at all — 186 checks, with no CSP violation and no
431
+
resource request. Each step waits for its result rather than for a length of time. One of its
432
+
pages plays runs in the order a real run sends them — a placeholder at the start of every call —
433
+
then replays the same conversation as a reopened session, and compares the two: a repair, a
434
+
repair written as loose JSON, a redraw, a change of subject mid-repair, tool calls named
435
+
`__proto__` and `constructor`, and a picture between two pieces of prose.
405
436
- Mutation testing: 147 single-edit defects seeded across the modules, the host glue, the page and
406
437
the eval harness, each run against the suite that should notice (and only after that suite
407
438
passed on the unmutated copy). Ten survived at first: three were redundant code (removed or
408
-
simplified), seven were gaps in the suites (closed). All 144 that still apply are caught.
439
+
simplified), seven were gaps in the suites (closed). All 144 that still apply were caught. The
440
+
review round after the pull request was opened seeded 69 more against what it changed — 57
441
+
against the plain-Node suites, 12 against the browser check. Two survived at first, both gaps in
442
+
the page's card tests (nothing looked at *where* a redraw stands, or at a card that went with a
443
+
wiped transcript); both are closed and all 69 are caught. (The first set was not run again after
444
+
that round.)
409
445
410
446
-`scripts/diagram-editor-check.js`: the real editor. A second, throwaway instance of the dev build
411
447
loads this checkout's extension, talks to a stand-in provider on localhost, and is driven through
412
-
the DevTools protocol — 17 checks: the tool and its rules reach the model, the diagram is painted
413
-
in the real webview in the editor's theme, a linked node opens its file at the symbol, the session
414
-
on disk holds the diagram, a wider column re-lays it out, and the answer around it renders as
415
-
Markdown. (Added after the feature was first called done without ever having run in the editor.)
448
+
the DevTools protocol — 19 checks: the tool and its rules reach the model, the diagram is painted
449
+
in the real webview in the editor's theme, the full-size view opens from its button and is modal
450
+
there, a linked node opens its file at the symbol, the session on disk holds the diagram, a wider
451
+
column re-lays it out, and the answer around it renders as Markdown. (Added after the feature was
452
+
first called done without ever having run in the editor.)
0 commit comments