# How to Validate Generated Diagrams with self_check.py in the Diagram-Design Repository

> Validate generated diagrams using self_check.py in the diagram-design repository. This script enforces security, accessibility, and motion rules, ensuring diagram integrity with detailed error reporting.

- Repository: [Cathryn Lavery/diagram-design](https://github.com/cathrynlavery/diagram-design)
- Tags: how-to-guide
- Published: 2026-09-12

---

**The [`self_check.py`](https://github.com/cathrynlavery/diagram-design/blob/main/self_check.py) script is a zero-dependency validator that parses HTML diagram files to enforce security, accessibility, and motion-contract rules, exiting with status 0 on success or 1 with detailed error messages.**

The cathrynlavery/diagram-design repository includes a lightweight validation tool at [`skills/diagram-design/scripts/self_check.py`](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/scripts/self_check.py) that allows developers to validate generated diagrams locally before CI submission. This standalone script ensures your SVG output meets the repository's strict **accessible-SVG** and **motion-contract** standards without requiring the full linter stack.

## What self_check.py Validates

The validator uses Python's built-in `HTMLParser` to walk the document tree and enforce six distinct categories of rules. When you validate generated diagrams with [`self_check.py`](https://github.com/cathrynlavery/diagram-design/blob/main/self_check.py), it performs comprehensive checks against the same standards enforced by the production linters ([`lint-skin.py`](https://github.com/cathrynlavery/diagram-design/blob/main/lint-skin.py) and [`verify-motion.py`](https://github.com/cathrynlavery/diagram-design/blob/main/verify-motion.py)).

### Security and Safety Checks

The script blocks unsafe HTML elements and attributes that could introduce XSS vulnerabilities or external dependencies. In [`skills/diagram-design/scripts/self_check.py`](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/scripts/self_check.py) (lines 92-99), the parser disallows `<base>`, `<embed>`, `<object>`, `<iframe>`, and any attribute starting with `on` (such as `onclick`). Additionally, lines 48-65 prevent remote resource loading by blocking CSS `@import` statements, `url()` functions containing non-fragment values, `image-set()` declarations, and any remote URL that is not the approved Google Fonts stylesheet.

### SVG Accessibility Requirements

For accessibility compliance, the validator requires at least one SVG element that is not `aria-hidden` and includes specific attributes defined in lines 81-112. Your diagram must contain an SVG with `role="img"`, a `<title>` element as its first child, a non-empty `<desc>` element, and matching `aria-labelledby` IDs that use the diagram-specific prefix.

### Script Integrity Verification

Lines 14-30 enforce strict controls on JavaScript inclusion. The document may contain at most one `<script>` tag, which must carry only the canonical `data-diagram-controls` attribute. The script body must exactly match the canonical controller found in [`template-motion.html`](https://github.com/cathrynlavery/diagram-design/blob/main/template-motion.html) to prevent unauthorized code execution.

### Motion Contract Compliance

If your diagram includes motion markup (identified by `data-motion-root` or `data-motion-item` attributes), the validator checks the motion contract implementation in lines 136-188. This includes validating the animation mode (`none`, `reveal`, `step`, or `loop`), ensuring step counts fall between 1 and 8, verifying item budgets, checking semantic step continuity, confirming proper playback controls, and validating the presence of reduced-motion and print fallbacks.

## Running the Validator

### Validating a Single Diagram

Execute the script with the path to your generated HTML file:

```bash
python3 skills/diagram-design/scripts/self_check.py path/to/my-diagram.html

```

A valid file produces the output:

```

OK path/to/my-diagram.html

```

### Batch Validation Multiple Files

Process multiple diagrams simultaneously by passing glob patterns or multiple paths:

```bash
python3 skills/diagram-design/scripts/self_check.py diagrams/*.html

```

When validation fails, the script returns structured error messages:

```

FAIL diagrams/bad-diagram.html
  - <iframe> is not allowed in a diagram file
  - remote stylesheet is not the approved Google Fonts /css2 URL: https://example.com/style.css
  - svg 1 needs role=img
  - svg 1 title must be its first child

```

### Integrating with CI Pipelines

Add the validator to your continuous integration workflow to block invalid diagrams at build time. The script returns exit code 1 on failure, causing the job to fail automatically:

```yaml
- name: Validate generated diagrams
  run: |
    python3 skills/diagram-design/scripts/self_check.py $(git ls-files '*/generated/*.html')

```

## Anatomy of a Valid Diagram

The following HTML structure satisfies all [`self_check.py`](https://github.com/cathrynlavery/diagram-design/blob/main/self_check.py) requirements:

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Demo</title>
  <link href="https://fonts.googleapis.com/css2?family=Geist&display=swap" rel="stylesheet">
</head>
<body>
  <svg role="img" aria-labelledby="demo-title demo-desc">
    <title id="demo-title">Demo Diagram</title>
    <desc id="demo-desc">A simple accessible diagram.</desc>
    <rect width="100" height="100" fill="#f5f5f5"/>
  </svg>
  <script data-diagram-controls>
    (() => { /* controller body – must match template-motion.html */ })();
  </script>
</body>
</html>

```

Running [`self_check.py`](https://github.com/cathrynlavery/diagram-design/blob/main/self_check.py) on this file outputs `OK` because it contains no unsafe elements, uses only approved remote resources, implements proper SVG accessibility patterns, and includes the canonical script controller.

## Summary

- **Zero-dependency validation**: The script requires only Python's standard library, using `HTMLParser` to analyze diagram files without external packages.
- **Security enforcement**: Blocks unsafe elements like `<iframe>` and `on*` event handlers while restricting remote resources to approved Google Fonts URLs.
- **Accessibility mandates**: Requires `role="img"`, proper `<title>` and `<desc>` placement, and valid `aria-labelledby` references.
- **Motion contract validation**: Verifies animation modes, step limits, and accessibility fallbacks for diagrams with motion markup.
- **CI-ready exit codes**: Returns 0 for valid diagrams and 1 with descriptive error messages for invalid files.
- **Script integrity**: Ensures JavaScript matches the canonical controller in [`template-motion.html`](https://github.com/cathrynlavery/diagram-design/blob/main/template-motion.html) exactly.

## Frequently Asked Questions

### What exit codes does self_check.py return?

The script exits with status 0 when validation succeeds, printing `OK <filepath>`. If any check fails, it exits with status 1 and prints a `FAIL <filepath>` message followed by a bulleted list of specific violations.

### Can I use self_check.py without installing dependencies?

Yes. The validator is designed to run with zero dependencies beyond Python's standard library. It uses the built-in `html.parser.HTMLParser` class rather than external parsing libraries, making it suitable for lightweight local validation or containerized CI environments.

### How does self_check.py differ from lint-skin.py?

While [`self_check.py`](https://github.com/cathrynlavery/diagram-design/blob/main/self_check.py) located in `skills/diagram-design/scripts/` provides a fast, portable subset of validation rules, [`lint-skin.py`](https://github.com/cathrynlavery/diagram-design/blob/main/lint-skin.py) in the repository root offers comprehensive linting including additional CSS safety checks and skin validation. Use [`self_check.py`](https://github.com/cathrynlavery/diagram-design/blob/main/self_check.py) for rapid local feedback and [`lint-skin.py`](https://github.com/cathrynlavery/diagram-design/blob/main/lint-skin.py) for full repository gate checks.

### What should I do if the script check fails?

If the validator reports script integrity errors, compare your diagram's `<script>` tag content against the canonical controller in [`skills/diagram-design/assets/template-motion.html`](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/assets/template-motion.html). The script body must match exactly, and the tag must use only the `data-diagram-controls` attribute without inline event handlers or external src references.