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:
- 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. - Global Uniqueness – Within a single file, a
data-block-idvalue may appear exactly once. Duplicate IDs trigger diagnostics listing every offending line. - Parent Resolution – If
data-block-parentis present, its value must match an existingdata-block-idwithin the same file. Unmatched parents are flagged as orphan references. - Name Presence – Each block must carry a non-blank
data-block-nameattribute to ensure human-readable identification. - 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 stringparent: Optional parent referencename: Human-readable labelline: 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, anddata-block-nameattributes in diagram HTML/SVG files. - Implemented in
scripts/verify-block-registry.py, the validator useshtml.parser.HTMLParserto 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
--allflag support, integrates into CI pipelines via exit codes, and exposes a Python API via thecheck()function. - Validated block metadata can be exported as JSON using the
--registryflag, 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →