# Geometric Label Placement Validation Rules and CI Enforcement in Diagram Design

> Enforce geometric label placement rules in diagram design with CI validation. Learn how scripts prevent visual clipping and integrate with GitHub Actions for robust diagram validation.

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

---

**The diagram-design repository prevents visual clipping by enforcing strict geometric constraints through [`scripts/verify-geometry.py`](https://github.com/cathrynlavery/diagram-design/blob/main/scripts/verify-geometry.py), which validates that label masks are never obscured by later-declared nodes using dimensional heuristics, containment checks with epsilon tolerance, and paint-order analysis integrated into GitHub Actions.**

The cathrynlavery/diagram-design repository maintains diagram consistency by implementing geometric label placement validation rules that ensure SVG text labels remain visible above node elements. A dedicated geometry checker analyzes every `<rect>` element in HTML diagram assets to enforce size constraints and z-order correctness. These validations are automatically enforced through continuous integration, guaranteeing that no pull request can merge while containing label clipping violations.

## Core Geometric Validation Rules

The validation logic implemented in [`scripts/verify-geometry.py`](https://github.com/cathrynlavery/diagram-design/blob/main/scripts/verify-geometry.py) applies five specific geometric constraints to classify rectangles as nodes or masks and detect paint-order violations that would hide labels in the rendered output.

### Minimum Node Dimensions

A valid node must be a `<rect>` element measuring at least **60 px × 40 px**. The script enforces these minimums through the module-level constants `NODE_MIN_W = 60.0` and `NODE_MIN_H = 40.0`, filtering out smaller rectangles from node classification.

### Mask Size Constraints

Label masks must fall within strict dimensional bounds: **20 px ≤ width ≤ 200 px** and **8 px ≤ height ≤ 14 px**. These constraints are defined by `MASK_MIN_W`, `MASK_MAX_W`, `MASK_MIN_H`, and `MASK_MAX_H`, allowing the parser to distinguish legitimate label backgrounds from other decorative rectangles.

### Containment Exceptions for Badge Chips

Masks that are fully contained within a node geometry are permitted, accommodating badge chips such as `EXT`, `EDGE`, and `ORIG`. The `contained()` function implements this check with an epsilon tolerance of **0.5 px** (`EPSILON = 0.5`), accounting for sub-pixel rounding errors in SVG coordinate data.

### Overlap Tolerance Thresholds

The checker ignores minor overlaps of **≤ 1 px** in either dimension, as these variations are indistinguishable from normal rendering artifacts. In the main validation loop, the algorithm explicitly continues to the next candidate when `dx <= 1.0 or dy <= 1.0`, filtering out insignificant geometric intersections.

### Paint-Order Violation Detection

The most critical validation detects when a mask overlaps a node declared later in the document, which would clip the mask in the final paint order. The algorithm compares element offsets using `if node.offset <= mask.offset: continue` to safely skip nodes painted earlier, flagging any subsequent overlapping node as a paint-order violation that must be resolved.

## Implementation in verify-geometry.py

The script parses HTML diagram files using a regular expression (`RECT_RE`) to extract all `<rect>` elements, then classifies each rectangle based on the dimensional heuristics above. For every mask detected, the system iterates through nodes appearing later in the document structure (higher offset values) to identify illegal overlaps.

The core overlap detection logic follows this pattern:

```python
for mask in masks:
    for node in nodes:
        if node.offset <= mask.offset:
            continue          # node painted before mask → safe

        dx, dy = overlap(mask, node)
        if dx <= 1.0 or dy <= 1.0 or contained(mask, node):
            continue          # trivial overlap or allowed containment

        findings.append(
            f"{path.name}:{mask.line}: label mask {mask} is clipped by node "
            f"{node} declared later at line {node.line} (overlap {dx:g}x{dy:g}px) "
            "- move the label onto a free segment of its connector"
        )
        break

```

## Continuous Integration Enforcement

Geometric validation is integrated into the repository’s CI pipeline via **[`.github/workflows/ci.yml`](https://github.com/cathrynlavery/diagram-design/blob/main/.github/workflows/ci.yml)**, ensuring every commit meets the geometry contract before merging into the main branch.

### Geometry Verification Step

The workflow executes the checker against all shipped diagram assets using the `--all` flag:

```yaml
- name: Verify label geometry
  if: always()
  id: geometry
  run: python scripts/verify-geometry.py --all

```

### Unit Test Validation

A complementary step validates the geometry checker itself through its dedicated test suite:

```yaml
- name: Verify label geometry checker
  if: always()
  id: geometry_tests
  run: python scripts/test-verify-geometry.py

```

These steps execute on every push and pull request across a matrix of operating systems and Python versions, reporting results in the execution summary table. Any geometry violation triggers a workflow failure, blocking the merge until the finding is resolved.

## Practical Usage Examples

Developers can run the geometry checker locally to validate diagrams before committing changes.

To check a single diagram file:

```bash
python3 scripts/verify-geometry.py skills/diagram-design/assets/example-x.html

```

To validate every shipped diagram (matching the CI behavior):

```bash
python3 scripts/verify-geometry.py --all

```

## Summary

- The `cathrynlavery/diagram-design` repository enforces geometric label placement validation rules through [`scripts/verify-geometry.py`](https://github.com/cathrynlavery/diagram-design/blob/main/scripts/verify-geometry.py) to prevent visual clipping in SVG diagrams.
- **Nodes** must measure at least **60 px × 40 px**, while **label masks** must fall between **20–200 px wide** and **8–14 px tall**.
- The `contained()` function permits masks fully inside nodes (for badges like `EXT` and `EDGE`) with a **0.5 px** epsilon tolerance.
- Overlaps of **≤ 1 px** are ignored as rendering noise, but masks overlapping later-declared nodes trigger paint-order violation errors requiring correction.
- Continuous integration automatically runs these checks via **[`.github/workflows/ci.yml`](https://github.com/cathrynlavery/diagram-design/blob/main/.github/workflows/ci.yml)**, executing both [`verify-geometry.py`](https://github.com/cathrynlavery/diagram-design/blob/main/verify-geometry.py) and [`test-verify-geometry.py`](https://github.com/cathrynlavery/diagram-design/blob/main/test-verify-geometry.py) on every pull request to block regressions.

## Frequently Asked Questions

### What happens if a label mask overlaps a node by more than 1 pixel?

The validation script records a paint-order violation finding that specifies the file path, line numbers, and exact overlap dimensions, advising the developer to move the label onto a free segment of its connector. This error causes the CI workflow to fail, preventing the merge until the geometry is corrected.

### Why are some overlapping masks allowed even when they intersect nodes?

Masks that are fully contained within a node geometry are explicitly permitted to accommodate badge chips such as `EXT`, `EDGE`, and `ORIG`. Additionally, trivial overlaps of **≤ 1 px** in either dimension are ignored as indistinguishable from normal rendering variations in the SVG engine.

### How does the validation distinguish between nodes and label masks?

The script classifies rectangles based on dimensional heuristics defined in [`scripts/verify-geometry.py`](https://github.com/cathrynlavery/diagram-design/blob/main/scripts/verify-geometry.py): elements measuring at least **60 px × 40 px** are classified as nodes, while rectangles between **20–200 px wide** and **8–14 px tall** are classified as label masks based on the `NODE_MIN_W`, `NODE_MIN_H`, and mask constant thresholds.

### Where are the geometry validation tests located?

The unit tests for the geometry checker reside in **[`scripts/test-verify-geometry.py`](https://github.com/cathrynlavery/diagram-design/blob/main/scripts/test-verify-geometry.py)**, which validates the classification logic, overlap detection, and containment algorithms. This test suite is executed in the CI pipeline on every pull request alongside the main verification script to ensure the validation logic remains correct across supported Python versions.