agentic-mermaid 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (340) hide show
  1. package/AGENT_NATIVE.md +155 -91
  2. package/CHANGELOG.md +163 -4
  3. package/Instructions_for_agents.md +10 -10
  4. package/LICENSES/Apache-2.0.txt +202 -0
  5. package/README.md +31 -38
  6. package/THIRD_PARTY_NOTICES.md +29 -0
  7. package/assets/hero.png +0 -0
  8. package/dist/agent-core.d.ts +463 -0
  9. package/dist/agent-core.js +397 -0
  10. package/dist/agent.d.ts +73 -1868
  11. package/dist/agent.js +336 -37325
  12. package/dist/agentic-mermaid-mcp.js +7 -38399
  13. package/dist/am.js +33626 -40446
  14. package/dist/chunk-2P5FKUQC.js +3485 -0
  15. package/dist/chunk-2S3VSS6I.js +149 -0
  16. package/dist/chunk-2SILJDW2.js +37 -0
  17. package/dist/chunk-BJYMBT4I.js +61963 -0
  18. package/dist/chunk-FDM43XU7.js +615 -0
  19. package/dist/chunk-MYPDVZCO.js +4702 -0
  20. package/dist/index-DWPa2MJs.d.ts +6780 -0
  21. package/dist/index.d.ts +1 -1
  22. package/dist/index.js +310 -33014
  23. package/dist/mcp-cli-5J47WEY3.js +17 -0
  24. package/docs/README.md +39 -31
  25. package/docs/agent-api-cookbook.md +44 -35
  26. package/docs/agent-mutation-policy.md +1 -1
  27. package/docs/agent-workflow-examples.md +2 -2
  28. package/docs/api.md +284 -77
  29. package/docs/ascii.md +26 -16
  30. package/docs/code-mode-impact.md +214 -0
  31. package/docs/comparison.md +23 -11
  32. package/docs/computational-aesthetics-prototype-plan.md +252 -0
  33. package/docs/config.md +26 -10
  34. package/docs/custom-fonts.md +265 -0
  35. package/docs/custom-style-cookbook.md +130 -9
  36. package/docs/diagram-families.md +48 -23
  37. package/docs/features.md +59 -52
  38. package/docs/fork-differences.md +6 -3
  39. package/docs/getting-started.md +23 -16
  40. package/docs/issue-derived-test-cases.md +29 -22
  41. package/docs/mcp-code-mode-rationale.md +13 -6
  42. package/docs/mcp-http-transport.md +20 -13
  43. package/docs/mermaid-layout-complaints.md +66 -52
  44. package/docs/mutation-testing.md +145 -66
  45. package/docs/quality.md +23 -14
  46. package/docs/react.md +2 -2
  47. package/docs/schemas/style-spec.schema.json +1221 -30
  48. package/docs/style-authoring.md +241 -38
  49. package/docs/svg-semantic-contract.md +49 -0
  50. package/docs/testing-strategy.md +166 -58
  51. package/docs/theming.md +19 -32
  52. package/examples/styles/catalog.json +54 -0
  53. package/examples/styles/cloudflare-workers-inspired-prototype.mmd +9 -0
  54. package/examples/styles/cloudflare-workers-inspired-prototype.style.json +110 -0
  55. package/examples/styles/cupertino-prototype.mmd +10 -0
  56. package/examples/styles/cupertino-prototype.style.json +63 -0
  57. package/examples/styles/mid-century-report.style.json +2 -2
  58. package/examples/styles/star-chart-atlas.style.json +2 -1
  59. package/examples/styles/transit-route-map.style.json +2 -2
  60. package/examples/styles/vercel-inspired-prototype.mmd +6 -0
  61. package/examples/styles/vercel-inspired-prototype.style.json +87 -0
  62. package/package.json +85 -45
  63. package/server.json +2 -2
  64. package/skills/agentic-mermaid-diagram-workflow/SKILL.md +17 -36
  65. package/skills/agentic-mermaid-diagram-workflow/references/cli.md +4 -5
  66. package/skills/agentic-mermaid-diagram-workflow/references/code-mode.md +15 -31
  67. package/skills/agentic-mermaid-diagram-workflow/references/sequence.md +10 -14
  68. package/skills/agentic-mermaid-live-editor/SKILL.md +100 -206
  69. package/TODO.md +0 -684
  70. package/dist/index-wjRjbsP-.d.ts +0 -1102
  71. package/docs/assets/improvements/box-start-connector.png +0 -0
  72. package/docs/assets/improvements/comment-dropped-lint.png +0 -0
  73. package/docs/assets/improvements/er-content-loss.png +0 -0
  74. package/docs/assets/improvements/fan-in-trunks.png +0 -0
  75. package/docs/assets/improvements/gantt-family.png +0 -0
  76. package/docs/assets/improvements/gantt-milestone-clamp.png +0 -0
  77. package/docs/assets/improvements/gantt-verify-seam.png +0 -0
  78. package/docs/assets/improvements/subgraph-container-edges.png +0 -0
  79. package/docs/assets/improvements/wrapper-frontmatter.png +0 -0
  80. package/docs/assets/improvements/wrapper-init-directive.png +0 -0
  81. package/docs/assets/improvements/wrapper-leading-comment.png +0 -0
  82. package/docs/assets/style-cookbook/mid-century-report.png +0 -0
  83. package/docs/assets/style-cookbook/star-chart-atlas.png +0 -0
  84. package/docs/assets/style-cookbook/transit-route-map.png +0 -0
  85. package/docs/contributing/adding-diagram-types.md +0 -144
  86. package/docs/contributing/diagram-family-citizenship.matrix.json +0 -2127
  87. package/docs/contributing/diagram-family-citizenship.md +0 -82
  88. package/docs/contributing/harvesting-upstream-tests.md +0 -126
  89. package/docs/contributing/lessons-learned.md +0 -276
  90. package/docs/contributing/releasing.md +0 -82
  91. package/docs/contributing/visual-review-evidence.md +0 -53
  92. package/docs/design/families/README.md +0 -26
  93. package/docs/design/families/architecture-beta.md +0 -48
  94. package/docs/design/families/flowchart-parser-conformance.md +0 -22
  95. package/docs/design/families/gantt-research.md +0 -137
  96. package/docs/design/families/gantt.md +0 -329
  97. package/docs/design/families/journey-agentic-cards-before.png +0 -0
  98. package/docs/design/families/journey-experience-curve-implementation.png +0 -0
  99. package/docs/design/families/journey-mermaid-classic-implementation.png +0 -0
  100. package/docs/design/families/journey-mermaid-classic-prototype.png +0 -0
  101. package/docs/design/families/journey-mermaid-classic-prototype.svg +0 -163
  102. package/docs/design/families/journey-mermaid-classic-prototype.svg.png +0 -0
  103. package/docs/design/families/journey-migration-parity.md +0 -439
  104. package/docs/design/families/journey-section-overlap-after.png +0 -0
  105. package/docs/design/families/journey-section-overlap-before.png +0 -0
  106. package/docs/design/families/journey-usage-research.md +0 -423
  107. package/docs/design/families/journey.md +0 -153
  108. package/docs/design/families/xychart.md +0 -85
  109. package/docs/design/system/README.md +0 -45
  110. package/docs/design/system/abstraction-audit.md +0 -224
  111. package/docs/design/system/abstraction-recommendations.md +0 -655
  112. package/docs/design/system/architecture.mmd +0 -29
  113. package/docs/design/system/architecture.svg +0 -137
  114. package/docs/design/system/layout-guarantees-and-robustness.md +0 -351
  115. package/docs/design/system/layout-rubric.md +0 -138
  116. package/docs/design/system/route-contracts.md +0 -848
  117. package/docs/design/system/source-preservation-ladder.md +0 -52
  118. package/docs/design/system/styles-rollout.md +0 -216
  119. package/docs/design/system/ugly-layouts.md +0 -119
  120. package/docs/layout-characterization/README.md +0 -245
  121. package/docs/layout-characterization/contact-sheet-families.md +0 -498
  122. package/docs/layout-characterization/contact-sheet.md +0 -638
  123. package/docs/layout-characterization/properties.md +0 -281
  124. package/docs/layout-characterization/visual-quality.md +0 -160
  125. package/docs/layout-characterization/visual-snapshots/architecture.svg +0 -79
  126. package/docs/layout-characterization/visual-snapshots/class.svg +0 -60
  127. package/docs/layout-characterization/visual-snapshots/er.svg +0 -61
  128. package/docs/layout-characterization/visual-snapshots/flowchart.svg +0 -58
  129. package/docs/layout-characterization/visual-snapshots/gantt.svg +0 -52
  130. package/docs/layout-characterization/visual-snapshots/journey.svg +0 -98
  131. package/docs/layout-characterization/visual-snapshots/pie.svg +0 -36
  132. package/docs/layout-characterization/visual-snapshots/quadrant.svg +0 -47
  133. package/docs/layout-characterization/visual-snapshots/sequence.svg +0 -59
  134. package/docs/layout-characterization/visual-snapshots/state.svg +0 -52
  135. package/docs/layout-characterization/visual-snapshots/timeline.svg +0 -64
  136. package/docs/layout-characterization/visual-snapshots/xychart.svg +0 -97
  137. package/docs/project/divergences.md +0 -98
  138. package/docs/project/dogfooding-docs-strategy.md +0 -66
  139. package/docs/project/hosted-mcp-cloudflare-plan.md +0 -338
  140. package/docs/project/lessons-learned.md +0 -1019
  141. package/docs/project/remove-role-styling-plan.md +0 -176
  142. package/examples/agent-improve-auth-flow.ts +0 -206
  143. package/examples/agent-loop.ts +0 -53
  144. package/examples/mcp-vs-cli-complex-diagrams.ts +0 -133
  145. package/llms.txt +0 -104
  146. package/skill-evals/README.md +0 -77
  147. package/skill-evals/fixtures/architecture-cache/input.mmd +0 -5
  148. package/skill-evals/fixtures/class-payment/input.mmd +0 -4
  149. package/skill-evals/fixtures/er-orders/input.mmd +0 -10
  150. package/skill-evals/fixtures/flowchart-cache/input.mmd +0 -3
  151. package/skill-evals/fixtures/gantt-release/input.mmd +0 -7
  152. package/skill-evals/fixtures/journey-checkout/input.mmd +0 -6
  153. package/skill-evals/fixtures/pie-exports/input.mmd +0 -5
  154. package/skill-evals/fixtures/quadrant-priorities/input.mmd +0 -11
  155. package/skill-evals/fixtures/sequence-retry/input.mmd +0 -8
  156. package/skill-evals/fixtures/state-lifecycle/input.mmd +0 -5
  157. package/skill-evals/fixtures/timeline-release/input.mmd +0 -6
  158. package/skill-evals/fixtures/xychart-growth/input.mmd +0 -5
  159. package/skill-evals/shared-benchmark.json +0 -510
  160. package/src/agent/analyze.ts +0 -157
  161. package/src/agent/apply.ts +0 -146
  162. package/src/agent/architecture-body.ts +0 -458
  163. package/src/agent/certificates.ts +0 -110
  164. package/src/agent/class-body.ts +0 -319
  165. package/src/agent/core.ts +0 -207
  166. package/src/agent/create.ts +0 -106
  167. package/src/agent/describe.ts +0 -368
  168. package/src/agent/er-body.ts +0 -224
  169. package/src/agent/facts.ts +0 -360
  170. package/src/agent/families-builtin.ts +0 -920
  171. package/src/agent/families.ts +0 -232
  172. package/src/agent/family-layouts.ts +0 -832
  173. package/src/agent/flowchart-body.ts +0 -372
  174. package/src/agent/flowchart-unsupported.ts +0 -243
  175. package/src/agent/font-coverage.ts +0 -288
  176. package/src/agent/gantt-body.ts +0 -495
  177. package/src/agent/index.ts +0 -10
  178. package/src/agent/journey-body.ts +0 -374
  179. package/src/agent/label-metrics.ts +0 -28
  180. package/src/agent/layout-to-rendered.ts +0 -63
  181. package/src/agent/mutate.ts +0 -97
  182. package/src/agent/mutation-ops.ts +0 -51
  183. package/src/agent/op-schema.ts +0 -443
  184. package/src/agent/parse.ts +0 -223
  185. package/src/agent/pie-body.ts +0 -270
  186. package/src/agent/png.ts +0 -171
  187. package/src/agent/quadrant-body.ts +0 -336
  188. package/src/agent/quality.ts +0 -363
  189. package/src/agent/readability-audit.ts +0 -92
  190. package/src/agent/rendered-route-audit.ts +0 -61
  191. package/src/agent/sequence-body.ts +0 -345
  192. package/src/agent/serialize.ts +0 -214
  193. package/src/agent/state-body.ts +0 -589
  194. package/src/agent/structural-count.ts +0 -150
  195. package/src/agent/timeline-body.ts +0 -280
  196. package/src/agent/trace-log.ts +0 -43
  197. package/src/agent/types.ts +0 -995
  198. package/src/agent/verify.ts +0 -603
  199. package/src/agent/xychart-body.ts +0 -472
  200. package/src/architecture/config.ts +0 -282
  201. package/src/architecture/layout.ts +0 -496
  202. package/src/architecture/parser.ts +0 -375
  203. package/src/architecture/renderer.ts +0 -611
  204. package/src/architecture/types.ts +0 -113
  205. package/src/ascii/ansi.ts +0 -423
  206. package/src/ascii/architecture.ts +0 -210
  207. package/src/ascii/canvas.ts +0 -443
  208. package/src/ascii/class-diagram.ts +0 -697
  209. package/src/ascii/converter.ts +0 -475
  210. package/src/ascii/draw.ts +0 -1693
  211. package/src/ascii/edge-bundling.ts +0 -328
  212. package/src/ascii/edge-routing.ts +0 -330
  213. package/src/ascii/er-diagram.ts +0 -439
  214. package/src/ascii/gantt.ts +0 -276
  215. package/src/ascii/grid.ts +0 -747
  216. package/src/ascii/index.ts +0 -196
  217. package/src/ascii/journey.ts +0 -169
  218. package/src/ascii/meta.ts +0 -244
  219. package/src/ascii/multiline-utils.ts +0 -80
  220. package/src/ascii/pathfinder.ts +0 -301
  221. package/src/ascii/pie.ts +0 -67
  222. package/src/ascii/quadrant.ts +0 -158
  223. package/src/ascii/reverse.ts +0 -216
  224. package/src/ascii/sequence.ts +0 -499
  225. package/src/ascii/shapes/circle.ts +0 -27
  226. package/src/ascii/shapes/corners.ts +0 -143
  227. package/src/ascii/shapes/diamond.ts +0 -27
  228. package/src/ascii/shapes/hexagon.ts +0 -27
  229. package/src/ascii/shapes/index.ts +0 -106
  230. package/src/ascii/shapes/rectangle.ts +0 -168
  231. package/src/ascii/shapes/rounded.ts +0 -27
  232. package/src/ascii/shapes/special.ts +0 -332
  233. package/src/ascii/shapes/stadium.ts +0 -110
  234. package/src/ascii/shapes/state.ts +0 -192
  235. package/src/ascii/shapes/types.ts +0 -73
  236. package/src/ascii/timeline.ts +0 -141
  237. package/src/ascii/types.ts +0 -312
  238. package/src/ascii/validate.ts +0 -120
  239. package/src/ascii/width.ts +0 -81
  240. package/src/ascii/wrap.ts +0 -131
  241. package/src/ascii/xychart.ts +0 -919
  242. package/src/browser.ts +0 -29
  243. package/src/class/layout.ts +0 -240
  244. package/src/class/parser.ts +0 -332
  245. package/src/class/renderer.ts +0 -638
  246. package/src/class/types.ts +0 -129
  247. package/src/cli/agent-instructions.ts +0 -1
  248. package/src/cli/am-bin.ts +0 -6
  249. package/src/cli/exit-codes.ts +0 -18
  250. package/src/cli/index.ts +0 -1132
  251. package/src/cli/init-agent.ts +0 -147
  252. package/src/cli/run-entrypoint.ts +0 -10
  253. package/src/color-resolver.ts +0 -152
  254. package/src/elk-instance.ts +0 -114
  255. package/src/er/layout.ts +0 -187
  256. package/src/er/parser.ts +0 -226
  257. package/src/er/renderer.ts +0 -792
  258. package/src/er/types.ts +0 -99
  259. package/src/family-rubric.ts +0 -425
  260. package/src/font-manifest.ts +0 -31
  261. package/src/gantt/layout.ts +0 -365
  262. package/src/gantt/parser.ts +0 -282
  263. package/src/gantt/pipeline.ts +0 -27
  264. package/src/gantt/renderer.ts +0 -414
  265. package/src/gantt/schedule.ts +0 -513
  266. package/src/gantt/types.ts +0 -255
  267. package/src/index.ts +0 -368
  268. package/src/journey/layout.ts +0 -554
  269. package/src/journey/parse-core.ts +0 -251
  270. package/src/journey/parser.ts +0 -101
  271. package/src/journey/renderer.ts +0 -917
  272. package/src/journey/types.ts +0 -144
  273. package/src/layout/geometry.ts +0 -182
  274. package/src/layout/pass.ts +0 -142
  275. package/src/layout/passes/index.ts +0 -3916
  276. package/src/layout-engine.ts +0 -1565
  277. package/src/layout-rubric.ts +0 -659
  278. package/src/mcp/artifacts.ts +0 -137
  279. package/src/mcp/dynamic-harness.ts +0 -31
  280. package/src/mcp/dynamic-modules.d.ts +0 -7
  281. package/src/mcp/facade.ts +0 -608
  282. package/src/mcp/harness-runtime.ts +0 -203
  283. package/src/mcp/hosted-server.ts +0 -468
  284. package/src/mcp/mcp-bin.ts +0 -3
  285. package/src/mcp/mcp-cli.ts +0 -82
  286. package/src/mcp/protocol.ts +0 -13
  287. package/src/mcp/sandbox.ts +0 -195
  288. package/src/mcp/sdk-decl.ts +0 -391
  289. package/src/mcp/server.ts +0 -362
  290. package/src/mcp/tool-surface.ts +0 -146
  291. package/src/mermaid-source.ts +0 -655
  292. package/src/multiline-utils.ts +0 -228
  293. package/src/parser.ts +0 -1031
  294. package/src/pie/layout.ts +0 -168
  295. package/src/pie/parser.ts +0 -136
  296. package/src/pie/renderer.ts +0 -234
  297. package/src/pie/types.ts +0 -82
  298. package/src/quadrant/layout.ts +0 -191
  299. package/src/quadrant/parser.ts +0 -183
  300. package/src/quadrant/renderer.ts +0 -322
  301. package/src/quadrant/types.ts +0 -113
  302. package/src/render-family-hooks.ts +0 -244
  303. package/src/renderer.ts +0 -1099
  304. package/src/route-contracts.ts +0 -2723
  305. package/src/scene/backend.ts +0 -76
  306. package/src/scene/fidelity.ts +0 -183
  307. package/src/scene/hybrid-backend.ts +0 -174
  308. package/src/scene/ir.ts +0 -181
  309. package/src/scene/marks.ts +0 -127
  310. package/src/scene/rough-backend.ts +0 -378
  311. package/src/scene/seed.ts +0 -46
  312. package/src/scene/style-registry.ts +0 -556
  313. package/src/sequence/layout.ts +0 -456
  314. package/src/sequence/parser.ts +0 -255
  315. package/src/sequence/renderer.ts +0 -604
  316. package/src/sequence/types.ts +0 -154
  317. package/src/shape-clipping.ts +0 -351
  318. package/src/shared/accessibility-directives.ts +0 -22
  319. package/src/shared/batched.ts +0 -61
  320. package/src/shared/color-math.ts +0 -93
  321. package/src/shared/svg-a11y.ts +0 -29
  322. package/src/shared/syntax-error.ts +0 -17
  323. package/src/shared/unicode-ranges.ts +0 -135
  324. package/src/styles.ts +0 -318
  325. package/src/svg-paths.ts +0 -28
  326. package/src/text-metrics.ts +0 -248
  327. package/src/theme.ts +0 -710
  328. package/src/timeline/layout.ts +0 -381
  329. package/src/timeline/parser.ts +0 -215
  330. package/src/timeline/renderer.ts +0 -538
  331. package/src/timeline/types.ts +0 -105
  332. package/src/types.ts +0 -462
  333. package/src/website-worker-modules.d.ts +0 -18
  334. package/src/xychart/axis-utils.ts +0 -109
  335. package/src/xychart/colors.ts +0 -124
  336. package/src/xychart/config.ts +0 -88
  337. package/src/xychart/layout.ts +0 -656
  338. package/src/xychart/parser.ts +0 -504
  339. package/src/xychart/renderer.ts +0 -640
  340. package/src/xychart/types.ts +0 -282
