d2 emits SVG natively; its PNG path wants a ~150 MB headless-Chromium download and prompts interactively, so every PNG here was produced by an out-of-band magick step. There is no Chromium on this system. Dropping PNG removes the dependency rather than trading one format for another, and cuts docs/diagrams/ from 17 MB to 3.3 MB. SVG renders in Gitea and in clide (`clide draw --file <path>`, which takes .d2 source directly), and diffs as text. One PNG is kept on purpose: design/star-map-concentric.png has no .d2 source. Also renders the 7 star-map .d2 files for the first time. star-map-plan.md listed their renders as a deliverable in March and the step never ran; the new `make check-diagrams` is what surfaced it. New: docs/diagrams/data-flow/wiki-generator-flow.d2 — which way the arrows point for any file under wiki/. Every edge was read in the tool's own source rather than inferred. It records the trap that keeps costing us: scaffold_bodies.py writes a body page once and never overwrites it, and the generator then reads that frontmatter directly — so a hand-edit there is not reverted, it is obeyed, and silently changes world generation. Two rendering traps found the expensive way and now written down: - A d2 `|md` block becomes an SVG <foreignObject>. ImageMagick and flutter_svg both silently drop it, so the legend was in the file and invisible in every viewer except a browser. Plain labels render as real <text> everywhere. - Container boxes fight the layout engine. Grouping nodes whose flow-depths differ forces long edge routes; this diagram went from an unreadable 2.4:1 sprawl to a legible 0.75:1 by deleting five containers and changing nothing else. Colour classes carry the grouping instead. make diagrams / make check-diagrams render and gate. Repo-specific rules in .claude/rules/diagrams.md; d2 syntax and the traps live in the user-scope d2-diagram skill, whose PNG default was flipped to SVG to match. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2.2 KiB
Diagrams
Use the user-scope Skill(d2-diagram) for d2 syntax, category templates, the
render scripts, and the rendering traps (the |md → foreignObject trap in
particular will cost you a render that looks authored and shows blank). This
file is only what is specific to this repo.
.d2 source + .svg render in docs/diagrams/{category}/ — categories in
use: architecture, data-flow, design, entity, state, ui.
make diagrams # render every .d2 -> .svg
make check-diagrams # fail if any .d2 lacks a .svg
clide draw --file docs/diagrams/data-flow/wiki-generator-flow.d2 # show the user
make diagrams is the repo's entry point rather than the skill's batch script,
so the convention holds for anyone without that skill installed.
Scratch renders go in .cache/ — never in docs/diagrams/, never in /tmp.
One PNG survives deliberately: design/star-map-concentric.png has no
.d2 source. Everything else under docs/diagrams/ is .d2 + .svg
(SVG-only since 2026-08-20; the flip cut the tree from 17 MB to 3.3 MB).
Some .d2 files are generator output — do not hand-edit
docs/diagrams/design/star-map-*.d2 (×7: overview, core,
north/south/east/west-reach, deep-frontier) are written by
tooling/generate-star-map.py alongside docs/design/star-map.json. The
concentric/realcoords/topology SVGs come from a second script,
tooling/generate-star-map-svg.py, and never pass through d2 at all.
Edit the generator and re-run it; a hand-edit is lost on the next run. Same
source-canonical rule as .claude/rules/asset-pipeline.md.
A diagram that names files goes stale silently
Nothing fails when a path in a diagram moves. So when writing one here:
- State what was verified in a header comment — whether edges were read in
the source or inferred.
wiki-generator-flow.d2says every path was read in the tool's own source; that claim is the diagram's value. - Say what it answers, in one line, at the top. A diagram without a stated question accumulates nodes.
- Cross-reference the D-record it illustrates, and reference the diagram back from that record, or it is unreachable from the governance tree.
Create or update a diagram when a D-record is added or amended.