agentic-mermaid 0.1.0 → 0.1.2

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 (333) hide show
  1. package/CHANGELOG.md +149 -4
  2. package/LICENSES/Apache-2.0.txt +202 -0
  3. package/README.md +25 -32
  4. package/THIRD_PARTY_NOTICES.md +29 -0
  5. package/assets/fonts/FONT-LICENSES.md +9 -5
  6. package/assets/fonts/Inter-Bold.ttf +0 -0
  7. package/assets/fonts/Inter-Medium.ttf +0 -0
  8. package/assets/fonts/Inter-Regular.ttf +0 -0
  9. package/assets/fonts/Inter-SemiBold.ttf +0 -0
  10. package/dist/agent-core.d.ts +463 -0
  11. package/dist/agent-core.js +397 -0
  12. package/dist/agent.d.ts +81 -1822
  13. package/dist/agent.js +336 -36839
  14. package/dist/agentic-mermaid-mcp.js +7 -37908
  15. package/dist/am.js +33638 -36261
  16. package/dist/chunk-4QECACIA.js +4702 -0
  17. package/dist/chunk-CDPKJ2BQ.js +37 -0
  18. package/dist/chunk-QKDLMOJJ.js +3487 -0
  19. package/dist/chunk-WI35L7IR.js +615 -0
  20. package/dist/chunk-WN3YDOBG.js +149 -0
  21. package/dist/chunk-ZYMMKQ3I.js +62637 -0
  22. package/dist/index-D54dqSdC.d.ts +6777 -0
  23. package/dist/index.d.ts +1 -1
  24. package/dist/index.js +310 -32836
  25. package/dist/mcp-cli-SBQSTJFC.js +17 -0
  26. package/docs/README.md +14 -6
  27. package/docs/schemas/style-spec.schema.json +1221 -30
  28. package/examples/styles/catalog.json +54 -0
  29. package/examples/styles/cloudflare-workers-inspired-prototype.mmd +9 -0
  30. package/examples/styles/cloudflare-workers-inspired-prototype.style.json +110 -0
  31. package/examples/styles/cupertino-prototype.mmd +10 -0
  32. package/examples/styles/cupertino-prototype.style.json +63 -0
  33. package/examples/styles/mid-century-report.style.json +2 -2
  34. package/examples/styles/star-chart-atlas.style.json +2 -1
  35. package/examples/styles/transit-route-map.style.json +2 -2
  36. package/examples/styles/vercel-inspired-prototype.mmd +6 -0
  37. package/examples/styles/vercel-inspired-prototype.style.json +87 -0
  38. package/package.json +70 -43
  39. package/server.json +41 -0
  40. package/skills/agentic-mermaid-diagram-workflow/SKILL.md +17 -36
  41. package/skills/agentic-mermaid-diagram-workflow/references/cli.md +4 -5
  42. package/skills/agentic-mermaid-diagram-workflow/references/code-mode.md +15 -31
  43. package/skills/agentic-mermaid-diagram-workflow/references/sequence.md +10 -14
  44. package/skills/agentic-mermaid-live-editor/SKILL.md +100 -206
  45. package/AGENT_NATIVE.md +0 -602
  46. package/Instructions_for_agents.md +0 -83
  47. package/TODO.md +0 -662
  48. package/assets/hero.png +0 -0
  49. package/dist/index-x2Cj1dVv.d.ts +0 -1089
  50. package/docs/agent-api-cookbook.md +0 -308
  51. package/docs/agent-mutation-policy.md +0 -104
  52. package/docs/agent-workflow-examples.md +0 -46
  53. package/docs/api.md +0 -203
  54. package/docs/ascii.md +0 -103
  55. package/docs/assets/improvements/box-start-connector.png +0 -0
  56. package/docs/assets/improvements/comment-dropped-lint.png +0 -0
  57. package/docs/assets/improvements/er-content-loss.png +0 -0
  58. package/docs/assets/improvements/fan-in-trunks.png +0 -0
  59. package/docs/assets/improvements/gantt-family.png +0 -0
  60. package/docs/assets/improvements/gantt-milestone-clamp.png +0 -0
  61. package/docs/assets/improvements/gantt-verify-seam.png +0 -0
  62. package/docs/assets/improvements/subgraph-container-edges.png +0 -0
  63. package/docs/assets/improvements/wrapper-frontmatter.png +0 -0
  64. package/docs/assets/improvements/wrapper-init-directive.png +0 -0
  65. package/docs/assets/improvements/wrapper-leading-comment.png +0 -0
  66. package/docs/assets/style-cookbook/mid-century-report.png +0 -0
  67. package/docs/assets/style-cookbook/star-chart-atlas.png +0 -0
  68. package/docs/assets/style-cookbook/transit-route-map.png +0 -0
  69. package/docs/comparison.md +0 -94
  70. package/docs/config.md +0 -105
  71. package/docs/contributing/adding-diagram-types.md +0 -144
  72. package/docs/contributing/diagram-family-citizenship.matrix.json +0 -2127
  73. package/docs/contributing/diagram-family-citizenship.md +0 -82
  74. package/docs/contributing/harvesting-upstream-tests.md +0 -126
  75. package/docs/contributing/lessons-learned.md +0 -276
  76. package/docs/contributing/releasing.md +0 -71
  77. package/docs/contributing/visual-review-evidence.md +0 -53
  78. package/docs/custom-style-cookbook.md +0 -154
  79. package/docs/design/families/README.md +0 -26
  80. package/docs/design/families/architecture-beta.md +0 -48
  81. package/docs/design/families/flowchart-parser-conformance.md +0 -22
  82. package/docs/design/families/gantt-research.md +0 -137
  83. package/docs/design/families/gantt.md +0 -329
  84. package/docs/design/families/journey-agentic-cards-before.png +0 -0
  85. package/docs/design/families/journey-mermaid-classic-implementation.png +0 -0
  86. package/docs/design/families/journey-mermaid-classic-prototype.png +0 -0
  87. package/docs/design/families/journey-mermaid-classic-prototype.svg +0 -163
  88. package/docs/design/families/journey-mermaid-classic-prototype.svg.png +0 -0
  89. package/docs/design/families/journey-migration-parity.md +0 -433
  90. package/docs/design/families/journey-usage-research.md +0 -423
  91. package/docs/design/families/journey.md +0 -125
  92. package/docs/design/families/xychart.md +0 -85
  93. package/docs/design/system/README.md +0 -45
  94. package/docs/design/system/abstraction-audit.md +0 -224
  95. package/docs/design/system/abstraction-recommendations.md +0 -655
  96. package/docs/design/system/architecture.mmd +0 -29
  97. package/docs/design/system/architecture.svg +0 -137
  98. package/docs/design/system/layout-guarantees-and-robustness.md +0 -351
  99. package/docs/design/system/layout-rubric.md +0 -138
  100. package/docs/design/system/route-contracts.md +0 -848
  101. package/docs/design/system/source-preservation-ladder.md +0 -52
  102. package/docs/design/system/styles-rollout.md +0 -216
  103. package/docs/design/system/ugly-layouts.md +0 -119
  104. package/docs/diagram-families.md +0 -193
  105. package/docs/features.md +0 -147
  106. package/docs/fork-differences.md +0 -130
  107. package/docs/getting-started.md +0 -175
  108. package/docs/issue-derived-test-cases.md +0 -156
  109. package/docs/layout-characterization/README.md +0 -245
  110. package/docs/layout-characterization/contact-sheet-families.md +0 -496
  111. package/docs/layout-characterization/contact-sheet.md +0 -638
  112. package/docs/layout-characterization/properties.md +0 -281
  113. package/docs/layout-characterization/visual-quality.md +0 -160
  114. package/docs/layout-characterization/visual-snapshots/architecture.svg +0 -79
  115. package/docs/layout-characterization/visual-snapshots/class.svg +0 -60
  116. package/docs/layout-characterization/visual-snapshots/er.svg +0 -61
  117. package/docs/layout-characterization/visual-snapshots/flowchart.svg +0 -58
  118. package/docs/layout-characterization/visual-snapshots/gantt.svg +0 -52
  119. package/docs/layout-characterization/visual-snapshots/journey.svg +0 -118
  120. package/docs/layout-characterization/visual-snapshots/pie.svg +0 -36
  121. package/docs/layout-characterization/visual-snapshots/quadrant.svg +0 -47
  122. package/docs/layout-characterization/visual-snapshots/sequence.svg +0 -59
  123. package/docs/layout-characterization/visual-snapshots/state.svg +0 -52
  124. package/docs/layout-characterization/visual-snapshots/timeline.svg +0 -64
  125. package/docs/layout-characterization/visual-snapshots/xychart.svg +0 -97
  126. package/docs/mcp-code-mode-rationale.md +0 -101
  127. package/docs/mcp-http-transport.md +0 -223
  128. package/docs/mermaid-layout-complaints.md +0 -837
  129. package/docs/mutation-testing.md +0 -206
  130. package/docs/project/divergences.md +0 -98
  131. package/docs/project/dogfooding-docs-strategy.md +0 -66
  132. package/docs/project/hosted-mcp-cloudflare-plan.md +0 -338
  133. package/docs/project/lessons-learned.md +0 -1019
  134. package/docs/project/remove-role-styling-plan.md +0 -176
  135. package/docs/quality.md +0 -212
  136. package/docs/react.md +0 -97
  137. package/docs/style-authoring.md +0 -133
  138. package/docs/testing-strategy.md +0 -335
  139. package/docs/theming.md +0 -162
  140. package/examples/agent-improve-auth-flow.ts +0 -206
  141. package/examples/agent-loop.ts +0 -53
  142. package/examples/mcp-vs-cli-complex-diagrams.ts +0 -133
  143. package/llms.txt +0 -104
  144. package/skill-evals/README.md +0 -77
  145. package/skill-evals/fixtures/architecture-cache/input.mmd +0 -5
  146. package/skill-evals/fixtures/class-payment/input.mmd +0 -4
  147. package/skill-evals/fixtures/er-orders/input.mmd +0 -10
  148. package/skill-evals/fixtures/flowchart-cache/input.mmd +0 -3
  149. package/skill-evals/fixtures/gantt-release/input.mmd +0 -7
  150. package/skill-evals/fixtures/journey-checkout/input.mmd +0 -6
  151. package/skill-evals/fixtures/pie-exports/input.mmd +0 -5
  152. package/skill-evals/fixtures/quadrant-priorities/input.mmd +0 -11
  153. package/skill-evals/fixtures/sequence-retry/input.mmd +0 -8
  154. package/skill-evals/fixtures/state-lifecycle/input.mmd +0 -5
  155. package/skill-evals/fixtures/timeline-release/input.mmd +0 -6
  156. package/skill-evals/fixtures/xychart-growth/input.mmd +0 -5
  157. package/skill-evals/shared-benchmark.json +0 -510
  158. package/src/agent/analyze.ts +0 -157
  159. package/src/agent/apply.ts +0 -146
  160. package/src/agent/architecture-body.ts +0 -458
  161. package/src/agent/certificates.ts +0 -110
  162. package/src/agent/class-body.ts +0 -319
  163. package/src/agent/core.ts +0 -207
  164. package/src/agent/create.ts +0 -106
  165. package/src/agent/describe.ts +0 -364
  166. package/src/agent/er-body.ts +0 -224
  167. package/src/agent/facts.ts +0 -337
  168. package/src/agent/families-builtin.ts +0 -934
  169. package/src/agent/families.ts +0 -232
  170. package/src/agent/family-layouts.ts +0 -826
  171. package/src/agent/flowchart-body.ts +0 -372
  172. package/src/agent/flowchart-unsupported.ts +0 -243
  173. package/src/agent/gantt-body.ts +0 -495
  174. package/src/agent/index.ts +0 -10
  175. package/src/agent/journey-body.ts +0 -414
  176. package/src/agent/label-metrics.ts +0 -28
  177. package/src/agent/layout-to-rendered.ts +0 -63
  178. package/src/agent/mutate.ts +0 -97
  179. package/src/agent/mutation-ops.ts +0 -51
  180. package/src/agent/op-schema.ts +0 -439
  181. package/src/agent/parse.ts +0 -223
  182. package/src/agent/pie-body.ts +0 -270
  183. package/src/agent/png.ts +0 -117
  184. package/src/agent/quadrant-body.ts +0 -336
  185. package/src/agent/quality.ts +0 -363
  186. package/src/agent/readability-audit.ts +0 -92
  187. package/src/agent/rendered-route-audit.ts +0 -61
  188. package/src/agent/sequence-body.ts +0 -345
  189. package/src/agent/serialize.ts +0 -214
  190. package/src/agent/state-body.ts +0 -589
  191. package/src/agent/structural-count.ts +0 -150
  192. package/src/agent/timeline-body.ts +0 -280
  193. package/src/agent/trace-log.ts +0 -43
  194. package/src/agent/types.ts +0 -979
  195. package/src/agent/verify.ts +0 -571
  196. package/src/agent/xychart-body.ts +0 -472
  197. package/src/architecture/config.ts +0 -282
  198. package/src/architecture/layout.ts +0 -496
  199. package/src/architecture/parser.ts +0 -375
  200. package/src/architecture/renderer.ts +0 -611
  201. package/src/architecture/types.ts +0 -113
  202. package/src/ascii/ansi.ts +0 -423
  203. package/src/ascii/architecture.ts +0 -210
  204. package/src/ascii/canvas.ts +0 -443
  205. package/src/ascii/class-diagram.ts +0 -697
  206. package/src/ascii/converter.ts +0 -475
  207. package/src/ascii/draw.ts +0 -1693
  208. package/src/ascii/edge-bundling.ts +0 -328
  209. package/src/ascii/edge-routing.ts +0 -330
  210. package/src/ascii/er-diagram.ts +0 -439
  211. package/src/ascii/gantt.ts +0 -276
  212. package/src/ascii/grid.ts +0 -747
  213. package/src/ascii/index.ts +0 -196
  214. package/src/ascii/journey.ts +0 -189
  215. package/src/ascii/meta.ts +0 -244
  216. package/src/ascii/multiline-utils.ts +0 -80
  217. package/src/ascii/pathfinder.ts +0 -301
  218. package/src/ascii/pie.ts +0 -67
  219. package/src/ascii/quadrant.ts +0 -158
  220. package/src/ascii/reverse.ts +0 -216
  221. package/src/ascii/sequence.ts +0 -499
  222. package/src/ascii/shapes/circle.ts +0 -27
  223. package/src/ascii/shapes/corners.ts +0 -143
  224. package/src/ascii/shapes/diamond.ts +0 -27
  225. package/src/ascii/shapes/hexagon.ts +0 -27
  226. package/src/ascii/shapes/index.ts +0 -106
  227. package/src/ascii/shapes/rectangle.ts +0 -168
  228. package/src/ascii/shapes/rounded.ts +0 -27
  229. package/src/ascii/shapes/special.ts +0 -332
  230. package/src/ascii/shapes/stadium.ts +0 -110
  231. package/src/ascii/shapes/state.ts +0 -192
  232. package/src/ascii/shapes/types.ts +0 -73
  233. package/src/ascii/timeline.ts +0 -128
  234. package/src/ascii/types.ts +0 -312
  235. package/src/ascii/validate.ts +0 -120
  236. package/src/ascii/width.ts +0 -81
  237. package/src/ascii/xychart.ts +0 -919
  238. package/src/browser.ts +0 -29
  239. package/src/class/layout.ts +0 -240
  240. package/src/class/parser.ts +0 -332
  241. package/src/class/renderer.ts +0 -638
  242. package/src/class/types.ts +0 -129
  243. package/src/cli/agent-instructions.ts +0 -1
  244. package/src/cli/am-bin.ts +0 -6
  245. package/src/cli/exit-codes.ts +0 -18
  246. package/src/cli/index.ts +0 -1117
  247. package/src/cli/init-agent.ts +0 -147
  248. package/src/color-resolver.ts +0 -152
  249. package/src/elk-instance.ts +0 -114
  250. package/src/er/layout.ts +0 -187
  251. package/src/er/parser.ts +0 -226
  252. package/src/er/renderer.ts +0 -792
  253. package/src/er/types.ts +0 -99
  254. package/src/font-manifest.ts +0 -27
  255. package/src/gantt/layout.ts +0 -365
  256. package/src/gantt/parser.ts +0 -282
  257. package/src/gantt/pipeline.ts +0 -27
  258. package/src/gantt/renderer.ts +0 -414
  259. package/src/gantt/schedule.ts +0 -513
  260. package/src/gantt/types.ts +0 -255
  261. package/src/index.ts +0 -368
  262. package/src/journey/layout.ts +0 -520
  263. package/src/journey/parser.ts +0 -218
  264. package/src/journey/renderer.ts +0 -811
  265. package/src/journey/types.ts +0 -144
  266. package/src/layout/geometry.ts +0 -182
  267. package/src/layout/pass.ts +0 -142
  268. package/src/layout/passes/index.ts +0 -3916
  269. package/src/layout-engine.ts +0 -1565
  270. package/src/layout-rubric.ts +0 -659
  271. package/src/mcp/artifacts.ts +0 -137
  272. package/src/mcp/dynamic-harness.ts +0 -31
  273. package/src/mcp/dynamic-modules.d.ts +0 -7
  274. package/src/mcp/facade.ts +0 -608
  275. package/src/mcp/harness-runtime.ts +0 -203
  276. package/src/mcp/hosted-server.ts +0 -468
  277. package/src/mcp/mcp-bin.ts +0 -3
  278. package/src/mcp/mcp-cli.ts +0 -82
  279. package/src/mcp/protocol.ts +0 -13
  280. package/src/mcp/sandbox.ts +0 -195
  281. package/src/mcp/sdk-decl.ts +0 -387
  282. package/src/mcp/server.ts +0 -362
  283. package/src/mcp/tool-surface.ts +0 -146
  284. package/src/mermaid-source.ts +0 -655
  285. package/src/multiline-utils.ts +0 -228
  286. package/src/parser.ts +0 -1031
  287. package/src/pie/layout.ts +0 -168
  288. package/src/pie/parser.ts +0 -136
  289. package/src/pie/renderer.ts +0 -234
  290. package/src/pie/types.ts +0 -82
  291. package/src/quadrant/layout.ts +0 -191
  292. package/src/quadrant/parser.ts +0 -183
  293. package/src/quadrant/renderer.ts +0 -322
  294. package/src/quadrant/types.ts +0 -113
  295. package/src/render-family-hooks.ts +0 -244
  296. package/src/renderer.ts +0 -1099
  297. package/src/route-contracts.ts +0 -2723
  298. package/src/scene/backend.ts +0 -76
  299. package/src/scene/fidelity.ts +0 -183
  300. package/src/scene/hybrid-backend.ts +0 -174
  301. package/src/scene/ir.ts +0 -181
  302. package/src/scene/marks.ts +0 -127
  303. package/src/scene/rough-backend.ts +0 -378
  304. package/src/scene/seed.ts +0 -46
  305. package/src/scene/style-registry.ts +0 -556
  306. package/src/sequence/layout.ts +0 -456
  307. package/src/sequence/parser.ts +0 -255
  308. package/src/sequence/renderer.ts +0 -604
  309. package/src/sequence/types.ts +0 -154
  310. package/src/shape-clipping.ts +0 -351
  311. package/src/shared/accessibility-directives.ts +0 -22
  312. package/src/shared/batched.ts +0 -61
  313. package/src/shared/color-math.ts +0 -72
  314. package/src/shared/svg-a11y.ts +0 -29
  315. package/src/shared/syntax-error.ts +0 -17
  316. package/src/shared/unicode-ranges.ts +0 -135
  317. package/src/styles.ts +0 -318
  318. package/src/svg-paths.ts +0 -28
  319. package/src/text-metrics.ts +0 -248
  320. package/src/theme.ts +0 -639
  321. package/src/timeline/layout.ts +0 -381
  322. package/src/timeline/parser.ts +0 -215
  323. package/src/timeline/renderer.ts +0 -538
  324. package/src/timeline/types.ts +0 -105
  325. package/src/types.ts +0 -454
  326. package/src/website-worker-modules.d.ts +0 -18
  327. package/src/xychart/axis-utils.ts +0 -109
  328. package/src/xychart/colors.ts +0 -124
  329. package/src/xychart/config.ts +0 -88
  330. package/src/xychart/layout.ts +0 -656
  331. package/src/xychart/parser.ts +0 -504
  332. package/src/xychart/renderer.ts +0 -640
  333. package/src/xychart/types.ts +0 -282