@@ -0,0 +1,214 @@
1
+ # Code Mode in Agentic Mermaid: impact, comparison, and costs
2
+
3
+ Agentic Mermaid uses Code Mode to keep a diagram edit inside one execution:
4
+ parse the source, narrow it to a mutable family, apply typed operations, verify
5
+ the result, and serialize only after verification passes. This changes both
6
+ the model-facing boundary and the execution boundary. The model writes a small
7
+ algorithm instead of relaying each intermediate diagram through another tool
8
+ call, while the server retains the trusted diagram lineage needed to reject
9
+ forged or invalid edits.
10
+
11
+ This document uses **local Code Mode** for the self-hosted MCP process running
12
+ on the agent's machine and **hosted Code Mode** for the public
13
+ `https://agentic-mermaid.dev/mcp` endpoint. Cloudflare calls the same split
14
+ client-side and server-side Code Mode. The names describe where the sandbox
15
+ runs, not where the model runs.
16
+
17
+ ## Local Code Mode
18
+
19
+ The local `agentic-mermaid-mcp` exposes `execute(code)`, which runs synchronous
20
+ JavaScript against the typed `mermaid.*` SDK in a hardened `node:vm` context.
21
+ The execution can retain parsed diagrams between SDK calls, so the model does
22
+ not have to copy an intermediate representation into another JSON request.
23
+ That matters because Agentic Mermaid's mutation checks depend on provenance:
24
+ SDK results are read-only, and structured changes must pass through
25
+ `mermaid.mutate`.
26
+
27
+ Running beside the agent also keeps diagram source local and avoids hosted
28
+ compute charges. The local server can return managed PNG files or URLs through
29
+ its direct `render_png` helper, while multi-step editing remains in `execute`.
30
+ The [MCP Code Mode rationale](./mcp-code-mode-rationale.md) explains why those
31
+ helpers stay narrow rather than recreating the full SDK as individual tools.
32
+
33
+ Progressive SDK discovery removed the largest client-side cost. The initial
34
+ `execute` declaration now contains the core SDK, while
35
+ `describe_sdk({ family, detail })` returns the mutation schema for one diagram
36
+ family. An agent that already knows an operation can skip discovery; an agent
37
+ handling an unfamiliar family can request compact signatures or exact fields.
38
+
39
+ ## Hosted Code Mode
40
+
41
+ The hosted endpoint puts the sandbox behind the MCP server, so an ordinary MCP
42
+ client gets Code Mode without shipping its own execution environment. Each
43
+ hosted `execute` runs in a Cloudflare Dynamic Worker configured with an empty
44
+ environment, `globalOutbound: null`, no subrequests, and a bounded CPU budget.
45
+ The isolate configuration is the security boundary. The hardened SDK facade is
46
+ kept for behavioural parity with the local server.
47
+
48
+ Hosted execution has a per-call cost, so common pure operations do not enter
49
+ the sandbox. `render_svg`, `render_ascii`, `render_png`, `verify`, `describe`,
50
+ and `describe_sdk` run as ordinary Worker calls whose successful deterministic
51
+ results can be reused by the private server-side Workers Cache. The JSON-RPC
52
+ HTTP responses remain `cache-control: no-store`.
53
+ Declarative `mutate` and `build` apply typed operation lists through the same
54
+ mutation core and verify before returning source. They give smaller models a
55
+ direct path for routine edits while reserving `execute` for control flow that
56
+ the operation list cannot express.
57
+
58
+ Local and hosted Code Mode share the same `mermaid.*` facade. Differential
59
+ tests compare result envelopes, errors, trace behaviour, read-only enforcement,
60
+ and serialization across both runtimes. The
61
+ [hosted MCP as-built record](./project/archive/hosted-mcp-cloudflare-plan.md) documents
62
+ the remaining runtime differences and abuse controls.
63
+
64
+ ## Measured effect
65
+
66
+ [PR #157](https://github.com/adewale/agentic-mermaid/pull/157) measured the
67
+ serialized declarations and tool lists with `o200k_base`. These counts are a
68
+ stable before-and-after proxy, not a provider billing claim.
69
+
70
+ | Model-facing surface | Before | After | Tokens saved |
71
+ |---|---:|---:|---:|
72
+ | `execute` SDK declaration | 10,527 | 903 | 9,624 (91.4%) |
73
+ | Local `tools/list` | 11,781 | 1,840 | 9,941 (84.4%) |
74
+ | Hosted `tools/list` | 15,646 | 2,969 | 12,677 (81.0%) |
75
+
76
+ The median complete family schema is 495 tokens. A hosted client that loads the
77
+ initial tool list and then requests that schema consumes 3,464 tokens, 77.9%
78
+ less than the old hosted list. The largest family, flowchart, brings the total
79
+ to 4,928 tokens, which is still 68.5% lower. Compact signature responses have a
80
+ 113-token median.
81
+
82
+ The same PR ran four schema-sensitive edits against the exact before and after
83
+ hosted tool lists. Each proposed mutation was replayed through the real
84
+ `applyOps` implementation and checked against semantic facts.
85
+
86
+ | Model | Before task-correct | After task-correct | After discovery |
87
+ |---|---:|---:|---:|
88
+ | `gpt-5.4-mini` | 3/4 | 4/4 | 4/4 |
89
+ | `gpt-5.3-codex-spark` | 4/4 | 4/4 | 4/4 |
90
+ | **Combined** | **7/8** | **8/8** | **8/8** |
91
+
92
+ All 16 mutations across both conditions applied successfully. The one incorrect
93
+ before-case omitted a requested Architecture edge label; the after-case kept
94
+ it. The combined four-case prompt fell from 16,048 to 5,833 tokens, a 63.7%
95
+ reduction even though the test prompt included all four family responses at
96
+ once. A normal request discloses one family.
97
+
98
+ This eval is evidence for the discovery change, not a broad model-quality
99
+ claim. It covers four tasks and two small models. Larger task sets, more model
100
+ families, and production latency measurements remain separate work.
101
+
102
+ ## Comparison with Cloudflare and Anthropic
103
+
104
+ Agentic Mermaid applies Code Mode to a pure diagram library. Cloudflare and
105
+ Anthropic apply the same technique to general tool catalogs, where generated
106
+ code may call remote services and carry data between them. That scope
107
+ difference explains most of the implementation differences.
108
+
109
+ | Dimension | Agentic Mermaid | Cloudflare | Anthropic |
110
+ |---|---|---|---|
111
+ | Primary scope | One deterministic diagram SDK | MCP tools and large APIs | General tool catalogs |
112
+ | Discovery | `describe_sdk` for one diagram family | Typed connectors, or `search` over an OpenAPI document | Tool Search, or filesystem-shaped tool definitions |
113
+ | Model-written code | Synchronous JavaScript | Asynchronous JavaScript | Python in Programmatic Tool Calling |
114
+ | Execution | Local `node:vm` or hosted Dynamic Worker | Dynamic Worker isolate | Anthropic Code Execution sandbox |
115
+ | Calls made from code | Pure in-process SDK calls | MCP calls or an authenticated request callback | Developer-provided tools |
116
+ | External effects | None beyond returned diagram artifacts | Allowed through host-controlled bindings and authorization | Allowed for tools that opt into programmatic calling |
117
+ | Persistent state | None | Durable runtime options are available | Filesystem state and reusable skills are possible |
118
+
119
+ ### Cloudflare
120
+
121
+ Cloudflare's first Code Mode implementation converted connected MCP tools into
122
+ a TypeScript API and ran the model's JavaScript in a Dynamic Worker. Its current
123
+ MCP patterns cover both a single `code` tool, where the complete generated API
124
+ fits in the tool description, and `search` plus `execute`, where a large
125
+ OpenAPI document stays inside the discovery sandbox. Authentication remains in
126
+ the host callback rather than entering generated code.
127
+
128
+ That general implementation supports asynchronous calls, remote APIs,
129
+ authorization and, in the durable runtime, pause-and-resume approval. Agentic
130
+ Mermaid does not need those facilities because its SDK calls are synchronous,
131
+ pure, and confined to one diagram transaction. It does use the same Dynamic
132
+ Worker substrate for hosted isolation, but it does not depend on
133
+ `@cloudflare/codemode`.
134
+
135
+ Cloudflare measured its server-side `search` and `execute` surface at roughly
136
+ 1,000 tokens for more than 2,500 API endpoints, 99.9% fewer than direct MCP
137
+ definitions. Agentic Mermaid's percentage is not directly comparable because
138
+ its catalog is smaller and its hosted tool list retains more direct helpers.
139
+
140
+ Sources: [original Code Mode design](https://blog.cloudflare.com/code-mode/),
141
+ [server-side API implementation](https://blog.cloudflare.com/code-mode-mcp/),
142
+ and [current MCP server patterns](https://developers.cloudflare.com/agents/model-context-protocol/codemode/).
143
+
144
+ ### Anthropic
145
+
146
+ Anthropic's November 2025 architecture generated a filesystem-like tree of MCP
147
+ tool definitions so an agent could inspect only the files it needed. It also
148
+ proposed a `search_tools` alternative with selectable detail levels. The code
149
+ execution environment could filter large results, retain intermediate state,
150
+ and pass data between tools without putting that data into the model context.
151
+
152
+ Anthropic later shipped the mechanism as Tool Search and Programmatic Tool
153
+ Calling. Deferred tools stay out of the initial prompt, while Python running in
154
+ the Code Execution sandbox can pause for an allowed tool, process the result,
155
+ and continue without sending that result through another model inference.
156
+ Anthropic reported an 85% token reduction for Tool Search in a large catalog,
157
+ along with accuracy gains on its MCP evaluations.
158
+
159
+ Agentic Mermaid's `describe_sdk` follows the same progressive-disclosure
160
+ principle but uses a family key instead of general search. Its execution model
161
+ is intentionally smaller: no filesystem, no persistence, no arbitrary tool
162
+ catalog, and no asynchronous callback loop.
163
+
164
+ Sources: [Code execution with MCP](https://www.anthropic.com/engineering/code-execution-with-mcp)
165
+ and [advanced tool use](https://www.anthropic.com/engineering/advanced-tool-use).
166
+
167
+ ## Costs and limits
168
+
169
+ Progressive discovery moves schema tokens out of the initial prompt, but an
170
+ unfamiliar edit now needs a `describe_sdk` call before `mutate`, `build`, or
171
+ `execute`. That extra round trip is wasted on a small catalog whose definitions
172
+ are used in every session. It pays off here because most diagram tasks use one
173
+ registered family, and the old declarations devoted 93.1% of the hosted tool-list
174
+ tokens to the full SDK and repeated mutation menus.
175
+
176
+ Code execution also adds work that a direct tool does not need. A one-shot
177
+ render, verification, or straightforward operation list should use the hosted
178
+ direct tools. Models, especially smaller ones, can make JavaScript mistakes or
179
+ violate the SDK's provenance and serialization rules; `mutate` and `build`
180
+ exist because those failures were observed in practice.
181
+
182
+ The local and hosted sandboxes have deliberate constraints:
183
+
184
+ - Code Mode is synchronous. It rejects `async`/`await`, Promise jobs, dynamic
185
+ imports, finalizers, and queued microtasks.
186
+ - Sandbox code has no filesystem, external network, environment variables, or
187
+ persistent workspace.
188
+ - Local `node:vm` is hardened but is not an operating-system or container
189
+ security boundary. It is a local tool for trusted use.
190
+ - Hosted execution contacts a billable Dynamic Worker on every call. Worker
191
+ Loader IDs are content-addressed so identical code can reuse a warm isolate,
192
+ while direct tools and their private compute cache keep routine work off that
193
+ path.
194
+ - Hosted `execute` responses are never compute-cached: Code Mode exposes time
195
+ and randomness, so retaining the first result would violate its observable
196
+ contract.
197
+ - Local timeouts use wall-clock time, while hosted limits use CPU time. Warm
198
+ hosted isolates can retain module globals, hosted output is capped, and
199
+ hosted PNG bytes are not part of the cross-runtime byte-determinism contract.
200
+
201
+ Keeping intermediate results outside model context is useful only when code
202
+ can decide what to discard. If the model must inspect each intermediate result
203
+ to make a semantic judgment, direct calls may be more appropriate. Anthropic
204
+ makes the same distinction for simple lookups and tasks where Claude should see
205
+ all intermediate data.
206
+
207
+ ## Decision
208
+
209
+ Because Agentic Mermaid's useful unit of work is a verified diagram
210
+ transaction rather than a general agent computer, its Code Mode surface can
211
+ stay narrow. The model receives the core SDK, requests one family schema when
212
+ needed, and returns reviewable Mermaid source only after the same verifier used
213
+ by the library and CLI has accepted it. That verified source is the outcome by
214
+ which the extra sandbox and discovery call should be judged.
@@ -19,11 +19,11 @@ one does, and the final section tells you which to install for common jobs.
19
19
  - **Agentic Mermaid** (`agentic-mermaid`, this repo) extends Beautiful
20
20
  Mermaid for programs that edit diagrams — AI agents foremost. It adds a
21
21
  typed parse → mutate → verify → serialize loop, byte-identical output
22
- across runs, structured verification, and CLI/MCP surfaces. The trade is
23
- explicit: 12 diagram families against Mermaid's ~25, in exchange for the
24
- guarantee that parsing and re-serializing a diagram never drops syntax.
22
+ across runs, structured verification, and CLI/MCP surfaces. The trade is explicit: the checked registry covers a focused subset of Mermaid's
23
+ broader catalogue in exchange for the guarantee that parsing and re-serializing
24
+ a diagram never drops syntax.
25
25
 
26
- Facts below reflect Mermaid ~11.15 and the upstream `beautiful-mermaid`
26
+ Facts below reflect Mermaid 11.16.0 and the upstream `beautiful-mermaid`
27
27
  repository as of mid-2026; both projects move quickly, so check their
28
28
  changelogs for the current state.
29
29
 
@@ -33,16 +33,16 @@ changelogs for the current state.
33
33
  |---|---|---|---|
34
34
  | Primary job | Define and render the diagram language everywhere | Fast, beautiful, browserless rendering | Agent-safe diagram *editing* plus rendering |
35
35
  | Runtime | Browser DOM (Node via Puppeteer/`mermaid-cli`) | Pure TypeScript, zero DOM, synchronous | Pure TypeScript, zero DOM, synchronous |
36
- | Diagram types | ~25 (flowchart, sequence, class, state, ER, gantt, pie, mindmap, gitgraph, timeline, journey, quadrant, sankey, xychart, block, packet, kanban, architecture, radar, treemap, venn, ishikawa, wardley, treeview, event modeling, …) | 6 (flowchart, state, sequence, class, ER, XY chart) | 12 (those 6 + timeline, journey, architecture, pie, quadrant, gantt) |
36
+ | Diagram types | Broad Mermaid catalogue, including newer experimental families | Flowchart, state, sequence, class, ER, and XY chart | Registry-backed subset listed by `am capabilities --json` |
37
37
  | Output formats | SVG (PNG/PDF via CLI tooling) | SVG, ASCII/Unicode | SVG, PNG (offline resvg), ASCII/Unicode, JSON layout |
38
38
  | Theming | Theme config + CSS | Two-color foundation, 15+ named themes, Shiki/VS Code compatibility, live CSS-variable switching | Style + Palette stacks: named looks, palette-only styles, custom JSON records, and deterministic seeds |
39
- | Parse to a typed AST for editing | — (internal parser, not an editing API) | — (render-only API) | ✅ `parseMermaid` → typed `ValidDiagram` |
40
- | Typed mutation ops | — | — | ✅ 12 of 12 families (101 ops total), structured-or-opaque, never lossy |
39
+ | Parse to a typed AST for editing | — (internal parser, not an editing API) | — (render-only API) | ✅ `parseRegisteredMermaid` → typed `ValidDiagram` |
40
+ | Typed mutation | — | — | ✅ every registered family, structured-or-opaque and never lossy |
41
41
  | Structural verification | — | — | ✅ 3 warning tiers + perceptual quality metrics, all families |
42
42
  | Deterministic output | Not a goal (browser/layout variance) | Mostly stable, not a tested guarantee | ✅ byte-identical across runs/processes, CI-gated |
43
43
  | Round-trip guarantee (parse → serialize keeps your source) | — | — | ✅ verbatim for unmodeled syntax, canonical for structured bodies |
44
44
  | CLI | `mermaid-cli` (`mmdc`, Puppeteer-based) | — | `am` (render/verify/mutate/batch/preview/…, single-binary build) |
45
- | MCP / agent surface | Official hosted MCP (validation, PNG, Mermaid Chart integration) | — | Local Code Mode MCP (`execute`, `render_png`, `describe`) plus hosted `/mcp` (`execute`, render/verify/describe, `mutate`/`build`), `llms.txt`, agent skill |
45
+ | MCP / agent surface | Official hosted MCP (validation, PNG, Mermaid Chart integration) | — | Local Code Mode MCP (`execute`, `describe_sdk`, `render_png`, `describe`) plus hosted `/mcp` (`execute`, progressive schema discovery, render/verify/describe, `mutate`/`build`), `llms.txt`, agent skill |
46
46
  | Interactivity (click handlers, animations) | ✅ | Partial (tooltips) | Inherited where upstream has it; not a focus |
47
47
  | Ecosystem & docs | Vast — the de-facto standard, GitHub/GitLab/Notion render it natively | Growing, popular for terminal/AI use | Small; this repo |
48
48
 
@@ -61,7 +61,7 @@ enriched palettes and Shiki theme compatibility; ASCII/Unicode terminal
61
61
  output. Agentic Mermaid inherits all of this — it is upstream's work, and
62
62
  credit belongs there.
63
63
 
64
- **Only Agentic Mermaid:** the typed editing loop. `parseMermaid` returns a
64
+ **Only Agentic Mermaid:** the typed editing loop. `parseRegisteredMermaid` returns a
65
65
  sealed IR; family narrowers (`asFlowchart` … `asXyChart`) expose typed
66
66
  mutation ops; `verifyMermaid` returns structured warnings instead of asking
67
67
  an agent to eyeball pixels; `serializeMermaid` round-trips losslessly
@@ -73,10 +73,22 @@ for zero-install render/verify/describe and structured edits, and tested
73
73
  byte-identical determinism. Neither upstream project needed any of this: both serve humans who write
74
74
  diagrams once, while this surface serves programs that edit them repeatedly.
75
75
 
76
+ ## Mindmap/GitGraph and the terminal ecosystem
77
+
78
+ The checked fixtures follow the official [Mindmap](https://mermaid.ai/open-source/syntax/mindmap.html) and [GitGraph](https://mermaid.ai/open-source/syntax/gitgraph.html) syntax pages and render from the same authored source in Mermaid 11.16.0 and Agentic Mermaid. See the captioned [Mindmap comparison](./design/families/mindmap.md#visual-evidence) and [GitGraph comparison](./design/families/gitgraph.md#visual-evidence). Compare semantic structure—labels, shapes, hierarchy, lanes, commits, parentage, tags, and bounds—not pixels, because the layout/style engines differ.
79
+
80
+ [AlexanderGrooff/mermaid-ascii](https://github.com/AlexanderGrooff/mermaid-ascii) 1.4.0 does not currently implement either family. Replaying the documented CLI against the same fixtures exits 1 with:
81
+
82
+ ```text
83
+ unsupported graph type 'mindmap'. Supported types: graph TD, graph TB, graph LR, flowchart TD, flowchart TB, flowchart LR
84
+ unsupported graph type 'gitGraph'. Supported types: graph TD, graph TB, graph LR, flowchart TD, flowchart TB, flowchart LR
85
+ ```
86
+
87
+ Its [diagram coverage issue #74](https://github.com/AlexanderGrooff/mermaid-ascii/issues/74) tracks additional families. This is a capability difference, not a claim that an unsupported render is visually worse.
88
+
76
89
  ## Choosing
77
90
 
78
- - Rendering inside a web app, or you need mindmap/gitgraph/any family
79
- beyond the 12 here → **Mermaid**.
91
+ - Rendering inside a web app, or you need a family absent from `am capabilities --json` → **Mermaid**.
80
92
  - Fast, beautiful SVG/ASCII rendering of the core families in
81
93
  Node/Bun/terminal, render-only → **Beautiful Mermaid**.
82
94
  - An AI agent (or any program) needs to *edit* diagrams safely, verify them
@@ -0,0 +1,252 @@
1
+ # Computational-aesthetics prototype plan
2
+
3
+ This is the revised plan for cheap, deterministic computational aesthetics in
4
+ Agentic Mermaid. It covers pure functions over geometry and concrete sRGB. It
5
+ does not turn a rubric into an optimizer, add learned scores, or introduce
6
+ stochastic search.
7
+
8
+ The governing rule is stricter than “the formula is deterministic”:
9
+
10
+ > An aesthetic mechanism is ready only when its domain, runtime, product
11
+ > reachability, and evidence are all explicit.
12
+
13
+ Agentic Mermaid already operationalizes graph-layout research in
14
+ `src/layout-rubric.ts` and `src/family-rubric.ts`. The work below extends that
15
+ discipline to categorical color and whole-canvas composition without pretending
16
+ that one scalar score certifies beauty.
17
+
18
+ ## Status
19
+
20
+ - **shipped** — implemented on a product path with discriminating tests.
21
+ - **prototype** — report-only until the evaluation harness justifies a weight.
22
+ - **rejected** — considered, but redundant or insufficiently specified.
23
+
24
+ | # | Idea | Status | Contract / next question |
25
+ |---|---|---|---|
26
+ | 1 | OKLCH constant-lightness categorical ramps | **shipped** | deterministic concrete-sRGB generation |
27
+ | 2 | Minimum ΔE_OK collision floor | **shipped** | hard for 7–24 fills; best-effort and linear-time above 24 |
28
+ | 3 | APCA plus WCAG background-visibility floors | **shipped** | every derived fill clears both for valid concrete backgrounds |
29
+ | 10 | Common-region ownership purity | **shipped** | architecture, class, ER, and timeline ownership frames |
30
+ | 12 | Separate typographic CPL warning | **rejected** | duplicates public universal `LABEL_OVERFLOW`; no independent signal |
31
+ | 4 | Cohen-Or hue-harmony templates | **rejected as a default** | 4/360 cases retain {1,2,3}; experiment remains reproducible |
32
+ | 5 | Purchase-normalized crosslessness `m_c` | prototype | does normalization discriminate across graph sizes? |
33
+ | 6 | Consistent flow-direction metric | prototype | does it catch anything ELK does not already guarantee? |
34
+ | 7 | Whole-canvas composition | prototype | which Ngo terms correlate with preference on our diagrams? |
35
+ | 8 | Crossing-angle / RAC penalty | prototype | incremental value after crossing count |
36
+ | 9 | Spine-straightness continuity | prototype | incremental value after {5,8} |
37
+ | 11 | Proximity / MST purity | prototype | incremental value after common-region and composition metrics |
38
+ | 13 | Information-theoretic order | prototype | is a pinned gzip ratio more than a coarse alignment proxy? |
39
+
40
+ ## What the first implementation taught us
41
+
42
+ The audit and controlled rollout changed the plan in twelve ways.
43
+
44
+ 1. **Runtime is part of correctness.** A deterministic pairwise repair still
45
+ fails the product if an allowed 1,000-slice input takes seconds. The ΔE
46
+ guarantee is therefore bounded at 24 and the large-count path has expected
47
+ linear work. Portable CI asserts the real branch and its operation counts;
48
+ wall-clock observations live in `eval/palette-performance/report.json` with
49
+ their machine, protocol, input hashes, and limitations. Every prototype must
50
+ declare an input-size budget and a degraded-tail rule.
51
+
52
+ 2. **A threshold needs a corpus, not one friendly example.** The 0.10 ΔE claim
53
+ initially failed on shipped themes and custom accent/background pairs. The
54
+ contract now runs across every built-in theme, every count from 7 through
55
+ 24, and adversarial saturated backgrounds. Future thresholds need the same
56
+ domain matrix before they can be called guarantees.
57
+
58
+ 3. **Use the perceptual quantity that controls the decision.** HSL lightness
59
+ misclassified a bright saturated yellow-green background as dark. Palette
60
+ polarity now uses OKLab lightness, and visibility repair searches both
61
+ lightness directions before falling back to a visible achromatic extreme.
62
+
63
+ 4. **A shared waist multiplies risk as well as value.** `pieSliceColors` already
64
+ reaches pie and radar, so one defect reaches both. Migrating four more
65
+ families remains valuable, but only after the waist has an explicit range,
66
+ a hard runtime bound, adversarial tests, and per-family visual review.
67
+
68
+ 5. **Reachability precedes novelty.** A test-only finding is not a product
69
+ capability. The proposed `LABEL_LINE_OVERLONG` finding was not surfaced by
70
+ verify, CLI, API, or MCP and overlapped the existing public
71
+ `LABEL_OVERFLOW` warning. It is removed rather than wired twice.
72
+
73
+ 6. **Independence applies before implementation too.** A new metric must state
74
+ which existing defect it detects that current metrics miss. Idea #12 fails
75
+ that test. Ideas {7,11} and {5,8,9} must pass it through ablation.
76
+
77
+ 7. **Semantic scope must follow every real model.** Common-region purity is not
78
+ architecture-only: class namespaces, ER groups, and timeline sections also
79
+ express ownership. Ancestor walks must be cycle-safe without arbitrary
80
+ depth cutoffs.
81
+
82
+ 8. **Visual evidence needs its own reproducibility contract.** The rollout now
83
+ freezes pre-change SVGs, extracts the categorical colors actually serialized
84
+ by each renderer, writes a machine-readable comparison, and hashes every
85
+ source input plus the generated report/contact sheet. `--check` fails when
86
+ code, baseline, metrics, or images drift.
87
+
88
+ 9. **A controlled rollout is a compatibility policy, not a global recolor.**
89
+ Counts up to six retain each family's existing derived colors byte-for-byte
90
+ (including Journey's established actor wheel). Authored
91
+ `plotColorPalette`, `actorColours`, `sectionFills`/`sectionColours`, and
92
+ `git0..7` remain authoritative. Only derived high-cardinality peer-category
93
+ colors change.
94
+
95
+ 10. **Harmony and categorical distinctness compete at this density.** Across
96
+ 20 built-in themes × counts 7..24, the Cohen-Or/Matsuda experiment reduced
97
+ mean harmony loss from 8.8303° to 0.0084°, but reduced mean minimum ΔE_OK
98
+ from 0.1107 to 0.0456. Only 4/360 palettes retained {1,2,3}; no count above
99
+ seven passed. That rejects #4 as a default layer over this palette.
100
+
101
+ 11. **A measurement must not claim more than it measures.** The performance
102
+ corpus measures one palette-generation call, not a complete diagram render.
103
+ Most controlled families have one peer-category channel; Journey has two
104
+ independent channels (sections and actors). Following the
105
+ [testing-best-practices guidance](https://github.com/adewale/testing-best-practices/tree/e50479920006aa010850a2c37f9bee1e02b5badf),
106
+ CI gates deterministic complexity and evidence freshness, never a portable
107
+ millisecond threshold.
108
+
109
+ 12. **Normalize at the algorithm boundary without erasing compatibility.**
110
+ StyleSpec accepts concrete `#RGB`, named, `rgb()`, and `hsl()` colors, while
111
+ the perceptual math requires six-digit sRGB. The high-count path now
112
+ normalizes every parser-resolvable concrete color before repair. The ≤6
113
+ path deliberately preserves each family's historical spelling or fallback
114
+ policy byte-for-byte; a global normalizer at that boundary would be a
115
+ compatibility regression disguised as cleanup.
116
+
117
+ ## Shipped color contract and family reach
118
+
119
+ The color work is a generation constraint, not evidence that the quality
120
+ rubric predicts human preference. The neutral shared waist now reaches pie,
121
+ radar, xychart, journey, mindmap, and gitgraph. SVG and terminal xychart/gitgraph
122
+ use the same derived palette; the other terminal families do not currently
123
+ encode peer categories with color.
124
+
125
+ The scope rule for this rollout, and for any future shared-palette expansion,
126
+ is explicit:
127
+
128
+ > The scope is intentionally limited to families where color identifies peer
129
+ > categories. Semantic colors—status, hierarchy, role, or user-authored
130
+ > meaning—should not be automatically redistributed.
131
+
132
+ | Property | 7–24 fills | More than 24 fills |
133
+ |---|---|---|
134
+ | deterministic | hard | hard |
135
+ | valid concrete hex output | hard | hard |
136
+ | WCAG ≥ 1.25 and APCA ≥ 15 vs concrete background | hard | hard |
137
+ | unique fills | hard | best-effort |
138
+ | minimum pairwise ΔE_OK ≥ 0.10 | hard | not claimed |
139
+ | asymptotic repair cost | bounded `O(M·n²)`, with `n ≤ 24` and fixed corpus `M` | expected `O(n)` with average `O(1)` set membership |
140
+
141
+ The established local palette is preserved when it meets the contract. If it
142
+ does not, a deterministic farthest-point packing pass selects background-visible
143
+ concrete sRGB candidates. Above 24, pairwise enforcement is skipped.
144
+
145
+ ## Prototype protocol
146
+
147
+ Reuse the existing evaluator; do not create a second quality system.
148
+
149
+ 1. **Define the contract first.** State applicable families, input-size range,
150
+ asymptotic and wall-clock budgets, degraded-tail behavior, and exclusions.
151
+ 2. **Prove product reachability.** Identify the public result, warning, or
152
+ report that exposes the metric. A private helper plus unit test is not done.
153
+ 3. **Report before weighting.** Add the metric to the per-metric tracker with
154
+ zero score weight. A weight is a separate scoring-contract change.
155
+ 4. **Add trip fixtures.** Include healthy and deliberately bad examples that
156
+ make the metric move. Zero on every committed fixture is a guard, not a
157
+ demonstrated discriminator.
158
+ 5. **Measure the full domain.** Use the Mermaid docs corpus, heuristic tracker,
159
+ deterministic family fuzzers, all built-in themes where color is involved,
160
+ and adversarial boundary inputs.
161
+ 6. **Keep visual evidence.** Any generation or geometry change needs
162
+ before/after renders and snapshot review in every affected family. The
163
+ palette rollout operationalizes this rule in
164
+ `scripts/pr-assets/palette-rollout-evidence.ts`.
165
+ 7. **Gate determinism and cost.** Preserve byte identity and deterministically
166
+ assert that the intended bounded algorithmic path engaged. Keep p50/p95
167
+ observations over a fixed corpus in a separate, provenance-bound report;
168
+ do not use cross-machine wall time as a CI threshold. Idea #13 must also pin
169
+ codec and level.
170
+
171
+ ## Evaluation and graduation
172
+
173
+ For a candidate metric M, record:
174
+
175
+ - **coverage** — fraction of diagrams on which M varies;
176
+ - **discrimination** — LCC/SROCC against a small blinded human A/B set;
177
+ - **independence** — partial correlation after controlling for current metrics;
178
+ - **stability** — sensitivity to harmless translation, scale, and equivalent
179
+ source ordering where those transforms should not matter;
180
+ - **cost** — deterministic operation growth at the declared size boundary,
181
+ plus environment-qualified p50/p95 observations where useful;
182
+ - **reach** — public surfaces and diagram families that consume the result.
183
+
184
+ Graduate a metric from report-only only when it fires on trip fixtures, varies
185
+ on the corpus, adds preference signal after current metrics, and stays inside
186
+ its cost budget. Otherwise remove it or retain it explicitly as a correctness
187
+ guard with no aesthetic weight.
188
+
189
+ For combinations, run small ablations rather than blending everything. Treat
190
+ each combination as a gated ladder: validate the cheaper base term, add one
191
+ term, and stop when independence disappears.
192
+
193
+ - **{1,2,3}:** lightness structure, categorical distance, and background
194
+ visibility are complementary and already ship as one generation contract.
195
+ - **{1,2,3,4}:** the completed experiment found no useful Pareto front at
196
+ 8–24 categories: hue-sector contraction almost eliminates harmony loss but
197
+ breaks minimum categorical distance. Do not ship this bundle as a default.
198
+ - **{5,8}:** crossing prevalence and crossing quality should be complementary.
199
+ - **{5,6,8}:** add direction only if #6 catches defects not explained by the
200
+ crossing pair or by ELK's existing directional constraints.
201
+ - **{5,8,9}:** likely redundant; add #9 only if partial correlation survives.
202
+ - **{7,10,11}:** composition, common region, and proximity span figure,
203
+ ownership, and local grouping scales, but need ablation because the signals
204
+ can collapse onto the same cluster structure.
205
+
206
+ ## Revised stack rank
207
+
208
+ The rank uses five axes: user-visible value, independence from existing
209
+ signals, product reach, bounded runtime, and validation burden. “Foundation” is
210
+ not optional feature work. An arrow means “validate the new idea alone, then
211
+ admit it to the combination”; it is not permission to ship an opaque aggregate.
212
+
213
+ | Rank | Work package | Form | Why it is here | Stop / go gate |
214
+ |---|---|---|---|---|
215
+ | Foundation | **Keep {1,2,3,10}; reject #12** | shipped contract | Color and ownership have bounded, reachable contracts; the extra label warning is redundant. | keep the regression matrix green |
216
+ | Delivered | **Controlled {1,2,3} family rollout** | shipped combination | 14/14 fixture violations corrected; 8/8 family/theme cases pass; ≤6 colors and authored overrides remain compatible; six rich website examples expose the peer mapping at inspectable size. | palette evidence, complexity, website, and family gates |
217
+ | Rejected | **#4 → {1,2,3,4} color-harmony default** | completed experiment | 4/360 pass rate; mean minimum ΔE_OK falls 0.1107 → 0.0456. | reconsider only with a new constraint-preserving algorithm and blinded preference evidence |
218
+ | Paused 1 | **#5 normalized crosslessness `m_c`** | telemetry, postponed | Still the cheapest next metric experiment, but telemetry work is intentionally deferred. | resume only on explicit telemetry restart |
219
+ | Paused 2 | **#8 → {5,8} crossing-quality bundle** | telemetry, postponed | Clear ablation after #5. | #8 must add signal after #5 |
220
+ | Paused 3 | **#6 → {5,6,8} directional-legibility bundle** | telemetry, postponed | Likely overlaps ELK behavior. | independent trip case first |
221
+ | Paused 4 | **#7 whole-canvas composition** | telemetry, postponed | Potential figure-level value, high calibration burden. | stable, nonzero corpus coverage |
222
+ | Paused 5 | **#11 → {7,10,11} multiscale grouping** | telemetry, postponed | Plausible value with high redundancy risk. | term-by-term ablation |
223
+ | Paused 6 | **#9 → {5,8,9} edge-path bundle** | telemetry, postponed | Costlier and likely redundant. | partial-correlation survival |
224
+ | Paused 7 | **#13 pinned-gzip order** | telemetry, postponed | Codec-sensitive and coarse. | beat simpler direct features |
225
+
226
+ This supersedes the earlier ordering. The highest-ranked product change is now
227
+ delivered and its evidence gate is permanent. The harmony experiment has also
228
+ resolved its decision: it is not merely lower priority; this formulation is a
229
+ bad default. With telemetry postponed, there is no authorized next aesthetic
230
+ metric package. If telemetry resumes, it still starts with #5 and every later
231
+ bundle remains conditional on ablation.
232
+
233
+ ## Scope boundaries
234
+
235
+ - This plan covers measurement and closed-form generation, not optimization.
236
+ - Flowchart/state subgraph purity remains in `layout-rubric.ts`; the generic
237
+ #10 implementation covers ownership frames projected by architecture, class,
238
+ ER, and timeline.
239
+ - `LABEL_OVERFLOW` remains the public label-length signal. It applies the
240
+ caller-configurable cap to the longest rendered line after entity decoding,
241
+ line-break normalization, and formatting-tag removal. A second fixed CPL
242
+ warning would be redundant and less reachable.
243
+ - The shared perceptual palette reaches only families where color denotes peer
244
+ categories: pie slices, radar curves, xychart series, journey actors/sections,
245
+ mindmap top-level branches, and gitgraph branches. Structural families use
246
+ color for roles, status, hierarchy, or authored semantics; automatic hue
247
+ spreading there would invent category meaning and can weaken brand/status
248
+ cues. Timeline/gantt/quadrant have family-specific categorical contracts and
249
+ are not silently swept into this rollout.
250
+ - A score of 100 proves only that a renderer clears the measured hygiene floor;
251
+ it does not certify beauty. Each family still needs an aesthetic thesis and
252
+ human visual review.
package/docs/config.md CHANGED
@@ -3,7 +3,7 @@
3
3
  Agentic Mermaid accepts Mermaid-style runtime config through explicit render options, YAML frontmatter, and `%%{init: ...}%%` / `%%{initialize: ...}%%` directives.
4
4
 
5
5
  Round-trip behavior: the agent surface preserves these source wrappers
6
- byte-verbatim — `parseMermaid → serializeMermaid` and every `mutate` re-emit
6
+ byte-verbatim — `parseRegisteredMermaid → serializeMermaid` and every `mutate` re-emit
7
7
  the original frontmatter/directives/leading comments untouched, so a
8
8
  `config.layout`/`config.look` request written for Mermaid survives an
9
9
  Agentic Mermaid edit loop. Canonical wrapper synthesis (config-nested
@@ -29,7 +29,7 @@ const svg = renderMermaidSVG(source, {
29
29
  })
30
30
  ```
31
31
 
32
- Explicit options win over source-level config when both specify the same supported field.
32
+ Explicit options win over source-level config when both specify the same supported field. `RenderOptions.onConfigDiagnostic` can collect warnings for explicit config that is unknown, invalid, or has no faithful effect; without a collector, explicit ineffective State config warns through `console.warn` rather than disappearing silently.
33
33
 
34
34
  ## YAML frontmatter
35
35
 
@@ -70,14 +70,30 @@ Top-level:
70
70
  `themeVariables` and explicit color options still win over a style's
71
71
  palette, preserving Mermaid compatibility.)
72
72
 
73
- Family-specific:
74
-
75
- - `xyChart.width`, `xyChart.height`, `xyChart.chartOrientation`, `xyChart.showDataLabel`, `xyChart.titlePadding`, `xyChart.xAxisLabelPadding`, `xyChart.yAxisLabelPadding`, `xyChart.plotReservedSpacePercent`, `xyChart.plotColorPalette`, `xyChart.useMaxWidth`, `xyChart.useWidth`
76
- - `architecture.padding`, `architecture.iconSize`, `architecture.fontSize`
77
- - `timeline.disableMulticolor`, `timeline.padding`, `timeline.sectionFontSize`, `timeline.periodFontSize`, `timeline.eventFontSize`
78
- - `gantt.displayMode` (`compact` packs non-overlapping tasks in a section into shared rows)
79
-
80
- Unsupported fields are preserved at the source level where possible, but only documented fields are interpreted by renderers.
73
+ Family-specific config is **wire-or-warn**: every accepted key either changes
74
+ output or produces `INEFFECTIVE_CONFIG` naming the field. Unknown keys also
75
+ warn, so spelling mistakes cannot disappear silently. This contract covers all
76
+ every registered family and both frontmatter and init directives.
77
+
78
+ Notable wired sections include:
79
+
80
+ - `flowchart`: spacing and measured wrapping;
81
+ - `sequence`: actor/message/note spacing, dimensions, activations, and numbering;
82
+ - `timeline`, `journey`, `class`, `er`, `architecture`, `xyChart`, `pie`,
83
+ `quadrantChart`, `mindmap`, and `gitGraph`: the fields documented in their
84
+ family design notes;
85
+ - `gantt.displayMode` (`compact` packs non-overlapping tasks in a section into
86
+ shared rows).
87
+
88
+ `state` has a typed `StateRuntimeConfig`. `nodeSpacing`, `rankSpacing`,
89
+ `padding`, `radius`, `fontSize`, `compositTitleSize` (upstream spelling),
90
+ `forkWidth`, `forkHeight`, `noteMargin`, and `dividerMargin` are wired to
91
+ State-specific geometry/paint. `defaultRenderer: 'elk'` is satisfied;
92
+ alternate renderer requests, invalid values, and legacy Dagre/fixed-metric
93
+ calibration fields emit qualified `state.*` diagnostics. Unsupported fields
94
+ and wrappers remain source-preserved. The executable all-family audit is
95
+ `src/__tests__/unknown-config-wire-or-warn.test.ts`; the independent State key
96
+ inventory and discriminating geometry probes are in `state-config.test.ts`.
81
97
 
82
98
  ## Security
83
99