# How the Post-Render Artifact Checker Detects Diagonal Arrows and Legend-Crossing Routes

> Learn how the post render artifact checker detects diagonal arrows and legend crossing routes by analyzing SVG path geometries. Ensure accurate diagrams with Archify.

- Repository: [tt-a1i/archify](https://github.com/tt-a1i/archify)
- Tags: internals
- Published: 2026-07-14

---

**The post-render artifact checker validates rendered SVG diagrams by analyzing path geometries to flag diagonal arrows and detect intersections between routes and legend bounding boxes.**

The post-render artifact checker in the `tt-a1i/archify` repository ensures that generated architecture diagrams maintain strict orthogonal routing and avoid visual collisions with legend elements. After a diagram renders to HTML, the Node.js script `archify/scripts/check-render-output.mjs` parses the SVG markup and executes geometric validation checks that catch layout artifacts before they reach production.

## Where the Post-Render Artifact Checker Lives

The validation logic resides in `archify/scripts/check-render-output.mjs`. The script operates on the HTML output file, extracting the `<svg>` block and running two primary checks: `orthogonal_arrows` and `legend_clearance`. Both checks register with the internal `checks` array via `addCheck()` (lines 28‑30), and the final JSON report includes a boolean `ok` flag plus detailed failure messages (lines 62‑64).

## How Diagonal Arrow Detection Works

The checker identifies accidental diagonal arrows through geometric analysis of SVG path data.

### Collecting Arrow Elements

First, the script gathers all potential arrow candidates. The function `collectArrows()` (lines 70‑79) scans the SVG for `<path>` and `<line>` elements that represent diagram connections. For each element found, the script constructs an array of line segments stored in `lineSegments` or `pathSegments` properties.

### The Diagonal Classification Logic

An arrow qualifies as diagonal if it meets strict geometric criteria evaluated by `isTwoPointDiagonal()` (lines 100‑104). The function tests whether the arrow consists of exactly one segment whose start and end points differ in **both** the X and Y dimensions by more than a tolerance of **0.01** units. If any arrow satisfies this condition, the `orthogonal_arrows` check fails, and the script reports the offending element including its class and `d` attribute.

## How Legend-Crossing Detection Works

The checker prevents routes from intersecting with legend elements through bounding-box collision detection.

### Identifying Legend Bounding Boxes

The legend region begins at the HTML comment `<!-- Legend -->`. The function `collectLegendBoxes()` (lines 106‑126) extracts all `<rect>` and `<text>` elements from this fragment and converts them into bounding boxes with coordinates `(x1, y1, x2, y2)`. For text elements, the script approximates width using `estimatedTextWidth()` (lines 162‑166), which applies heuristic calculations to unmeasured text nodes.

### Collision Detection with Padding

With arrow segments and legend boxes collected, `collectLegendCollisions()` (lines 129‑140) performs intersection tests. The geometry validation uses `segmentIntersectsBox()` (lines 224‑233), which implements standard computational geometry algorithms including `segmentsIntersect`, `orientation`, and `onSegment` tests. Each legend box receives a 2 px padding via `padBox()` (lines 266‑274) to tolerate minor overlaps without flagging false positives. When any route segment intersects a padded legend box, the `legend_clearance` check fails, reporting the specific arrow index and the coordinates of the crossed legend element.

## Running the Validation

Execute the checker against any rendered Archify diagram:

```bash

# Generate the diagram first, then validate:

node archify/scripts/check-render-output.mjs my-diagram.html

```

When the checker detects violations, it outputs structured JSON identifying specific failures:

**Diagonal arrow violation:**

```json
{
  "ok": false,
  "file": "/path/to/my-diagram.html",
  "checks": [
    {
      "name": "orthogonal_arrows",
      "ok": false,
      "details": [
        "path 3: <path class=\"a-default\" marker-end=\"url(#arrowhead)\" d=\"M10 10 L50 30\"/>"
      ]
    }
  ]
}

```

**Legend crossing violation:**

```json
{
  "ok": false,
  "file": "/path/to/my-diagram.html",
  "checks": [
    {
      "name": "legend_clearance",
      "ok": false,
      "details": [
        "line 5 crosses legend rect@200,10"
      ]
    }
  ]
}

```

## Summary

- The post-render artifact checker lives in `archify/scripts/check-render-output.mjs` and validates SVG output after HTML generation.
- **Diagonal detection** relies on `isTwoPointDiagonal()` checking for single-segment arrows with simultaneous X and Y displacement above 0.01 tolerance.
- **Legend crossing detection** uses `collectLegendBoxes()` to build bounding boxes from the `<!-- Legend -->` comment forward, then tests intersections with `segmentIntersectsBox()` using 2 px padding.
- Failed checks return detailed JSON reports identifying specific arrow indices and crossed legend coordinates.

## Frequently Asked Questions

### What tolerance does the post-render artifact checker use for diagonal detection?

The checker uses a tolerance of **0.01** units in the `isTwoPointDiagonal()` function (lines 100‑104). An arrow only flags as diagonal if both its X and Y deltas exceed this threshold, filtering out floating-point rounding errors while catching intentional diagonal routes.

### How does the checker identify which SVG elements belong to the legend?

The script searches for the HTML comment `<!-- Legend -->` as a sentinel marker. Everything after this comment belongs to the legend fragment, which `collectLegendBoxes()` (lines 106‑126) scans for `<rect>` and `<text>` elements to build collision detection bounding boxes.

### What padding does the legend collision detection apply?

The `padBox()` function (lines 266‑274) adds **2 px** of padding to each legend bounding box before intersection tests. This tolerance prevents false positives from minor overlaps while still catching significant route crossings that would impair readability.

### Can the checker run as part of an automated CI pipeline?

Yes. The script exits with a non-zero status when `ok` is false, and outputs machine-readable JSON to stdout. You can invoke it via `node archify/scripts/check-render-output.mjs <file>` after any diagram generation step to enforce quality gates in continuous integration workflows.