Skip to content
Back to skills

Declarative Visualization

ASecurity

Author a Vega-Lite / Deneb / SVG spec for a stated intent on any surface (web vega-embed, react-vega, Evidence, Observable, Power BI Deneb, Tableau extension/SVG, SVG-in-DAX). Six-step method: pick grammar → bind data → encode → wire interactivity → test null/empty → verify via render loop. Ships a surface-agnostic spec-patterns library. Mandatory security audit (no data.url, no remote loader, no SVG script) enforced by lint.py (Gate 101). Complements the visual-feedback-loop (render referee)...

  • 7 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 23, 2026
ai-agentspythongoreactexpresstestingapisecurity

Works with

  • api

Security analysis

A100/100

Pro scans all 8 files and shows the line behind each finding

Scanned September 23, 2026

npx -y skills add mcorbett51090/RavenClaude --skill declarative-visualization --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Declarative Visualization?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Declarative Visualization
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/mcorbett51090-declarative-visualization/badge)](https://www.skillsdirectory.com/skills/mcorbett51090-declarative-visualization)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: declarative-visualization
description: "Author a Vega-Lite / Deneb / SVG spec for a stated intent on any surface (web vega-embed, react-vega, Evidence, Observable, Power BI Deneb, Tableau extension/SVG, SVG-in-DAX). Six-step method: pick grammar → bind data → encode → wire interactivity → test null/empty → verify via render loop. Ships a surface-agnostic spec-patterns library. Mandatory security audit (no data.url, no remote loader, no SVG script) enforced by lint.py (Gate 101). Complements the visual-feedback-loop (render referee) and pbir-layout-engine (coordinate linter). NOT for coordinate/layout arithmetic (pbir-layout-engine) or render-loop orchestration (visual-feedback-loop)."
---

# Skill: declarative-visualization

## What this is

A **method + runnable linter** for authoring Vega-Lite, Vega, Deneb, and SVG specs
on any surface — web, Power BI, Tableau, or standalone SVG. It is the spec-authoring
layer beneath every visualization agent; usable standalone to build and validate a
chart spec without invoking an agent.

The conceptual canon (when to use which grammar, the surface→delivery map, the full
security model) lives in
[`../../knowledge/declarative-visualization.md`](../../knowledge/declarative-visualization.md).
This SKILL is the operating reference for the method and the runnable linter.

## The six-step method

1. **Pick the grammar.** Vega-Lite first (concise, portable). Escalate to full Vega
   only when a required mark or transform is absent. Use Deneb only for Power BI;
   SVG only for non-chart visuals or SVG-in-DAX.

2. **Bind data per surface.** Always use `data.name` + dummy `values` for local
   testing. Never use `data.url` in committed specs (security rule). Wire the real
   data source in the host app (JS `view.change()`, Deneb field mapping, etc.) after
   the spec passes the linter and the render check.

3. **Encode.** Map fields to channels (`x`, `y`, `color`, `size`, `opacity`,
   `tooltip`). For small-multiples: use `facet`. For overlays: use `layer`. The
   spec-patterns library ([`spec-patterns/`](spec-patterns/)) provides starter
   templates for the most common chart types.

4. **Wire interactivity** (where needed). For web: Vega-Lite `params` / `select`.
   For Deneb/Power BI: the `powerbi` cross-filter expression. For Tableau: the
   Extension API datasource hook.

5. **Test null / empty data.** Replace `data.values` with `[]` and confirm the
   chart degrades cleanly (empty state message, not a blank visual).

6. **Verify via the render loop.** Run
   [`../visual-feedback-loop/driver.py`](../visual-feedback-loop/SKILL.md) for a
   pass/fail verdict. For Power BI PBIR: also run
   [`../pbir-layout-engine/lint.py`](../pbir-layout-engine/SKILL.md) for coordinate
   facts. The render loop is the schema check — a spec that renders without error is
   schema-valid; a spec that does not render is not.

## Mandatory security audit

Before committing any spec or template, run the linter:

```
python3 plugins/ravenclaude-core/skills/declarative-visualization/lint.py <spec.json>
```

Exit 0 = clean. Exit 1 = security violation (reject the spec and fix the offending
key). Exit 2 = I/O or path error.

**The four forbidden patterns (exit 1):**

| Pattern | Why forbidden |
|---|---|
| `data.url` (string value) | Spec fetches from a remote URL at render — SSRF vector |
| `transform.lookup` with a `from.data` that has a `url` key | Same as above, via transform |
| `loader` key anywhere in the spec (custom loader override) | Redirects all relative URL resolution |
| SVG `<script>` element or `on*` attribute | Script injection |

Any PR adding or modifying a file under `spec-patterns/` routes through
`ravenclaude-core/security-reviewer` (invariant — this is load-bearing, not a
suggestion).

## Spec-patterns library

The templates under [`spec-patterns/`](spec-patterns/) are the six most common
surface-agnostic chart types. Each:

- Uses `data: {"name": "source"}` + a `values` dummy for local test.
- Is valid JSON (passes `python3 -m json.tool`).
- Passes `lint.py` with exit 0.
- Includes a `description` field stating its intent.

| Template | File | Chart type |
|---|---|---|
| Diverging bar | `diverging-bar.json` | Positive/negative bars around a zero axis |
| Dumbbell | `dumbbell.json` | Start–end comparison per category |
| Small-multiples facet | `small-multiples-facet.json` | Faceted grid of line/bar charts |
| Heatmap | `heatmap.json` | x×y grid colored by value |
| Sparkline strip | `sparkline-strip.json` | Row-per-series compact line mini-charts |
| Annotated line | `annotated-line.json` | Line + text mark at notable points |

## Proven by Gate 101

[`scripts/audit-gates.sh`](../../../../scripts/audit-gates.sh) Gate 101 + the
fixtures under
[`tests/fixtures/declarative-viz/`](../../../../tests/fixtures/declarative-viz/)
are the bidirectional floor: a mutant template with `data.url` must fail (exit 1),
and the clean templates must pass (exit 0). Both halves are asserted.

## Output contract

When authoring a spec for a user, emit:

1. The spec JSON (in a fenced ` ```json ` block).
2. The `lint.py` verdict (`exit 0` or the violation that was fixed).
3. The render loop result if a browser tool was available.
4. The null/empty state confirmation.

Use the Structured Output Protocol block per
[`../structured-output/SKILL.md`](../structured-output/SKILL.md) when handing off
to another agent.

Files in this skill

  • SKILL.md5.3 KB
  • lint.py18.1 KB
  • spec-patterns/annotated-line.json1.9 KB
  • spec-patterns/diverging-bar.json1.1 KB
  • spec-patterns/dumbbell.json1.6 KB
  • spec-patterns/heatmap.json1.7 KB
  • spec-patterns/small-multiples-facet.json1.6 KB
  • spec-patterns/sparkline-strip.json1.6 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…