SuperAPI AI Directory

diagram

Data & analytics

View repository

Updated 10-16 01:07

About this skill

diagram — draw exactly by machine, don't let the model make up shapes

Central principle, borrowed from archify and kept as-is because it's correct: model does NOT draw. The model only fills logic into a schema'd declaration (which blocks exist, how block A connects to block B). The rendering is the job of deterministic code. Once drawn, the machine re-inspects the layout itself; if broken, keep the previous good version and state clearly what's wrong, absolutely never emit a garbage shape.

That's also why this skill exists instead of letting the model draw SVG itself: a wrong shape still looks "sort of okay", so layout errors are the type of error that slips through the farthest.

WHAT

Purpose and context

  • Purpose: draw DIAGRAMS (relations/flows) and CHARTS (data) with deterministic code — the model only fills a schema'd declaration, the machine renders and self-inspects the layout; if broken, keep the previous good version and state clearly what's wrong.
  • Trigger (when to use): user says "draw a diagram", "draw a chart", "draw a flow", "architecture diagram", "processing flow", "flow", "graph", "chart", "visualization", "compare two flows", "draw a diagram", "sequence diagram", "state machine", "dependency graph", "plot", "dashboard", "convert Mermaid", "diff two flows" (full list at description).
  • Non-goals: NOT used for UI/landing page screens — that's hallmark. Don't hand-draw SVG coordinates for a new shape. Don't replace the generator for diagrams in auto-generated documents.

Mental model

câu hỏi người xem → có TRỤC SỐ? → Sơ đồ (ngữ pháp → archify) hoặc Biểu đồ (dataviz + 5 luật lieflat) → file HTML → cổng nhà (frontend-antipattern, tuỳ chọn visual-receipt) → giao nguyên tử (xanh mới thay, đỏ giữ bản cũ). Model fills logic; code renders; deterministic gate decides pass/fail.

Input and output contract

Field Required? Meaning
In description of the flow/relation or data yes the question the viewer needs answered
In diagram type no architecture, workflow, sequence, dataflow, lifecycle; if left blank the engine guesses
In existing Mermaid no paste it in, archify redraws it
In anchor to real code no sources[] + meta.repository + --repo-root (full 40-char SHA)
Out self-contained HTML file yes diagram or chart, through the home gate
Out gate verdict yes rc of frontend-antipattern.py (0 clean, 1 FAIL, 2 WARN only); optional visual-receipt.py (0 pass, 1 fail, 2 SKIPPED) + 4 images + JSON receipt + contact sheet

Rules and capabilities

  • RULE-01 (MUST): The model does not draw. The model fills in the declaration; code builds the figure. If you find yourself typing SVG coordinates by hand for a new figure, you have already gone down the wrong branch.
  • RULE-02 (MUST): Do not release junk figures. If the new version does not pass the gate, keep the old good version, and clearly report where it is wrong. This repo's generator already does exactly that (_deliver in build-overstack-docs.py: render to a temp file, run the gate on the temp file, only if green then os.replace).
  • RULE-03 (MUST): SKIP ≠ CLEAN. Missing Chrome, missing network, missing engine → say "skip", never report "pass". A gate that lies while still showing green is worse than no gate at all.
  • RULE-04 (MUST): Do not import an external engine's style constraints as house rules. Measure first: archify demands arrows be straight horizontal/vertical, but this repo's diagrams intentionally fan out (6·4·10 valid diagonals across three diagrams) — so that rule was rejected during absorption, while the other three geometry rules were accepted.
  • RULE-05 (MUST): For diagrams in auto-generated documents, use the generator, do not call an agent. Each diagram drawn via chat costs one agent turn, forever; SVG-generating code costs 0. Only use the chat branch for new figures or one-off figures.
  • Capabilities: call the deterministic diagram-drawing engine and the chart engine; run a 0-token static gate on HTML files; optionally run a real browser to capture and measure requests; write the destination file atomically.

Failure boundaries

  • Unclear whether there is a NUMERICAL AXIS → clarify (ask "does what I'm drawing have a NUMERICAL AXIS?").
  • The request is a product screen → blocked, hand off to hallmark.
  • Chart violates discipline (truncated axis, glow/3-D on data marks, data too thin) → refuse/downgrade with reasons, offer an honest alternative.
  • deliver red or gate FAIL → failed, the destination file remains the old good version; report where it is wrong.
  • Missing Chrome/network/engine → SKIP, never report "pass" (RULE-03).
  • Wrong code anchor (SHA not exactly 40 characters, origin does not match) → blocked (fail-closed).

HOW

Main workflow

