visualize/ is the canonical mount. The three sibling directories (skills/visualize/, hermes/design/visualize/, pi/agent/skills/visualize/) are byte-identical mirrors regenerated by bin/sync-mounts.sh. Never edit them directly — CI will fail the build.
After editing anything under visualize/:
bin/sync-mounts.shCI runs the same script with --check and fails on drift.
The skill should help the reader understand the source, not reward the agent for making more changes. When revising its procedures, preserve these distinctions:
- Requirements versus solutions. Feedback can expose a defect or change the brief; it does not automatically justify another local adjustment. Keep that decision in SKILL.md's Design judgment, and have verb-specific refusal and routing instructions defer to it.
- Artifact scope versus shared authority. Refinement permission covers the artifact, not its project's brand profile or token source. The authority boundary belongs in Universal laws.
- Evidence versus activity. Finding counts, diff size, and clean detector output do not establish design quality. Preserve bounded completion in polish and rendered comparison evidence in Artifact Explore.
Keep procedures in the linked skill sections; this guide explains what edits must preserve. Before adding another instruction, identify the demonstrated failure and whether it comes from routing, unclear guidance, conflicting rules, or a mechanical check. Change the responsible layer rather than adding a second policy to a reference.
Validate workflow changes with an independent agent using the changed skill on
a representative artifact. Check both the failure and a nearby valid case:
clean output should not provoke invented polish work; a bounded correction
should not reopen the brief; unresolved structure should not trigger target
edits; and a missing shared token should not authorize a design-system change.
Keep test artifacts and screenshots under temp/. Inspect the actions and
rendered evidence, not just the agent's explanation. Re-test after fixes;
mirror and syntax checks do not establish behavioral correctness.
Drop a new directory under visualize/templates/<slug>/ with one file: template.md. Required frontmatter is name and description; shell is optional and must resolve to visualize/shells/<slug>/README.md. Keep the body focused on Use when, Do not use when, Structure, Creation guidance, Hierarchy contract, Mobile contract, and concrete failure modes. Do not add live template HTML or template-skill.md.
If the template needs shared creation guidance, mention pattern recipe slugs in body prose. Pattern recipes are not automatic dependencies and must not appear in template frontmatter.
Before opening a PR that changes templates, run:
node dev-scripts/inventory-template-composition.mjs --strict
dev-scripts/build-template-previews.sh --matrix dev-scripts/template-preview-matrix.json
find temp/template-previews -name '*.html' -print0 | xargs -0 node visualize/scripts/detect.mjs --strictGenerated fixture previews live under temp/template-previews/ and are intentionally uncommitted.
Drop a new directory under visualize/design-systems/<slug>/ with DESIGN.md (Google Stitch's canonical format — YAML frontmatter carrying design tokens + a six-section markdown body: Overview / Colors / Typography / Elevation / Components / Do's and Don'ts) and tokens.css (sidecar with CSS custom properties for the :root + .dark blocks). The worked exemplar is visualize/design-systems/clean/DESIGN.md — match its overall shape (YAML structure, evocative subtitles, Named Rules pattern) and adapt the content for the new register.
Then add <slug> to the DESIGN_SYSTEMS array in dev-scripts/build-previews.sh (alphabetical) and regenerate the previews:
dev-scripts/build-previews.shCommit the generated preview.html + preview-dark.html alongside DESIGN.md + tokens.css. CI runs build-previews.sh --check and fails the build if the committed previews drift from regenerated output.
A package may also include a short README.md linking its design guidance, tokens, and previews, with an example of theme usage; see Editorial. Keep system-specific identity and adaptation rules in DESIGN.md, and application/override procedure in SKILL.md's Artifact themes section. Do not duplicate the shared workflow across package READMEs.
A design system can ship its own preview-template.html that overrides the generic preview-kit/template.html shell. Most design systems carry one so the preview can show their signature moves; systems without an override fall back to the preview-kit shell with only their tokens applied.
Drop preview-template.html in visualize/design-systems/<slug>/. The file must carry four placeholders verbatim: __ROOT_ATTR__ on the <html> tag, __DESIGN_SYSTEM_NAME__ wherever the slug should appear, and /* __TOKENS_PLACEHOLDER__ */ + the legacy marker /* __COMPONENTS_PLACEHOLDER__ */ each inside a <style> block on a whitespace-only line. The latter now injects preview-only fixture styles from preview-kit/fixture-styles/. dev-scripts/build-previews.sh auto-detects the override. Per-system templates don't inherit preview-kit/template.html, so declare any required Google Fonts inside the per-system <head>.
If the brand's synthesised dark mode reads wrong (low contrast or wrong-temperature surfaces), hand-edit the [data-theme="dark"] block in tokens.css to the brand's actual dark surface. See visualize/design-systems/AUTHORING.md for pattern references, the dark-mode strategy decision table, and the detect-clean checklist.
After editing:
bash dev-scripts/build-previews.sh
node visualize/scripts/detect.mjs --strict visualize/design-systems/<slug>/preview.html
bash bin/sync-mounts.shvisualize/preview-kit/ carries the canonical token-surface preview page. Each design system gets two generated files at design-systems/<slug>/preview.html (light) and preview-dark.html (dark).
Do not hand-edit the generated previews. When you change preview-kit/template.html, fixture styles under preview-kit/fixture-styles/, or a design system's tokens.css, regenerate via dev-scripts/build-previews.sh. See visualize/preview-kit/README.md for the placeholder contract and extension notes.
For targeted fixture previews, use dev-scripts/build-template-previews.sh. It renders fixture files from visualize/fixtures/manifest.json against any design-system tokens.css and writes standalone HTML to temp/template-previews/:
dev-scripts/build-template-previews.sh --fixture patterns/table.html --design-system swiss --mode light
dev-scripts/build-template-previews.sh --manifest --design-system clean
dev-scripts/build-template-previews.sh --matrix dev-scripts/template-preview-matrix.jsonThe README template collage is generated from the same composed previews:
dev-scripts/build-templates-showcase.sh --screenshotFixture HTML and generated fixture previews must pass the deterministic detector:
node visualize/scripts/detect.mjs --strict path/to/artifact.htmlRules across 6 categories — all mechanical patterns regex or node-html-parser can identify reliably, plus WCAG contrast computed via the vendored culori library. Run node visualize/scripts/detect.mjs --list-rules for the authoritative current set; the categories below survive rule-set churn:
- fossil — lorem-ipsum, citation artifacts (turn0search0 /
<!-- claude:/ 【N†source】 / ASSISTANT:), AI-attribution disclaimers ("Generated by Claude / with AI assistance") - slop — gradient text, dark glow (text-shadow with high blur + chroma), glassmorphism (backdrop-filter + translucent), emoji headings, monotonous spacing, bounce easing, side-tab, system-default fonts (when brand-aware)
- a11y — missing alt (including lazy alts like
alt="image"/alt="DSC_0042"), missing/empty lang, empty links, WCAG-AA contrast, heading structure (missing h1, multiple h1, skipped levels) - meta — missing title, missing favicon, missing OG / Twitter card, external script outside the library-policy allowlist
- perf — layout-thrash (transition on width/height/top/left, plus
transition: all), img without width/height (CLS risk) - diagram — semantic figure shape, node/edge/group integrity, delivered connector geometry, and unrendered diagram source
CI runs node detect.mjs --strict <file> against fixture HTML and generated fixture previews; any error-severity finding fails the build.
Rules deliberately NOT in detect.mjs — vocab-unbounded fossils (mock identity beyond the obvious / slop openers / sycophant footers / imperative-tricolon), brand-and-register-dependent slop (ai-color-palette / icon-tile-stack / center-everything / uppercase-body), and structural-pattern slop the detector can't distinguish from legitimate design (triple-feature-card / trust-signal slop / scroll-jacking / responsive overflow). Those live in the /visualize:review LLM-judge prompt in SKILL.md § "Review verb procedure" — the agent reads them when reviewing an artifact and applies judgment the detector can't.
The split is deliberate: mechanical patterns get detector rules (cheap, deterministic, CI-enforced); judgment-shaped patterns get prompt instructions (require register awareness, brand context, semantic understanding).
- Output: human-readable default;
--jsonfor NDJSON. --strict— exit 2 on any error finding.--skip slop/emoji-heading,a11y/missing-alt— comma-separated rule IDs to skip.--config .visualize-detect.json— config file (severity overrides + skip list).--brand DESIGN.md— explicit brand profile path (auto-loaded from any ancestor of the artifact otherwise).
import { detect } from './visualize/scripts/detect.mjs';
const findings = await detect({ path: './artifact.html', skip: ['slop/emoji-heading'], brandProfile: { fonts: ['sohne'] } });detect.mjs imports two libraries from visualize/scripts/vendor/: node-html-parser (real DOM walking) and culori (WCAG contrast). Both bundled inline (no npm install required after npx skills add display-dev/visualize). See visualize/scripts/vendor/README.md for re-bundle instructions when upstream releases.
Every template the skill emits is meant to be self-contained HTML — inlined CSS, no build step, no asset pipeline. Third-party libraries are the carve-out, and the policy is tight:
CDN allowlist (CI-enforced):
cdn.jsdelivr.net/npm/chart.js@<version>— for Dashboard charts
Forbidden:
- Any
<script src>reference outside the allowlist above. Adding a library requires updatingdev-scripts/check-library-policy.mjsAND the policy appendix in the spec in the same change. CI runsnode dev-scripts/check-library-policy.mjs --quietand fails the build on violation. - ECharts (too large; Chart.js covers current chart needs).
- jQuery / Lodash / utility libraries (templates don't need them; the agent writes the JS each template ships inline).
Syntax highlighting: templates that show code (tutorial, runbook, diff-review, slide-deck) use the agent-hand-classed + CSS tokens approach — no library. The agent adds <span class="kw"> / .str / .cmt etc. classes; --syntax-* CSS tokens style them per design system. This is brand-aware and zero-maintenance. If a future template's code volumes outgrow hand-classing, vendor a highlight.js subset (~30KB) inline.
Mermaid is an authoring tool, not a delivery dependency. Render Mermaid locally, normalize the result to the semantic inline-SVG contract in reference/diagram.md, and remove Mermaid source, runtime scripts, and network dependencies from the delivered artifact.
SKILL_VERSION in visualize/scripts/_common.sh requires a manual bump. Edit it in lockstep with every git tag so the client_source analytics attribution stays accurate — the value travels on X-Client-Source: visualize-skill@<version> on every request the skill makes.
For local testing without editing the file, set SKILL_VERSION_OVERRIDE in your environment.