@@ -1,82 +0,0 @@
1
- # Diagram-family citizenship ratchet
2
-
3
- Issue: #41. Status: enforced checklist + checked matrix.
4
-
5
- A diagram family is a **good citizen** when it is integrated into every runtime, documentation, agent, editor, eval, and distribution surface that teaches users or agents what Agentic Mermaid supports. Rendering is not enough: a family must be discoverable, safely editable when its modeled body narrows, verifiable before render, represented in examples/evals, and either backed by evidence or tracked as an explicit exception.
6
-
7
- ## Source of truth
8
-
9
- `BUILTIN_FAMILY_METADATA` in `src/agent/families.ts` is the canonical shipped-family registry. It records the family id, label, Mermaid headers, typed narrower, live-editor example id/type, and editor glyph. The registry has compile-time coverage against `DiagramKind`; tests then project it into CLI capabilities, MCP/Code Mode, docs, editor examples, eval fixtures, package keywords, and generated discovery docs.
10
-
11
- The checked citizenship matrix lives at [`diagram-family-citizenship.matrix.json`](./diagram-family-citizenship.matrix.json). It is intentionally separate from the registry: the registry says “this family ships”; the matrix says “these citizenship surfaces are satisfied, and these remaining gaps are tracked.”
12
-
13
- ## Semantic correctness vs. system citizenship
14
-
15
- Keep these distinct in reviews:
16
-
17
- - **Semantic correctness** asks whether a parser/IR/serializer/verifier/renderer preserves the family’s own Mermaid meaning. Examples: Gantt schedule resolution, flowchart route certificates, sequence segment preservation, pie percentage invariants, XY axis/domain laws.
18
- - **System citizenship** asks whether every supported entry point points to the same typed path. Examples: `am capabilities`, `llms.txt`, `am init-agent`, MCP initialize guidance, SDK declarations, Code Mode sandbox narrowers, editor examples/glyphs, eval fixtures, generated site samples, package exports, and docs tables.
19
-
20
- A new family can be semantically good and still fail citizenship if an agent discovering the package through a different surface cannot find the same parse → narrow → mutate → verify → serialize path.
21
-
22
- ## Checklist surfaces
23
-
24
- The matrix has one cell per family for each surface below. A cell is either `satisfied` with concrete evidence paths, or `exception` with a tracked TODO/issue reference. CI fails if a registered family is missing a row, a surface, evidence, or exception tracking.
25
-
26
- | Surface | Contract |
27
- |---|---|
28
- | `registryDiscovery` | Family appears in `BUILTIN_FAMILY_METADATA`, registered plugins, CLI capability metadata, and typed IDs. |
29
- | `detectionParse` | Shared detector, agent parse, SVG render, ASCII render, CLI, and MCP paths route consistently; state’s flowchart renderer split is the only documented exception. |
30
- | `semanticModel` | Modeled syntax subset and opaque/source-preservation ladder are explicit. |
31
- | `serializeRoundTrip` | Modeled syntax has parse → serialize → parse stability; opaque/segment-preserved syntax round-trips losslessly. |
32
- | `typedMutation` | A public narrower and mutation ops exist, and opaque fallback bodies do not fake structured mutation. |
33
- | `verifyRenderSeam` | Modeled syntax has no “verify ok, render throws” path; render-blocking conditions surface as named warnings/errors. |
34
- | `determinism` | No ambient wall clock/random/locale/process-order dependence; runtime knobs such as `ganttToday` are explicit. |
35
- | `svgRender` | SVG/PNG-capable rendering path is covered for the family. |
36
- | `asciiUnicodeRender` | ASCII/Unicode output is covered when advertised. |
37
- | `layoutProjection` | `layoutMermaid`, quality metrics, and verify layout expose truthful geometry, not placeholder data. |
38
- | `stableRegions` | Region metadata for editor/TUI/accessibility is present or explicitly tracked as a gap. |
39
- | `editorExample` | Live editor has a working `Supported diagrams` example and explicit glyph for the family. |
40
- | `docsAgentSurfaces` | README/docs/spec/skills/agent instructions/SDK declaration/llms surfaces stay in sync. |
41
- | `evalFixture` | Shared skill benchmark has at least one fixture-backed case tagged `family:<id>`. |
42
- | `upstreamHarvest` | Official upstream Mermaid examples/tests are harvested into an executable docs corpus, family bench, or accounted parser/DB bench. |
43
- | `divergenceLedger` | Known compatibility divergences in harvested upstream examples/tests are executable and cannot rot, or tracked for ledger work. |
44
- | `domainProperties` | Family-specific invariants/properties exist beyond “renders without throwing.” |
45
- | `goldensEvidence` | Text/SVG/visual evidence exists where reviewer judgment needs artifacts. |
46
- | `generatedSite` | Site samples/gallery/generated docs include the family or have explicit exceptions. |
47
- | `distributionPackage` | Package exports/files/consumer init artifacts include the public family surface. |
48
- | `mutationLane` | Targeted mutation/sabotage lane exists, or a tracked exception explains the gap. |
49
-
50
- ## Worked example: Gantt
51
-
52
- Gantt is the bar for a new family entering the system:
53
-
54
- - registry + mutation: `BUILTIN_FAMILY_METADATA`, `asGantt`, typed Gantt ops, CLI capabilities, SDK declaration, MCP sandbox, and `am init-agent` all expose the same path;
55
- - semantics: `src/gantt/parser.ts`, `src/gantt/schedule.ts`, `src/gantt/layout.ts`, and `src/agent/gantt-body.ts` keep scheduling pure and wall-clock-free;
56
- - verify/render seam: `UNRESOLVABLE_SCHEDULE` turns render-blocking schedule failures into named verification output;
57
- - compatibility: `eval/mermaid-gantt-bench/` has cases plus executable exclusions; `src/__tests__/gantt-upstream-bench.test.ts` runs it;
58
- - properties: `src/__tests__/property-gantt-schedule.test.ts` includes the CPM shadow-model property;
59
- - evidence: SVG snapshots, ASCII/Unicode goldens, `docs/assets/improvements/gantt-family.png`, and `mutation-test:gantt` cover reviewer-visible and sabotage paths;
60
- - editor/skill-evals/docs: editor examples, eval fixtures, docs, `llms.txt`, and MCP/Code Mode surfaces are all registry-checked.
61
-
62
- ## Non-Gantt audit: XY chart
63
-
64
- XY chart proves the checklist works for an older family that was promoted after the registry existed:
65
-
66
- - citizenship surfaces are satisfied for registry, detection, typed mutation (`asXyChart`), CLI/MCP docs, editor examples, eval fixtures, generated site samples, package exposure, SVG/ASCII output, and layout projection;
67
- - semantic correctness is pinned by parser/integration/layout/renderer tests and `src/__tests__/property-xychart.test.ts`;
68
- - mutation-testing citizenship is satisfied through `mutation-test:families`, which mutates `src/xychart/*` together with Architecture;
69
- - stable region citizenship is satisfied through `src/__tests__/agent-ascii-meta.test.ts`;
70
- - upstream-docs harvest/divergence citizenship is satisfied through the regenerated `eval/mermaid-docs-corpus/corpus.json`, executable `divergences.json` ledger, `eval/mermaid-gantt-bench/`, and the fully accounted cross-family parser/DB bench in `eval/mermaid-upstream-suite-bench/`.
71
-
72
- This is the intended ratchet shape: historical gaps are either closed or represented by a live checked cell. After the BUILD-22 backfill, the matrix has zero exceptions; if a future family introduces one, it must be tracked before merge.
73
-
74
- ## Review workflow
75
-
76
- When adding or changing a family:
77
-
78
- 1. Add/update `BUILTIN_FAMILY_METADATA` first.
79
- 2. Add/update parser, renderer, agent body, mutation ops, verify behavior, and examples.
80
- 3. Update the citizenship matrix row in the same PR. Prefer `satisfied` with evidence; use `exception` only with a concrete TODO/issue reference.
81
- 4. Run `bun test src/__tests__/diagram-family-citizenship.test.ts src/__tests__/agent-doc-sync.test.ts src/__tests__/editor-examples.test.ts src/__tests__/cli-capabilities.test.ts` before wider validation.
82
- 5. For any matrix exception introduced by the PR, add a follow-up issue or `TODO.md` entry before merge.
@@ -1,126 +0,0 @@
1
- # Harvesting Upstream Test Suites
2
-
3
- How to turn "we are compatible with Mermaid" from a claim into a measured,
4
- CI-gated number — by vendoring the *actual test suites* of upstream
5
- implementations and running their inputs against ours. First applied to Gantt
6
- (`eval/mermaid-gantt-bench/`); this guide generalizes the method so any family
7
- can repeat it. Pairs with [`adding-diagram-types.md`](./adding-diagram-types.md):
8
- do the harvest no later than the family's first release, and for not-yet-built
9
- families do it **before** implementation — it is the cheapest way to learn the
10
- real (as opposed to documented) semantics.
11
-
12
- ## What a harvest produces
13
-
14
- ```
15
- eval/mermaid-<family>-bench/
16
- README.md provenance (repos, files, fetch date, licenses), schema, reason codes
17
- cases.json portable parity cases: upstream inputs + upstream-derived expectations
18
- exclusions.json every upstream case we deliberately do NOT match, each with a reason
19
- src/__tests__/<family>-upstream-bench.test.ts the runner (CI, every PR)
20
- ```
21
-
22
- The contract that keeps it honest:
23
-
24
- 1. **Every portable case passes.** Cases assert what upstream asserts —
25
- nothing more (our own stronger guarantees belong in our unit/property
26
- tests, not in the parity bench).
27
- 2. **Every exclusion is explained by a reason code**, and where the entry
28
- names an `oursErrorCode`, the runner **executes it** — proving we fail
29
- with exactly that named error. A divergence ledger that runs cannot rot.
30
- 3. **API-internal upstream tests are listed as not-portable** in the bench
31
- README (state-reset tests, internal helper unit tests, renderer DOM
32
- assertions) so "the entirety of their suite" is fully accounted for.
33
-
34
- Template to copy: `eval/mermaid-gantt-bench/` +
35
- `src/__tests__/gantt-upstream-bench.test.ts`.
36
-
37
- ## Where the upstream tests live
38
-
39
- | Source | Path | What to take |
40
- |---|---|---|
41
- | mermaid grammar specs | `packages/mermaid/src/diagrams/<family>/parser/<family>.spec.js` | Source strings + structural assertions (titles, ids, tags, click bindings). Mostly portable. |
42
- | mermaid semantics specs | `packages/mermaid/src/diagrams/<family>/<family>Db.spec.ts` (some families: `<family>Db.spec.js`, or logic specs beside the db) | The valuable layer: resolved values, ordering, edge cases. Portable after normalization; this is where wall-clock/TZ landmines hide. |
43
- | mermaid rendering specs | `cypress/integration/rendering/<family>.spec.js` | Inputs only — assertions target THEIR svg dom. Usually redundant with the docs corpus. |
44
- | mermaid docs examples | `packages/mermaid/src/docs/syntax/<file>.md` | Already wired: add the file to `FILE_TO_FAMILY` in `eval/mermaid-docs-corpus/build-corpus.ts` and floors to `src/__tests__/agent-mermaid-corpus.test.ts`. Docs are de facto behavior — they contain tolerated junk (see gotcha 3). |
45
- | ASCII forks | `pgavlin/mermaid-ascii` (`pkg/<family>/<family>_test.go`), `kais-radwan/ascii-mermaid` (`ts/test/<family>.test.js`), `AlexanderGrooff/mermaid-ascii` | Inputs + render-smoke only; their byte-level output assertions are theirs. |
46
- | oracle library | `mermaid-ast` (already a dependency) | A parsing differential (`<Family>.parse(...).toAST()`), not a semantics oracle — it does not resolve values. |
47
-
48
- Fetch raw files from the `develop` branch
49
- (`https://raw.githubusercontent.com/mermaid-js/mermaid/develop/<path>`), record
50
- the fetch date in the bench README, and **check the license before vendoring**
51
- (mermaid and both ASCII forks are MIT — attribute in the README; a repo with
52
- no license file must not be vendored, only summarized).
53
-
54
- ## The method
55
-
56
- 1. **Read both spec files end to end** before extracting anything. Count the
57
- `it(`/`it.each` blocks; every one must land in cases.json, exclusions.json,
58
- or the README's not-portable list.
59
- 2. **Classify each test**: `parse` (structural fields), `schedule`/semantic
60
- (resolved values), `error` (both sides reject), excluded (reason code), or
61
- API-internal (not representable as diagram source — note it).
62
- 3. **Normalize expectations, never inputs.** Inputs are vendored verbatim.
63
- Their local-time `new Date(y, m, d)` tuples become UTC ISO strings; their
64
- auto-synthesized ids (`task1`…) become index-based assertions; their
65
- boolean tag flags become tag sets.
66
- 4. **Run, and treat every failure as information.** A failing harvested case
67
- is one of: a real bug in ours (fix it), a deliberate spec divergence (move
68
- to exclusions with a reason + executable error code), or an upstream
69
- behavior our spec should adopt (change ours — the gantt `tickInterval
70
- 1decade` case). Decide explicitly; never weaken a case to make it pass.
71
- 5. **Gate it**: the runner is a normal `bun test` file; the docs-corpus floors
72
- are evidence-based and regression-only, with a comment naming each entry
73
- that holds the floor below 1.00 and why that is honest.
74
- 6. **Re-run the search before each release** for new upstream tests (the
75
- family's design doc should carry the watchlist of in-flight upstream
76
- syntax, as `docs/design/families/gantt.md` does).
77
-
78
- ## Exclusion reason codes
79
-
80
- Reuse these before inventing new ones, and document any new code in the bench
81
- README (the runner asserts every reason is documented):
82
-
83
- - `wall-clock-fallback` — upstream substitutes `new Date()` for missing or
84
- unparseable inputs; our determinism contract mandates named errors. Always
85
- executable (`oursErrorCode`).
86
- - `local-tz` — the upstream test only means something in a specific timezone
87
- (they themselves gate the gantt DST test behind `TZ=America/Los_Angeles`).
88
- - `silent-ignore-vs-named-error` — upstream tolerates a token its own docs
89
- call unsupported; we error by name per the family spec.
90
- - `exclude-boundary-model` (and siblings) — a real semantic difference,
91
- precisely characterized. Where possible state the conservation law both
92
- sides satisfy and exactly which inputs diverge.
93
-
94
- ## Gotchas the gantt harvest hit (check for each of these)
95
-
96
- 1. **Wall-clock expectations hide inside table tests** — scan for
97
- `new Date()` with no arguments and `setHours(0, 0, 0, 0)` in expected
98
- values, not just in implementation code.
99
- 2. **TZ/DST-gated tests** can't run verbatim against a UTC-only engine; port
100
- the input, assert our UTC behavior, ledger the difference.
101
- 3. **Official docs contain tolerated junk** (`tickInterval 1decade`, a task
102
- ending `1s %% not yet official`). Docs examples are inputs users will
103
- paste, so decide tolerate-vs-error consciously against the family spec and
104
- put the decision in the ledger either way.
105
- 4. **Boundary semantics can differ while conservation laws agree** — gantt's
106
- exclude-walk counts `(start, end]` upstream vs our `[start, end)`. A
107
- property test of the conservation law plus a ledger entry for the boundary
108
- beats chasing instant-for-instant parity.
109
- 5. **The harvest finds seams, not just bugs**: the very first harvested gantt
110
- case exposed verify saying ok while render threw, which became the
111
- `UNRESOLVABLE_SCHEDULE` warning. When a harvested input behaves
112
- inconsistently across our own surfaces (parse vs verify vs render), that
113
- inconsistency is the finding.
114
- 6. **Upstream resolves more than you may assume** — their gantt resolver
115
- handles forward references; we had documented the opposite. The harvest
116
- corrects folklore about upstream as a side effect.
117
-
118
- ## Definition of done
119
-
120
- - Every upstream test block accounted for (cases / exclusions / not-portable).
121
- - All cases green; all executable exclusions green; bench README has
122
- provenance, fetch date, licenses, schema, and reason codes.
123
- - Docs-corpus family entries + floors wired (`build-corpus.ts`,
124
- `agent-mermaid-corpus.test.ts`).
125
- - Divergences that changed our behavior are reflected in the family's design
126
- doc and CHANGELOG.
@@ -1,276 +0,0 @@
1
- # Lessons learned
2
-
3
- Process lessons this repo has paid for, so they only have to be paid for once.
4
- Each entry names the incident that taught it. Add new lessons at the top with a
5
- date; do not delete old ones — supersede them in place.
6
-
7
- > **Scope.** This is the dated contributor process log. For the long-form
8
- > cumulative fork narrative (loops 1–22), see
9
- > [`../project/lessons-learned.md`](../project/lessons-learned.md).
10
-
11
- ## 2026-07 — style coverage and typography semantics
12
-
13
- **A style transform is a semantic contract, not a blanket SVG rewrite.**
14
- The first style-coverage pass made typography expressive enough to expose an
15
- important boundary: class names, entity names, relationship labels, section
16
- labels, chart titles, and task labels are diagram labels; class members and ER
17
- attributes are schema/code-like literals. Uppercasing `Account` to `ACCOUNT`
18
- is a look. Uppercasing `displayName`, `createdAt`, `orderId`, or
19
- `closeAccount(reason: string)` destroys authored signal. Rule: label transforms
20
- apply to labels; syntax-like internals still participate in role-token paint
21
- and contrast audits, but keep authored casing unless a future explicit
22
- `member`/`attribute`/`syntaxText` policy says otherwise.
23
-
24
- **Measure the text the renderer will actually draw.** Aggressive typography is
25
- not layout-neutral: uppercase, weight, letter spacing, and compact labels all
26
- change measured width and row/axis/title budgets. The Gantt fix had to measure
27
- the transformed/tracked text, not the Mermaid source token, before rendering
28
- compact task labels and axes. Rule: any layout that reserves space for text
29
- must run the same transform path that the renderer uses, or the style will pass
30
- unit tests while visibly clipping in the editor.
31
-
32
- **Coverage evidence has to separate plumbing, readability, and taste.** The
33
- state-space diagram and galleries explain what the style catalog covers, but
34
- the durable gate is `style:audit`: every built-in family is rendered with
35
- sentinel role tokens, role propagation is checked, and contrast floors are
36
- enforced. Visual galleries answer "are these looks differentiated?"; the audit
37
- answers "does the style system reach the elements it claims to reach?" Keep
38
- both, and be explicit about the remaining gap: arbitrary user-authored
39
- style/palette stacks are not yet universally WCAG-proved.
40
-
41
- ## 2026-07 — the layout-shift audit and look-control rework
42
-
43
- **User-initiated layout shift is CLS-exempt but still visible jank — diff
44
- positions, don't trust the metric.** A whole-site audit read CLS 0.000
45
- everywhere, yet clicking the home "Use with an agent" button slid its
46
- neighbours 83px, selecting a diagram style reflowed the wrapped mobile topbar
47
- by a full row (the theme dropdown jumped 284px), and the editor's "Copy agent
48
- prompt" slid 81px. All fired within 500ms of the click, so `hadRecentInput`
49
- flagged them out of the Core Web Vitals number. Rule: to audit click-induced
50
- shift, diff each anchor's bounding rect before/after the interaction and read
51
- the raw (unfiltered) `layout-shift` entries — CLS alone certifies nothing about
52
- what the user sees at the moment they click.
53
-
54
- **A width reservation is only correct once you check every breakpoint it
55
- crosses.** The Share button grew ~7px when its label became "Copied"; the
56
- obvious fix — a permanent inline `min-width` — would have overridden the
57
- ≤760px `font-size:0` rule and broken the mobile icon-only square, because
58
- inline styles beat media queries. Reserving the label's width in `em` instead
59
- collapsed to 0 exactly when the mobile rule zeroed the font. Rule: prefer a
60
- unit/property the responsive rules can still override, and verify the
61
- reservation at each breakpoint it passes through before shipping it.
62
-
63
- **A layout invariant stated in a component's own copy is a test spec.** The
64
- seed-shuffle button's tooltip said "(never moves layout)" — true when clicked,
65
- false when it *appeared*, which is what reflowed the topbar. The existing
66
- style-switch test asserted "the chrome never moves" but only compared colours,
67
- so the regression passed straight through it. Rule: when a component claims a
68
- layout invariant (in a tooltip, a comment, or a test's own name), the guarding
69
- test must assert positions, not a proxy like colour.
70
-
71
- **Restructure by re-wrapping markup and re-scoping CSS; touch the JS only when
72
- an id or class contract actually changes.** Fusing the Style and Theme
73
- dropdowns into one split pill kept every button/wrap/menu id and the `.open`
74
- class the shared popup controller toggles, so selection, keyboard, and focus
75
- logic ran unchanged — the only rename was a CSS-only button class. Rule: when
76
- JS binds elements by id and toggles known classes, a visual restructure is a
77
- markup + CSS job; reading the id/class contracts first tells you whether the JS
78
- is even in scope.
79
-
80
- **Label from the code's own vocabulary, and check the word against its sibling
81
- controls.** "Theme" for the palette axis collided with the adjacent light/dark
82
- toggle and with Mermaid's `themeVariables`, and was category-muddy (internally
83
- a theme is a palette-only style) — while the style registry, CLI, and docs
84
- already called it a "palette." Relabelling to "Palette" was three visible
85
- strings with no code rename: there is no public `theme` render field, and
86
- renaming `state.theme` / `data-theme` / the localStorage key would have broken
87
- saved editor state and share links. Rule: audit where a term is actually used
88
- before putting it on a control; a user-facing label is not an API, and the two
89
- are allowed to differ.
90
-
91
- ## 2026-07 — the website consolidation PR (#113)
92
-
93
- **A long-running branch that commits generated output collides catastrophically
94
- with a base that stops committing it — keep website changes source-only.** PR
95
- #113 committed the whole `website/public` bundle (100+ files) across nine
96
- commits. Meanwhile `main` (#110) had made `website/public` a gitignored build
97
- artifact, rebuilt by the test preload and at deploy. The result was a "dirty"
98
- PR whose merge was ~20 modify/delete conflicts on generated pages — the actual
99
- change (five source files) was buried under hundreds of artifact diffs.
100
- Resolution was to adopt the artifact model (`git rm -r website/public`, keep
101
- only `build.ts`, `source/pages`, the contract test, and `TODO.md`), which
102
- collapsed the PR from ~86 changed files to 5. Rule: never commit
103
- `website/public`; a website PR's diff is source only. A committed generated
104
- bundle turns every base change into a conflict and hides the real edit in noise.
105
-
106
- **Deterministic build + `website:check` can pass on wrong-but-deterministic
107
- output — assert content, not existence.** The sitemap (the PR's headline
108
- feature) shipped with only an `existsSync` gate. Because the build is
109
- deterministic and `website:check` only diffs regenerated-vs-committed output, a
110
- stale or malformed sitemap would regenerate identically and pass every gate —
111
- the wrong output is reproduced, not caught. A multi-agent audit flagged it; the
112
- fix asserts the sitemap lists exactly the live pages (no removed routes, no
113
- machine artifacts, one `<loc>` per page) and was verified red→green by injecting
114
- a removed route. Rule: for generated content, the test must *discriminate*
115
- correct from incorrect output, because determinism guarantees a wrong generator
116
- passes a same-vs-same check.
117
-
118
- **`bun test` green is not `tsc` green, and a piped exit code lies.** A new test
119
- passed `bun test` but failed strict `bun x tsc --noEmit` — a `matchAll` capture
120
- group is typed `string | undefined`. It nearly shipped because
121
- `bunx tsc … | tail` printed "exit: 0": the pipeline's status was `tail`'s, not
122
- tsc's, masking two real type errors. Rule: run the actual CI gate
123
- (`bun x tsc --noEmit`) after adding tests, and read `${PIPESTATUS[0]}` (or drop
124
- the pipe) so a tool's failure is never hidden behind a successful `tail`/`grep`.
125
-
126
- **Check what the platform already serves before adding a competing file.**
127
- Production serves Cloudflare's *managed* content-signals `robots.txt` at the
128
- edge; a repo `website/public/robots.txt` would likely have been shadowed and
129
- never delivered its `Sitemap:` line. A live `curl` settled it — the repo file
130
- was removed and the directive routed to the Cloudflare dashboard (TODO DEC-5).
131
- Corollary: for platform-managed surfaces (robots.txt, headers, redirects),
132
- verify the live response before shipping an asset that may never win. And a
133
- related cleanup that landed the same PR: hand-maintained parallel route lists
134
- drift (the `_redirects` list had silently dropped `/about/design`) — derive
135
- them from one source (here, the emitted-pages map) to delete the drift class.
136
-
137
- ## 2026-07 — the brand-system and chrome-polish passes
138
-
139
- **Design intent and shipped hex drift apart; compute claims on what shipped.**
140
- The pine accent was chosen 28° of OkLCH hue from the semantic success green —
141
- in the design tool. The shipped hexes had converged to 15° apart (11° in dark
142
- mode): links and "Copied" confirmations read as one colour, worse for
143
- deuteranopes, and the review that picked pine had cited the design-intent
144
- number. The separation now lives as an executable claim
145
- (`chrome-token-lockstep.test.ts` asserts ≥ 20° on the shipped values). Rule:
146
- any colour-relationship claim is computed on the committed hex, and if the
147
- relationship matters, it becomes a test.
148
-
149
- **A "keep in lockstep" comment is a hope; a test is a guarantee.** Three files
150
- carried the shared chrome tokens (site stylesheet, editor stylesheet, and the
151
- editor's `chromeThemeColors()` in JS), synchronized only by comments — and a
152
- 12% vs 13% hairline drift had already shipped that way. The lockstep test now
153
- extracts the triplet, brand chip, functional hues (both polarities), radii,
154
- motion tokens, and the hairline mix from all three sources and asserts
155
- equality. Corollary: the first draft of that test was itself rejected by the
156
- repo's test-quality lint (`toBeTruthy`) — new guard code has to pass the
157
- house's existing guards.
158
-
159
- **A rebrand includes the assets nobody opens.** Months of chrome work shipped
160
- while `og-image.png` still read "Beautiful Mermaid — by the team at Craft":
161
- the upstream project's card, wrong name, pre-fork palette, posted on every
162
- social share of the site. The CSS was audited to the percent; the PNG was
163
- never looked at. Rule: a brand change enumerates its raster/social surfaces —
164
- og-image, touch icons, favicon, README-rendered artifacts, repo social
165
- preview — and someone *views* each one.
166
-
167
- **Breakpoint boundaries hide unreachable controls; probe them mechanically.**
168
- Between 761 and ~1000px the editor topbar clipped with no scroll path — Copy
169
- agent prompt and Export Image were simply unreachable on an iPad portrait,
170
- 8px above the mobile breakpoint. Nothing failed: no overflow, no console
171
- error, desktop and phone both fine. The check that catches it is mechanical
172
- (every interactive element's bounding rect inside `innerWidth`, sampled just
173
- above each breakpoint), and the fix is a policy, not a tweak: toolbars either
174
- wrap or scroll; they never assume they fit.
175
-
176
- **When one value moves, its coupled values move with it.** The iOS input-zoom
177
- fix (16px fields under coarse pointers) would have silently desynced the
178
- line-number gutter, which shares the textarea's font metrics row-for-row; the
179
- `forced-colors` block predated the new functional tokens and left them
180
- unmapped under Windows High Contrast. Both were caught only by asking "what
181
- else derives from or aligns with this?" before shipping. Same failure shape
182
- in both: a correct local change, an unenumerated dependency.
183
-
184
- **Verify a suspected gap exists before fixing it.** A review flagged popover
185
- keyboard handling (Escape, focus restore) as unaudited. The audit found a
186
- shared `createPopupController` already covering all seven popovers, including
187
- roving tabindex in the theme listbox. "Audited, no change needed" is a
188
- result worth reporting; patching per-component without looking for the shared
189
- mechanism would have added the inconsistency it meant to prevent.
190
-
191
- **Consistency work starts with a census, not a scroll-through.** Grep every
192
- value class and count occurrences (radii, durations, easings, font sizes,
193
- press scales, icon strokes, z-indexes, gaps) — the count-one entries are the
194
- findings. This surfaced 58 untokenized transition durations, three press
195
- scales where the system wanted one, five icon stroke weights where two were
196
- deliberate, and seven magic z-indexes with an accidental popover-above-popover
197
- ordering. Eyeballing pages finds none of these reliably.
198
-
199
- ## 2026-07 — the label-overlap audit and remediation
200
-
201
- **A metric you never measure is a defect class you ship.** No gate measured
202
- label-label or label-box occlusion in any family until the 2026-07 audit — and
203
- the curated, human-reviewed corpus itself carried collisions in five families
204
- (architecture edge-label pairs, quadrant point labels, gantt compact rows,
205
- state reciprocal pills, flowchart feedback pills). The blind spot had even been
206
- *seen* and deferred (issue #42's review explicitly carved out "a separate
207
- label-lane/self-loop policy") — deferral without an owner issue is how a known
208
- gap becomes an ambient defect. Rule: every deferral gets a filed issue at
209
- deferral time (see the closure-hygiene lesson below).
210
-
211
- **Detector first, then the fix, then the detector becomes the gate.** The
212
- remediation sequence that worked: build the overlap auditor → calibrate it on
213
- the curated corpus (which also separates auditor bugs from real defects — two
214
- of the initial finding classes were the auditor's own rotation and region-
215
- border mistakes) → fix family by family with the detector red first → land the
216
- detector as a permanent gate (`label-overlap-gate.test.ts`: corpus at zero,
217
- per-family fuzz ratchets). A fix without the standing gate would regress
218
- silently; a gate calibrated before the corpus was clean would have been
219
- disabled as noisy.
220
-
221
- **"Generator noise" is a hypothesis, not a verdict.** The deep-fuzz
222
- `offOutlineEndpoints` hits were dismissed as duplicate-parallel-edge generator
223
- artifacts — but duplicate parallel edges are *valid Mermaid*, and that same
224
- input class turned out to break certificate completeness (#83) and stack labels
225
- (70% of fuzzed state diagrams). When a fuzz class is excused, the excuse needs
226
- the same evidence bar as a fix: either the input is genuinely invalid, or the
227
- class gets an owner issue.
228
-
229
- **Fixing one flaky suite does not fix the policy.** Hours after the
230
- route-contracts seeds were pinned (#86), a *different* property file
231
- (`property-mermaid-source-and-parser.test.ts`) failed CI on a rolled seed — its
232
- generator emitted grammar-ambiguous ids (`s---Py3` reads as the link
233
- `s --- Py3`, in this engine and in Mermaid) that only rare seeds produce. Two
234
- sub-lessons: property generators must be constrained to inputs whose expected
235
- behavior is actually unambiguous, and a determinism policy has to be applied as
236
- a sweep (every fast-check suite), not incident-by-incident.
237
-
238
- **An invariant enforced by a random property is a lottery, not a gate.**
239
- Certificate completeness was guarded only by an unpinned fast-check property —
240
- it fired roughly one CI run in seven, which reads as "flaky CI" rather than
241
- "real bug" and trains people to re-run. Invariants get deterministic gates
242
- (enumerated corpus + pinned seeds); randomness is for *finding* new
243
- counterexamples (deep fuzz lanes), not for *holding* known ground.
244
-
245
- **A dead quality signal is worse than no signal.** Every CI run printed "the
246
- mutation score is the adequacy signal" while the nightly mutation lane had been
247
- timing out (cancelled) for over a week — the signal's *existence* was asserted
248
- by docs while its *output* was absent, and nothing alarmed. If a scheduled
249
- gate's failure/cancellation isn't itself surfaced (a required check, a badge, a
250
- notification), the gate will die quietly exactly when it matters.
251
-
252
- ## 2026-07 — tracker archaeology (issues 1–83)
253
-
254
- **Closure needs receipts on the issue, at closure time.** The audit found
255
- issues closed with zero receipts (#29, #34, #36, #41), an issue closed against
256
- its own last comment (#32), and closures that predated their fix (#37, #38's
257
- first close). Each needed a later archaeology pass to reconstruct. The rule
258
- this repo now follows: an issue closes with a comment naming the receipts
259
- (tests, docs, PRs, measurements) — and if part of the scope is deferred, the
260
- follow-up issue is filed *in the same action* (#87–#90 are the back-fill for
261
- past deferrals).
262
-
263
- **A pass that mutates geometry owns the consequences of the mutation.** Three
264
- post-freeze repairs re-routed edges and dropped their certificates without
265
- re-issuing them (#83); the shove pass moved nodes and left overlaps behind
266
- (#81). The doctrine that fixed both: any pass that mutates layout state must
267
- hand every invariant on — re-anchor the edges it moves, re-certify the routes
268
- it rewrites, re-separate the boxes it displaces. "A later pass will catch it"
269
- is how symptom-repair whack-a-mole starts.
270
-
271
- **Fix the invariant upstream, keep the net downstream.** The #81 degenerate
272
- class (18 fuzz signatures) collapsed to zero by restoring one upstream
273
- invariant (no node overlaps after a shove) — after a session of fixing
274
- individual routing symptoms had removed only one sub-class. The post-freeze
275
- nets stay as insurance, but they are gated on violations that should never
276
- occur, not used as the primary mechanism.
@@ -1,71 +0,0 @@
1
- # Releasing `agentic-mermaid` to npm
2
-
3
- The package is published by [`.github/workflows/publish.yml`](../../.github/workflows/publish.yml),
4
- which triggers on a **published GitHub Release**. The workflow reproduces CI's
5
- deterministic gate (tests, `tsc`, `hero:check`, `website:check`, golden-drift,
6
- incremental mutation), fuzzes the built bundle + packed tarball under Node,
7
- builds with `tsup`, and runs `npm publish --access public`. There is no manual
8
- `npm publish` step.
9
-
10
- Publishing uses **npm OIDC trusted publishing** — no `NPM_TOKEN` secret. The
11
- workflow mints a short-lived OIDC id-token (`permissions: id-token: write`), npm
12
- verifies it against the trusted-publisher config, and **provenance is generated
13
- automatically** (no `--provenance` flag).
14
-
15
- ## Preconditions (one-time, before the first release)
16
-
17
- - **Register the trusted publisher on npmjs.com.** On the (first-time: create the
18
- placeholder package, or use the org's package settings) package's
19
- Settings → Publishing access → "Add trusted publisher" → GitHub Actions, set:
20
- organization/user `adewale`, repository `agentic-mermaid`, workflow filename
21
- `publish.yml` (leave environment blank). This must be done before the first
22
- `npm publish` or it fails with an auth error.
23
- - **The GitHub repo must be public.** Provenance writes to a public transparency
24
- log and is **not** generated for private repos. If the repo must stay private,
25
- publishing works but without provenance.
26
- - **Three-way repository match.** The OIDC token's repo, the npmjs.com
27
- trusted-publisher config, and `package.json#repository.url`
28
- (`git+https://github.com/adewale/agentic-mermaid.git`) must all agree — they do.
29
- - **Account 2FA** on the publishing account (WebAuthn/FIDO; TOTP is being
30
- deprecated).
31
- - `npm view agentic-mermaid version` — confirm the version isn't already
32
- published (first release: expect a 404).
33
-
34
- The workflow pins Node 22 and upgrades to the latest npm (trusted publishing
35
- needs npm ≥ 11.5.1 / Node ≥ 22.14).
36
-
37
- ## Cutting a release
38
-
39
- 1. **Land everything on `main` green.** Releases are cut from `main`, whose CI
40
- has already run; `publish.yml` re-runs the deterministic gate + artifact fuzz
41
- as a backstop.
42
- 2. **Bump `version`** in `package.json` (first release is `0.1.0`). `llms.txt` /
43
- `am capabilities` derive the version from `package.json`, so no manual edit.
44
- 3. **Roll the changelog.** Retitle `## Unreleased` in
45
- [`CHANGELOG.md`](../../CHANGELOG.md) to `## <version> — <YYYY-MM-DD>` and open a
46
- fresh empty `## Unreleased` above it.
47
- 4. **Flip the "published" copy** (see below), commit via PR, and merge to `main`.
48
- 5. **Create the GitHub Release** on the merge commit (tag `v<version>`). Its
49
- publication fires `publish.yml`, which gates, builds, and publishes.
50
- 6. **Verify:** `npm view agentic-mermaid version` shows the new version;
51
- `npm install agentic-mermaid` into a scratch project resolves and its bins run.
52
- 7. **After the first publish,** set the package on npmjs.com to
53
- "Require two-factor authentication and disallow tokens" — trusted publishing
54
- keeps working, and token-based publishing is locked out.
55
-
56
- ## The "published" flip
57
-
58
- Before the first npm publish, the repo deliberately said *"not yet published;
59
- install from source"*. The 0.1.0 release-prep PR flips these surfaces to the
60
- published copy:
61
-
62
- - **Website** — the install card is generated by [`website/build.ts`](../../website/build.ts)
63
- (run via `bun run website`, deployed to Cloudflare Workers with `wrangler` via
64
- [`.github/workflows/deploy-cloudflare.yml`](../../.github/workflows/deploy-cloudflare.yml)).
65
- The default release build shows `npm i agentic-mermaid`; use
66
- `SITE_NPM_STATUS=source` or `SITE_NPM_PUBLISHED=0` only for pre-publish source
67
- install previews.
68
- - **README** — npm-install-first [Installation](../../README.md#installation)
69
- copy and the `Published on npm as agentic-mermaid` status line.
70
- - **`docs/getting-started.md`** — `npm install agentic-mermaid` is the primary
71
- Install block.
@@ -1,53 +0,0 @@
1
- # Visual review evidence
2
-
3
- Agentic Mermaid layout changes need evidence that is reproducible from source,
4
- not hand-edited screenshots. Use the smallest artifact that matches the change.
5
-
6
- ## Required evidence by change type
7
-
8
- | Change type | Required evidence |
9
- |---|---|
10
- | Route contracts, ports, shape anchors, or contact geometry | `bun test src/__tests__/route-contracts.test.ts src/__tests__/contact-sheet.test.ts`; regenerate/review `docs/pr-assets/contact-sheet.png` when scenarios or geometry intentionally change. |
11
- | Duplicate / parallel edges (a multigraph — the same directed pair written more than once) | `bun test src/__tests__/route-contracts.test.ts`; review the duplicate/parallel cases on the contact sheet (`AP`–`AR`) and the crossing ratchet in `layout-rubric.test.ts`. A duplicate-specific before/after lives at `docs/pr-assets/issue-62-duplicate-edge-lanes-before-after.png` (regenerate with `bun run scripts/pr-assets/issue-62-evidence.ts`). |
12
- | ASCII/Unicode routing or region metadata | Exact goldens/tests: `bun run goldens:ascii:check` plus relevant `src/__tests__/ascii*.test.ts` / `agent-ascii-meta.test.ts`. |
13
- | Family renderer/layout changes | Family parser/layout/renderer tests, SVG snapshot where available, and `agent-family-layouts.test.ts`. |
14
- | Broad layout heuristics | `bun run rubric:visual` and/or `eval/layout-compare` before/after output attached to the PR. Commit only small canonical assets; attach large HTML reports as artifacts. |
15
- | Website/editor visual changes | `bun test e2e/browser.test.ts`; inspect captured screenshots when baselines or UI structure change. |
16
- | Region/action metadata only | Prefer JSON/SVG metadata assertions over raster screenshots; include one representative fixture proving stable `data-region`/sidecar IDs. |
17
-
18
- ## Artifact meanings
19
-
20
- - `docs/pr-assets/contact-sheet.png` is the committed reviewer contact sheet for route/port geometry. The byte-match test ensures it reflects the current renderer. Scenarios `AP`–`AR` cover duplicate/parallel edges: duplicates must render as evenly-separated, nested (non-crossing) parallel lanes — never a collapsed single line or a crossed pair.
21
- - The duplicate-edge crossing ratchet (`layout-rubric.test.ts`) counts duplicate-pair crossings over the random-flowchart generator and holds the count at or below its pinned baseline. Duplicate edges share both endpoints, so a crossing between them is never logically required; the baseline is a regression ceiling whose target is zero — lower it when the count drops.
22
- - `eval/visual-rubric` produces deterministic scored galleries. Its scores are a gate for obvious regressions, not a replacement for human review.
23
- - `eval/layout-compare` compares before/after layout faithfulness and quality over a corpus. “0 regressions” means no configured metric/faithfulness regression, not a claim of pixel parity with Mermaid.js.
24
- - Browser screenshots prove the shipped site/editor still renders and remains usable. Pixel-diff is only active when dependencies are available, so reviewer inspection still matters.
25
-
26
- ## Golden-snapshot drift gate (`[approve-goldens]`)
27
-
28
- Committed goldens under `src/__tests__/testdata/` are a **hard CI gate**, not an
29
- ignorable warning. The `ci.yml` "Golden snapshot drift" step fails the build if:
30
-
31
- - running the suite leaves **uncommitted** changes under `testdata/` (regenerate
32
- and commit them), or
33
- - the PR's HEAD commit **modifies** committed goldens **without** an approval
34
- line starting with `[approve-goldens]`.
35
-
36
- So when a renderer change legitimately moves goldens: regenerate them, **review
37
- the diff** (this is the human decision the gate enforces), commit the result,
38
- and **start a commit-message line** with `[approve-goldens]`. The token only
39
- counts at the start of a line — merely mentioning it mid-sentence (as this doc
40
- does) is not approval, so prose about the gate can't trip it. A standalone
41
- `[approve-goldens]` line on a commit that changes no goldens also fails, to keep
42
- the token meaningful. The gate logic lives in `scripts/ci/golden-drift.ts` and is
43
- unit-tested; the PR template restates it as a checklist item.
44
-
45
- ## Reviewer checklist
46
-
47
- 1. Does the PR say which visual command was run?
48
- 2. Are generated artifacts reproducible from committed source/fixtures?
49
- 3. If a committed PNG/snapshot changed, is the change explained in the PR body?
50
- 4. If a visual check is skipped, is there a reason and an alternate structural test?
51
- 5. Are large generated reports linked/attached rather than committed?
52
- 6. For peer fan-in/fan-out screenshots, is the hub centered over the peer group?
53
- 7. Does the review wrapper match the rendered diagram background, or use a neutral surface, so it does not create false label/background contrast?