Step Type Inputs Action Outputs/exit Failure/next
W01 judgment request Choose branch: has NUMERICAL AXIS → Chart; not → Diagram; screen → hallmark branch UI → blocked; ambiguous → clarify
W02 judgment viewer question Diagram: choose GRAMMAR (topology, sequence, process, state, hierarchy, matrix); one question one figure archify type two questions → two figures
W03 effect declaration Diagram: call archify in natural language or node ~/.agents/skills/archify/bin/archify.mjs (B01) HTML file rc 1 → failed, old version stays unchanged
W04 effect data Chart: load dataviz before the first line of code + 5 lieflat rules (B02) HTML file discipline violation → reject/downgrade
W05 deterministic HTML file Gate python3 fdk/tools/frontend-antipattern.py <file.html> rc 0 1 → fix declaration, repeat W03/W04
W06 deterministic HTML file Optional browser evidence python3 fdk/tools/visual-receipt.py <file.html> (B03) images + receipt 2 → report SKIPPED, do not report passed
W07 effect file that passed the gate Atomic delivery: green replaces the target file; red keeps the old good version + reports where it is wrong target file —

Details of each step (source of truth for W01–W07):

Choose the branch before doing anything

What you are representing Branch Engine
Relationships / flows / sequences between components (boxes + arrows) Diagram archify
Data — comparison, distribution, trend, proportion Chart dataviz + the lieflat discipline below
A product screen not the job here hallmark

Not sure? Ask: "does what I am drawing have a NUMBER AXIS?" Yes → chart. No → diagram.

Within the Diagram branch — choose the correct GRAMMAR before choosing an engine

Ask first: what question must the viewer be able to answer? — the question decides the grammar, the grammar decides what the drawing looks like (DISSOLVED from plannotator/effective-html, see [[design-foundation]]):

Viewer's question Grammar archify type example
What is there, connected to what? Topology / system diagram architecture
What happens over time? Sequence / timeline sequence
How does the decision/transformation happen? Process flow workflow
How does this change state? State diagram lifecycle
What contains/owns what? Hierarchy / containment architecture (nested branch)
How do the options compare with each other? Matrix / row-aligned comparison table, no archify needed
How much / how often / how fast? Quantitative chart → branch Chart below

Don't cram two questions into one figure. Need both → two figures (or toggle layers), not one overloaded figure. Once the grammar is chosen, then comes the engine selection step (HTML/CSS, SVG, Canvas, WebGL) per the section below.

DIAGRAM branch — via archify

External engine, PULLED EXTERNALLY per [[adapt-modes]]: we do not rewrite it, only pin + call. Install: npx skills add Rheinmir/archify -g -s archify (the real target is ~/.agents/skills/archify). This is a fork of tt-a1i/archify: adds a 5th preset macos (liquid glass + Roboto) and sets it as default — leaving it empty meta.visual_preset gives exactly the house theme, without applying any extra step. The patched branch macos-roboto is the DEFAULT branch of the fork, so no need to pin a ref.

Two traps we've already paid for, don't repeat them:

  • There is no flag --ref. And owner/repo@nhánh CANNOT pin the branch at install time: the CLI prints Source: …git @macos-roboto but still installs the default branch, and also understands the part after @ as a SKILL NAME so it reports No matching skills found. That's why we pin by default-branch, not by syntax.
  • -l cannot replace a real install. add … -l reports Found 1 skill green while the real install command still fails. Checking the install path must actually install and then draw a diagram, see what data-preset outputs.

When upstream releases a new version, rebase the branch, don't overwrite-install with tt-a1i/archify.

Call in natural language in chat — no command prefix:

Use Archify to draw: Browser -> API -> Redis cache -> PostgreSQL fallback.

State the TYPE clearly and there's no guessing — architecture · workflow · sequence · dataflow · lifecycle. Pasting in existing Mermaid works too, it redraws it nicely.

Three things you must know before calling, verified by actually running it:

  1. The package named "private": true — is not on npm. npx archify does not run. Every shell command is node ~/.agents/skills/archify/bin/archify.mjs ….
  2. Exit codes don't follow the 0/1 convention: 2 is both a usage error (unknown command, unknown flag, unknown diagram type) and "visual-check skipped because there's no Chrome". 1 is the real failure of validate/render/deliver. Calling it in CI must branch deliberately.
  3. After a deliver RED, don't go inspecting the target file — it's still the good OLD version, not the one that just failed. This is a direct consequence of atomicity, not a bug.

Separately lifecycle, three rules live in the code, not in the schema — measured 2026-09-10, patched at the fork so only a fresh install has them:

  • The lane name is the contract. main → upper band, terminal → lower band (Outcomes), every other id falls into the middle band. Naming it anything else (outcome, recover, …) drops into the middle band and collides — this is where 4 layout rounds got burned.
  • Two floors of different heights. No terminal band used → viewBox[1] ≥ 510; used → ≥ 630. Before the patch both reported 566, so declaring terminal at 566 drops into the loop "State exceeds the vertical lifecycle area" with no way out.
  • The main rail does NOT become a relationship on its own. The order step only draws lines; for Route Probe / passport / trace to see it you must declare a real transition (drop the label if the slot is narrow). Click a node and read the Semantic Passport: seeing No connected relationships means the diagram is hollow even though validate/visual-check are both green.

For an architecture diagram to stick to the real code, declare sources[] (path + line range) + meta.repository

  • --repo-root. That gate fail-closed: the revision must be a full 40-character SHA, --repo-root must be a top-level checkout with a matching origin . Wrong anchor and it refuses to draw.

CHART branch — dataviz + lieflat-charts discipline

