This rule used to be markdown-only and was silently ignored, producing 12 rejected diagrams in one session (incident 2026-04-30, see ISA MEMORY/WORK/20260430-180000_art-skill-freeform-enforcement). It now lives in code.
Two layers enforce it:
Generate.ts itself refuses to run unless you pass --workflow=<name> (or the explicit --freeform-confirmed opt-out). It exits non-zero with the workflow lookup table.
ArtWorkflowGuard.hook.ts (PreToolUse Bash) blocks any Bash command containing Art/Tools/Generate.ts without --workflow= or --freeform-confirmed, with exit code 2 and the same lookup table.
The flow that works: read the matching workflow file → follow its prompt template → invoke Generate.ts with --workflow=<that-workflow-name> plus your model/prompt/size flags. The --workflow=<name> flag is your explicit assertion "I read the workflow and followed it."
The flow that's blocked: composing a freeform prompt and shipping it directly to Generate.ts. Both layers above will refuse.
Most Common Failure Mode (don't repeat it)
Reading the workflow's caps-warning, mentally noting "do the workflow," then composing a Bash command with your own prompt anyway because it feels faster. Stop. The workflow templates encode the technique, palette, composition rules, and validation gate the bare model fails to honor. Skipping them produced — verbatim — "absolute fucking ass" diagrams. Read the workflow file FIRST. Compose the prompt FROM the template. Pass --workflow=<name> so the gate can see you did it.
Workflow → command (copy-paste)
bun ~/.claude/skills/Art/Tools/Generate.ts \
--workflow=<WorkflowName> \
--model nano-banana-pro \
--prompt "..." \
--size 2K \
--aspect-ratio 16:9 \
--output ~/Downloads/<filename>.png
<WorkflowName> MUST match a file under Workflows/ (without .md):
Routing rules — pick a workflow FIRST, before writing any prompt:
| Request shape |
Required workflow |
| Blog header / editorial essay illustration |
Workflows/Essay.md — Steps 1–8 in order, no skipping |
| Mermaid diagram |
Workflows/Mermaid.md |
| Technical / architecture diagram |
Workflows/TechnicalDiagrams.md |
| Framework / 2x2 / matrix |
Workflows/Frameworks.md |
| D3 dashboard / chart |
Workflows/D3Dashboards.md |
| Taxonomy / hierarchy |
Workflows/Taxonomies.md |
| Timeline |
Workflows/Timelines.md |
| Comparison |
Workflows/Comparisons.md |
| Stat card |
Workflows/Stats.md |
| Aphorism / quote card |
Workflows/Aphorisms.md |
| Comic panel |
Workflows/Comics.md |
| YouTube thumbnail |
Workflows/AdHocYouTubeThumbnail.md or Workflows/YouTubeThumbnailChecklist.md |
| PAI pack icon |
Workflows/CreatePAIPackIcon.md |
| brand-logo wallpaper |
Workflows/LogoWallpaper.md |
| Recipe card |
Workflows/RecipeCards.md |
| Map / conceptual map |
Workflows/Maps.md |
| Annotated screenshot |
Workflows/AnnotatedScreenshots.md |
| Background removal only |
Workflows/RemoveBackground.md |
| Embossed logo wallpaper |
Workflows/EmbossedLogoWallpaper.md |
| Generic visualization (none of the above fit) |
Workflows/Visualize.md |
The ONLY exception: the user explicitly says "freeform" / "skip the workflow" / "just run Generate.ts directly with this prompt: ...". In that case, pass --freeform-confirmed to Generate.ts (which logs the explicit opt-out to stderr for audit). Without that explicit instruction from the user, ALWAYS pick the matching workflow and pass --workflow=<name> — both Generate.ts and ArtWorkflowGuard.hook.ts will refuse the call otherwise.
If no workflow matches the request, stop and surface to the user before generating — propose either (a) the closest existing workflow, (b) using Visualize.md as the generic catch-all, or (c) creating a new workflow first via the CreateSkill skill. Do not improvise.