Generate deterministic publication-quality architecture, workflow, and pipeline diagrams from structured JSON (FigureSpec) into editable SVG. Use when user says \"架构图\", \"workflow 图\", \"pipeline 图\", \"确定性矢量图\", \"figure spec\", \"draw architecture\", or needs precise, editable, publication-ready vector diagrams. Preferred over AI illustration for formal architecture/workflow figures.
Installs into .claude/skills of the current project.
Are you the author of Fig Spec?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/fourteen1416-fig-spec)
---
name: fig-spec
description: "Generate deterministic publication-quality architecture, workflow, and pipeline diagrams from structured JSON (FigureSpec) into editable SVG. Use when user says \"架构图\", \"workflow 图\", \"pipeline 图\", \"确定性矢量图\", \"figure spec\", \"draw architecture\", or needs precise, editable, publication-ready vector diagrams. Preferred over AI illustration for formal architecture/workflow figures."
argument-hint: "[description-of-diagram]"
allowed-tools: Bash(*), Read, Write, Edit
---
# FigureSpec: Deterministic JSON → SVG Figure Generation
Generate publication-quality **architecture diagrams**, **workflow pipelines**, **audit cascades**, and **system topology** figures as editable SVG vector graphics using a deterministic JSON → SVG renderer.
## 执行与产出
使用当前执行会话完成本步工作;产物路径按当前步骤合同。程序采集真实操作、输入输出、版本与运行清单,模型只负责实质成果和领域质量。
建议额外记录:FigureSpec JSON 输入哈希与渲染脚本版本。图表溯源门禁 figure_provenance 要求图有来源证据。
## When to Use This Skill
**Use `fig-spec`** for:
- System architecture diagrams (layered, hub-and-spoke, multi-plane)
- Workflow / pipeline figures
- Audit cascade / flow-control diagrams
- Any structured diagram where node positions, connections, and groupings are semantically important
- Figures that need to be edited/tweaked later (SVG is plain text)
- Figures where determinism matters (same spec → same SVG)
**Do NOT use for:**
- Data plots (bar/line/scatter) — use `/paper-figure`
- Natural/qualitative illustrations — use `/paper-illustration`
- Quick state-machine / flowchart — use `/mermaid-diagram` (lighter syntax)
## Core Properties
- **Deterministic**: identical FigureSpec JSON always produces identical SVG output (for a fixed renderer version + fonts)
- **Editable**: SVG output is plain-text, can be post-edited by hand or programmatically
- **Validated**: renderer enforces schema, rejects malformed specs with clear error messages
- **Shape-aware**: edge clipping works correctly for rect/rounded/circle/ellipse/diamond
- **CJK support**: multi-line labels with proper Chinese character width estimation
- **No external API**: runs fully local, no network, no API keys
## Tool Location
The canonical renderer lives inside this skill:
`skills/fig-spec/scripts/figure_renderer.py`. Resolve it with the
two-step chain below — first an explicit override, then the in-repo
skill directory (the driver agent already knows the repo root, so no
install layout is involved):
```bash
# 1) explicit override wins (set by the driver/workspace when needed)
FIGURE_RENDERER="${FIGURE_RENDERER:-}"
# 2) in-repo skill directory, from either checkout root layout
if [ -z "$FIGURE_RENDERER" ]; then
ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
for c in "$ROOT/academic-toolkit/skills/fig-spec/scripts/figure_renderer.py" "$ROOT/skills/fig-spec/scripts/figure_renderer.py"; do
[ -f "$c" ] && { FIGURE_RENDERER="$c"; break; }
done
fi
[ -f "$FIGURE_RENDERER" ] || {
echo "ERROR: figure_renderer.py not found under skills/fig-spec/scripts/ (override: \$FIGURE_RENDERER)." >&2
echo " fig-spec cannot produce SVG output without the renderer; check the repo checkout." >&2
exit 1
}
```
Invoke:
```bash
python3 "$FIGURE_RENDERER" render <spec.json> --output <out.svg>
python3 "$FIGURE_RENDERER" validate <spec.json>
python3 "$FIGURE_RENDERER" schema
```
## Workflow
### Step 1: Understand the Diagram Goal
From `$ARGUMENTS` (description or path to `PAPER_PLAN.md` / `NARRATIVE_REPORT.md`), identify:
- **Purpose**: architecture, workflow, pipeline, audit cascade, topology?
- **Main entities**: what are the boxes?
- **Relationships**: how do they connect? (uses, produces, calls, verifies, chains)
- **Grouping**: do entities cluster into named regions?
- **Hierarchy vs network**: stacked layers, left-to-right flow, or central hub?
### Step 2: Draft the FigureSpec JSON
Canvas sizing guide:
- Single-column figure: ~500×350 px
- Two-column (full-width): ~900×500 px
- Tall topology: ~700×700 px
Start from a template based on the diagram type:
**Architecture (stacked rows)**:
```json
{
"canvas": {"width": 900, "height": 520},
"nodes": [
{"id": "layer1_label", "label": "Layer 1", "x": 450, "y": 60, ...},
{"id": "node_a", "label": "A", "x": 180, "y": 120, ...},
{"id": "node_b", "label": "B", "x": 350, "y": 120, ...}
],
"edges": [...],
"groups": [
{"label": "Layer 1", "node_ids": ["node_a", "node_b"], "fill": "#F0F9FF", "stroke": "#BAE6FD"}
]
}
```
**Workflow (left-to-right chain)**:
```json
{
"canvas": {"width": 900, "height": 300},
"nodes": [
{"id": "step1", "label": "Step 1", "x": 100, "y": 150, "shape": "rounded"},
{"id": "step2", "label": "Step 2", "x": 280, "y": 150, "shape": "rounded"}
],
"edges": [
{"from": "step1", "to": "step2", "label": "produces"}
]
}
```
**Decision diamond**:
```json
{"id": "check", "label": "Passes?", "shape": "diamond", "x": 450, "y": 200}
```
### Step 3: Render and Validate
```bash
# Validate first ($FIGURE_RENDERER was resolved in "Tool Location" above)
python3 "$FIGURE_RENDERER" validate /tmp/spec.json
# Render to SVG
python3 "$FIGURE_RENDERER" render /tmp/spec.json --output figures/fig_arch.svg
# Convert to PDF for LaTeX inclusion
rsvg-convert -f pdf figures/fig_arch.svg -o figures/fig_arch.pdf
```
If validation fails, inspect the error (missing field, duplicate ID, overlap warning, invalid hex color) and fix the JSON.
### Step 4: Visual Review
Open the SVG/PDF and check:
- **No overlaps**: nodes don't collide with each other or group boundaries
- **Readability**: font sizes are consistent, labels aren't clipped
- **Edge clarity**: arrows hit nodes at clean angles, labels near edges are legible
- **Group alignment**: background rectangles frame their members cleanly
- **Color distinction**: categories are visually distinct in both color and grayscale
If issues found, edit the JSON spec (never the generated SVG) and re-render.
### Step 5: Iterate with Cross-Model Review (Optional, for High-Stakes Figures)
For paper architecture figures, invoke cross-model review through
whatever reviewer path the host provides (a host-side reviewer agent,
an MCP-style review tool, or `tools/reviewer_client.py`), passing:
```
reviewer call (host-neutral):
model: gpt-5.6-sol
config: {"model_reasoning_effort": "xhigh"}
prompt: |
Review this SVG figure for a technical paper (architecture / workflow diagram).
Spec file: /path/to/spec.json
Rendered: /path/to/fig.svg
Evaluate:
1. Clarity (C): can a reader understand the system from this figure alone?
2. Readability (R): font sizes, label placement, visual hierarchy
3. Semantic accuracy (S): do relationships match the described system?
Score each axis 1-10 and list specific issues to fix.
```
Iterate until all three axes ≥ 7/10. The ARIS tech report figures went through 5 rounds of this loop to reach C:7/R:7/S:8.
## Schema Quick Reference
Run `python3 "$FIGURE_RENDERER" schema` (resolve $FIGURE_RENDERER per "Tool Location" above) for the authoritative schema.
### Nodes
| Field | Required | Default | Notes |
|-------|----------|---------|-------|
| `id` | ✓ | — | Unique |
| `label` | ✓ | — | `\n` for multi-line |
| `x`, `y` | ✓ | — | Center coordinates |
| `width`, `height` | | 120, 50 | |
| `shape` | | `rounded` | `rect` / `rounded` / `circle` / `ellipse` / `diamond` |
| `fill`, `stroke` | | auto from palette | `#RRGGBB` |
| `text_color` | | `#333333` | |
| `font_size` | | 14 | Override style default |
### Edges
| Field | Default | Notes |
|-------|---------|-------|
| `from`, `to` | required | Same = self-loop |
| `label` | — | Short edge label |
| `style` | `solid` | `solid` / `dashed` / `dotted` |
| `color` | `#555555` | |
| `curve` | `false` | Curved path |
### Groups
Rectangular background regions framing a set of nodes:
```json
{"label": "Layer Name", "node_ids": ["a", "b", "c"], "fill": "#EFF6FF", "stroke": "#BFDBFE"}
```
## Design Patterns
### Pattern 1: Layered Architecture
Stack rows of related nodes, each row is a group, add inter-layer arrows with semantic labels (`uses↓`, `produces↑`, `checks↓`).
### Pattern 2: Hub-and-Spoke
Central node (e.g., Executor), peripheral nodes (skills, tools), solid arrows for primary relations, dashed for feedback.
### Pattern 3: Pipeline with Feedback
Left-to-right main flow, feedback arrows curve below with `curve: true`.
### Pattern 4: Audit Cascade
Three-stage horizontal cascade with inputs feeding in from top, outputs exiting right, each stage in its own group.
## Anti-Patterns
- **Don't use groups as hierarchy**: groups frame peer nodes, not containment
- **Don't nest groups**: renderer draws them as background rectangles; nested groups look like Russian dolls
- **Don't cross-draw long diagonals**: if an arrow crosses 3+ rows, rethink the layout
- **Don't mix font sizes for same role**: keep one size per node category
## Output Contract
- SVG file in `figures/` (vector, editable, hand-tweakable)
- Source FigureSpec JSON saved in `figures/specs/` for reproducibility
- PDF version via `rsvg-convert` for LaTeX inclusion
## Integration with Other Skills
- **`/paper-writing`** (Workflow 3): when `illustration: figurespec` (default for architecture figures), this skill handles Phase 2b
- **`/paper-figure`**: handles data plots; they complement each other (data + architecture = complete figure set)
- **`/paper-illustration`**: fallback for figures that need natural/qualitative style (method illustrations with photos, qualitative result grids)
- **`/mermaid-diagram`**: lighter alternative for simple flowcharts
## Review Tracing
After each cross-model reviewer call (any host reviewer path — see Step 5), save the trace following `references/review-tracing.md` (Policy C — forensic; never silently skip). Write the trace files directly to `<workspace>/traces/<skill>/<date>_run<NN>/` (the layout in `references/review-tracing.md`); no helper script is required. Respect the `--- trace:` parameter (default: `full`).