Load the skill dataviz before writing the first line of chart code, in every environment (HTML, SVG, matplotlib/plotly/d3/Recharts, or a PNG that will render). Plus five rules absorbed from lieflat-charts, all stand above aesthetics:

  1. Refusing is CORRECT behavior, not stubbornness. Cutting an axis (broken axis) → refuse, offer three honest alternatives. Glow / glassmorphism / 3-D on data marks → refuse. More than six categories and still demanding color → fall back to a mono scale. Data too thin for the chosen form (three nodes and demanding a force graph) → downgrade and say why.
  2. Number of charts = number of INDEPENDENT conclusions, not number of data columns. One question → one chart; a whole article → four to six; cap six charts per page then split pages.
  3. The title is the CONCLUSION, not the chart-type name. "Churn doubles after the April release", not "Churn bar chart".
  4. Show the evidence for the chart choice. Name at least three candidates and the reason each was rejected BEFORE charting. "I used a bar chart" with no candidate rejected means you never chose.
  5. Deterministic render. Ban Math.random() in charts — two refreshes must produce exactly one image. One color system per file; mixing two means redo.

Once you have the HTML file — run the HOUSE gate

The engine guards its layout; the gate below guards what it doesn't know: this repo's conventions.

python3 fdk/tools/frontend-antipattern.py <file.html>     # 0 sạch · 1 FAIL · 2 chỉ WARN

It's deterministic and 0 tokens:

  • Geometry — two boxes partially overlap, a box outside viewBox, text overflows its container box.
  • Accessibility + self-contained — missing role="img", missing <title> or <title> is not the first child, <title>/<desc> empty, and remote reference http (a self-contained page that opened offline is missing images).
  • Evidence anchors — a node declares data-src="path" / data-src="path:line" but the path doesn't resolve, or the line number exceeds the file length. Fail-closed: if not declared it isn't asked, if declared it must be correct.

It needs real browser evidence (not just static analysis):

python3 fdk/tools/visual-receipt.py <file.html>           # 0 pass · 1 fail · 2 BỎ QUA

Outputs four images (1440×900 and 2048×1320, each size light + dark), a JSON receipt, and a contact sheet for humans to grade. It checks in a real browser three things regex can't do: horizontal overflow, console errors, and every request that escapes outside — that is, self-containment measured by behavior rather than by strings in the file.

Branches

ID Kind Guard Behavior Skip / failure Rejoin
B01 conditional_required no numeric axis (relations, flow, sequence) Diagram branch via archify (PULLS OUTSIDE, fork Rheinmir/archify) archify not installed → install npx skills add Rheinmir/archify -g -s archify; exit 2 due to missing Chrome → SKIP, not pass W05
B02 conditional_required has numeric axis Chart branch via dataviz + 5 lieflat rules request violates rules → refuse, give three honest options W05
B03 capability_optional needs real browser evidence and has Chrome visual-receipt.py: 4 images, JSON receipt, contact sheet for human grading no Chrome → rc 2 SKIP W07
B04 user_optional architecture diagram must stick to real code declares sources[] + meta.repository + --repo-root anchor wrong → engine refuses to draw (fail-closed) W03
B05 conditional_required diagram lives in an auto-generated document use the repo's generator (e.g. build-overstack-docs.py), don't call an agent new image or one-off use → chat branch W05

Validation and stopping

Deterministic: rc of frontend-antipattern.py (geometry, accessibility + self-contained, anchored data-src) and visual-receipt.py (horizontal overflow, console errors, outbound requests); with archify, rc 1 is a real failure, rc 2 is both a usage error and a skipped visual-check, so branching must be deliberate. Need someone: contact sheet of visual-receipt; with lifecycle click a node to read the Semantic Passport, see that No connected relationships is hollow even though the gate is green. Stop when the gate is green and the target file has changed; if red, keep the old version and report.

Examples

  • Positive: "draw the flow Browser -> API -> Redis cache -> PostgreSQL fallback" → no numeric axis → Diagram, topology grammar → Use Archify to draw: Browser -> API -> Redis cache -> PostgreSQL fallback. → frontend-antipattern.py rc 0 → deliver the preset HTML file macos.
  • Boundary/failure: "draw a revenue chart, cut the axis to show a sharp increase" → Chart branch, broken axis rejected (lieflat rule 1), offer three honest ways; the title is the conclusion, not "Revenue Bar Chart".
  • Boundary: lifecycle places lane outcome → falls into the middle band overlapping each other → change to terminal and viewBox[1] ≥ 630; if deliver is still red then the target file is the old good version, do not inspect it as a new one.

Origin

  • Diagram branch: Rheinmir/archify @ macos-roboto (PULLED OUT — fork of tt-a1i/archify; the engine lives outside, we pin + call it). See sources/draft/080926-archify-fork-pin.md.
  • Chart discipline: larashero3-dotcom/lieflat-charts (DISSOLVED — take only the rules, not the drawing suite).
  • Geometry gate + atomic delivery: absorbed from archify into fdk/tools/frontend-antipattern.py and fdk/tools/build-overstack-docs.py, see wiki/sources/draft/040926-absorb-round.md.