Agent A renders. Agent B audits and patches. Agent A applies the patch and re-renders. Same JSON. Same SVG bytes. The collaboration demo no other chart library can run — because no other library is byte-deterministic and patchable as JSON.
The user has a CSV of bicycle rides and asks for a chart. Two agents are in the room: Agent A, the renderer, and Agent B, the auditor. Both speak MCP, both have Glyph installed (claude mcp add glyph -- npx -y @glyph/mcp), and they share the same scratch space.
Their contract is simple: Agent A writes Glyph JSON specs, Agent B finds problems, Agent B emits RFC 6902 patches, Agent A applies them. Neither agent regenerates the chart from scratch on each iteration — that would lose the byte-determinism trail.
Agent A sees the CSV and drafts a bar chart of rides per hour. It calls glyph_render with this spec:
{
"version": "glyph/0.1",
"title": "Bike rides by hour",
"data": { "source": "rides.csv" },
"layers": [{
"mark": "bar",
"encoding": {
"x": { "field": "hour", "type": "ordinal" },
"y": { "field": "rides", "type": "quantitative" }
}
}]
}
Glyph emits an SVG and an Explanation envelope back. The envelope records the resolved scale domains, the SHA-256 seal, and any audit warnings. Agent A passes the spec, the SVG, and the envelope to Agent B.
Agent B calls glyph_audit_spec on the same spec. Glyph's auditor returns a structured list of findings:
{
"findings": [
{
"severity": "warning",
"path": "/layers/0/encoding/y/scale",
"message": "y axis has no explicit domain; auto-fit may exaggerate variation",
"suggested_patch": [{
"op": "add",
"path": "/layers/0/encoding/y/scale",
"value": { "domain": [0, null] }
}]
},
{
"severity": "info",
"path": "/title",
"message": "title lacks units",
"suggested_patch": [{
"op": "replace",
"path": "/title",
"value": "Bike rides by hour (count per hour)"
}]
}
]
}
Agent B's job isn't to argue — it's to surface the problems. Agent A decides what to apply.
Agent A accepts both suggestions and emits an RFC 6902 patch:
[
{ "op": "add",
"path": "/layers/0/encoding/y/scale",
"value": { "domain": [0, null] } },
{ "op": "replace",
"path": "/title",
"value": "Bike rides by hour (count per hour)" }
]
Agent A applies the patch to its own spec, calls glyph_render again, and ships SVG v2 to the user. Because Glyph is byte-deterministic, every other agent (and every CI run) that applies the same patch to the same spec gets exactly the same bytes back. The whole conversation is reproducible.
[0, 1500]. Title carries units.These are the actual byte-locked fixtures from packages/core/__fixtures__/two-agents/. Both renders are deterministic and tested in CI — see two-agents.test.ts for the full assertion suite (parse → render → patch → re-render → byte-equal).
Determinism. Vega, Plotly, D3 all produce SVG whose bytes drift between platforms (subpixel rounding, ID generation, timestamp embedding). Without byte-equality, "the same spec produced this byte stream" is not a verifiable claim.
Audit-as-a-verb. Glyph's MCP surface includes glyph_audit_spec — the auditor is part of the library, not a separate tool. The second agent doesn't need a custom reviewer prompt to identify chart problems.
JSON patches against a stable schema. Glyph specs are flat JSON validated by Zod. RFC 6902 patches against them are auditable, idempotent, and replayable. A Vega-Lite spec compiled to D3 code is none of those.
SHA-256 seal. Every rendered SVG carries the hash of (spec, rows, schema). Anyone, including Agent C, can verify the bytes correspond to the claimed spec without re-rendering.
Open two Claude conversations side by side (or one Claude conversation with two roles). In both, run claude mcp add glyph -- npx -y @glyph/mcp. Then:
Conversation 1 (you'll be Agent A): "Render a bar chart fromrides.csvshowing rides per hour. Save the spec tospec-v1.jsonand the SVG tochart-v1.svg." — prompt for Agent A
Conversation 2 (you'll be Agent B): "Loadspec-v1.json. Callglyph_audit_spec. For each finding with severity warning or higher, emit an RFC 6902 patch. Write the patch list topatch.json." — prompt for Agent B
Back in conversation 1: "Applypatch.jsontospec-v1.json, save asspec-v2.json, and re-render tochart-v2.svg." — prompt for Agent A again
Both chart-v1.svg and chart-v2.svg will be byte-identical to anyone else running the same prompts. That's the trick.