Block Registry Structural Gate: Validating data-block-id and Parent Chain Integrity in Diagram Design

The block registry structural gate enforces five strict validation rules—non-blank unique IDs, valid parent references, present names, and acyclic hierarchies—on every HTML/SVG diagram file in the cathrynlavery/diagram-design repository.

The cathrynlavery/diagram-design repository implements a metadata side-car pattern to enable traceable block decomposition in architectural diagrams. The structural gate, located in scripts/verify-block-registry.py, ensures that data-block-id and parent chain attributes form a consistent, queryable tree structure before diagrams are committed or exported. This validation layer guarantees that downstream tooling can reliably navigate block hierarchies without encountering orphaned references or circular dependencies.

How the Structural Gate Validates Block Metadata

The validator treats every HTML or SVG file as a potential registry of blocks. During execution, it extracts elements bearing data-block-* attributes and subjects them to a five-stage validation pipeline.

The Five Validation Rules

According to the source code in scripts/verify-block-registry.py, the gate enforces the following constraints:

  1. Non-blank IDs – Every block must declare a non-empty data-block-id. Empty or whitespace-only IDs are reported as structural errors with precise line numbers.
  2. Global Uniqueness – Within a single file, a data-block-id value may appear exactly once. Duplicate IDs trigger diagnostics listing every offending line.
  3. Parent Resolution – If data-block-parent is present, its value must match an existing data-block-id within the same file. Unmatched parents are flagged as orphan references.
  4. Name Presence – Each block must carry a non-blank data-block-name attribute to ensure human-readable identification.
  5. Acyclic Hierarchy – The parent chain must form a directed acyclic graph. The validator traces each ancestry path; if a node repeats, it emits a cycle description such as A → B → C → A.

These checks are metadata-only and do not inspect visual geometry or connector routing, which is handled separately by scripts/verify-geometry.py.

Parsing Strategy and Data Model

The validator relies on Python’s standard-library html.parser.HTMLParser to ensure browser-equivalent parsing behavior, handling case-insensitive attributes and ignoring content inside <script> or <style> blocks.

During the parse phase, every start tag containing data-block-id is instantiated as a Block dataclass storing:

  • id: The unique identifier string
  • parent: Optional parent reference
  • name: Human-readable label
  • line: Source file line number for diagnostics

After parsing, dedicated functions—find_blank_ids(), find_duplicates(), find_orphan_parents(), find_missing_names(), and find_cycles()—scan the list of Block objects and return structured diagnostic messages. The main check() function aggregates these results, returning an empty list only when all five rules pass.

Architectural Foundation: ADR 0010

The structural gate was mandated by ADR 0010 – Block registry metadata contract, located at docs/adr/0010-block-registry-metadata-contract.md. This architectural decision record formalized the metadata side-car pattern for Traceable block decomposition, requiring that every diagram block expose stable identifiers and parent pointers to support automated audit trails.

The ADR defines the contract that verify-block-registry.py enforces, ensuring that block hierarchies remain navigable across Tree, Architecture, and other diagram types exported from the repository.

Running the Validator

Command-Line Interface

You can invoke the gate directly against specific files or entire asset directories:


# Validate a single diagram

python3 scripts/verify-block-registry.py skills/diagram-design/assets/example-x.html

# Validate all HTML/SVG assets in the skill

python3 scripts/verify-block-registry.py --all

Sample error output:


example-x.html:12: block has a blank data-block-id
example-x.html:24: duplicate data-block-id "node42" at lines 24, 37
example-x.html:31: data-block-parent "node99" on block "node7" does not match any data-block-id in this file
example-x.html:45: block "node12" has a missing or blank data-block-name
example-x.html: parent cycle: node5 -> node8 -> node5

CI Integration

Add the validator to a GitHub Actions workflow to block merges containing broken metadata:

- name: Verify block registry
  run: |
    python3 scripts/verify-block-registry.py --all

A non-zero exit code indicates validation failure, preventing the merge of diagrams with registry errors.

Programmatic Usage

Import the validation logic into other Python scripts:

from pathlib import Path
from scripts.verify_block_registry import check

path = Path('skills/diagram-design/assets/example-x.html')
issues = check(path)

if issues:
    for issue in issues:
        print(issue)
    exit(1)
else:
    print('All block metadata valid')

Export Registry Integration

When exporting diagrams with the --registry flag, the CLI relies on the structural gate to guarantee metadata integrity. Successfully validated blocks are serialized into a JSON side-car:

[
  {
    "id": "auth-service",
    "name": "Auth Service",
    "parent": "gateway",
    "attributes": {}
  },
  {
    "id": "gateway",
    "name": "API Gateway",
    "parent": null,
    "attributes": {}
  }
]

This integration ensures that consumers of the exported registry receive a verified, acyclic hierarchy that complies with the ADR 0010 contract.

Key Files and References

File Purpose
scripts/verify-block-registry.py Core validator implementing the five structural rules
scripts/test-verify-block-registry.py Test suite providing edge-case coverage and regression protection
docs/adr/0010-block-registry-metadata-contract.md Architectural Decision Record defining the metadata contract
skills/diagram-design/references/semantic-patterns.md Documentation for the Traceable block decomposition pattern (Section 8)
commands/export-diagram.md CLI reference for the --registry export flag

Summary

  • The block registry structural gate enforces five validation rules on data-block-id, data-block-parent, and data-block-name attributes in diagram HTML/SVG files.
  • Implemented in scripts/verify-block-registry.py, the validator uses html.parser.HTMLParser to extract blocks and runs checks for blank IDs, duplicates, orphan parents, missing names, and cyclic hierarchies.
  • ADR 0010 mandates this gate to support traceable block decomposition across diagram types.
  • The tool operates as a CLI utility with --all flag support, integrates into CI pipelines via exit codes, and exposes a Python API via the check() function.
  • Validated block metadata can be exported as JSON using the --registry flag, ensuring downstream consumers receive structurally sound hierarchies.

Frequently Asked Questions

What happens if two blocks share the same data-block-id?

The validator detects duplicates via find_duplicates() and emits an error message listing every line number where the duplicate ID appears. The check fails until the ID is made unique or the redundant block is removed.

Can a block have a parent from a different file?

No. The structural gate validates parent references only within the scope of a single file. The find_orphan_parents() function flags any data-block-parent value that does not match a data-block-id present in the same HTML or SVG document.

How does the validator detect circular parent chains?

The find_cycles() function performs an ancestry walk for each block, tracking visited nodes. If a node is encountered twice during the traversal, the function constructs a cycle string (e.g., A -> B -> C -> A) and reports it as a validation error, preventing infinite loops in downstream tree processors.

Is the validator required before exporting a diagram?

While the export command can run independently, using the --registry flag implicitly relies on valid metadata. The test suite in scripts/test-verify-block-registry.py ensures the gate catches errors early, and CI integration blocks merges that would break the registry contract, effectively enforcing validation prior to export.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →