How Archify Composition Checks Work: Label Clearance and Relationship Crossing Rules Explained

Archify composition checks are geometric validations that run after SVG rendering to enforce spacing rules (minimum 4px clearance) and prevent unrelated relationships from crossing. These checks operate purely on coordinate data, independent of the source model, ensuring diagrams remain readable and semantically correct.

The Archify rendering engine doesn't just draw diagrams—it validates them. After generating the final SVG, the runCompositionChecks() function in geometry.mjs inspects every spatial relationship between elements. This article explains how label-route clearance and proper crossing detection work, based on the actual implementation in the tt-a1i/archify repository.

What Are Archify Composition Checks?

Composition checks are pure-geometry rules that validate spatial relationships after rendering completes. Unlike model-level validations, these operate on the final coordinate data—points, rects, and segments—produced by the renderer.

Archify implements five composition checks total, with two covered here:

Check Code Purpose
Proper crossing composition/proper-crossing Prevents unrelated relationships from intersecting
Label-route clearance composition/label-route-clearance Enforces minimum distance between labels and foreign routes
Ambiguous corridor composition/ambiguous-corridor Maintains 4px separation for parallel merged routes
Container-border run composition/container-border-run Limits how long routes hug frame borders
Micro-segment composition/micro-segment Enforces minimum visible segment lengths

The label clearance and relationship crossing checks form the core visual integrity rules for professional-quality diagrams.

How Label-Route Clearance Detection Works

The label-route clearance check ensures label bounding boxes never sit too close to relationship lines they don't belong to. The implementation follows four precise steps:

1. Extract Label Rectangles

Every label node converts to an axis-aligned rectangle via hit.rect. The dimensions derive directly from the rendered <text> element's x, y, width, and height attributes.

2. Measure Distance to Foreign Routes

For each relationship not associated with the label, Archify walks every polyline segment and calls segmentRectClearance() in archify/renderers/shared/geometry.mjs:

// geometry.mjs (line 46) – perpendicular distance calculation
export function segmentRectClearance(segment, rect) {
  const { start, end } = segment;
  // Compute minimal perpendicular distance from segment to rectangle
  // Returns numeric clearance, or null if segment is inside rectangle
}

This function calculates the minimal perpendicular distance from the line segment to the rectangle boundary.

3. Apply Quality Profile Thresholds

Each profile defines a clearance threshold. The showcase profile defaults to 4px, defined in archify/bin/archify.mjs at line 187:

// archify.mjs – rule configuration for showcase quality
{
  code: 'composition/label-route-clearance',
  threshold: 4,  // pixels
  severity: 'error'
}

4. Generate Actionable Issues

When clearance falls below threshold, Archify pushes a structured issue object. From geometry.mjs around line 826:

// geometry.mjs – label clearance violation reporting
if (clearance < threshold) {
  issues.push({
    code: 'composition/label-route-clearance',
    clearance,           // measured: e.g., 2
    threshold,           // required: e.g., 4
    labelRelation,       // the label's parent relationship
    otherRelation,       // the foreign relationship too close
    segmentIndex,        // which segment violated
    rect,                // label bounding box
    message: `[composition/label-route-clearance] ${diagramType} label "${hit.label?.label}" ...`
  });
}

The message specifically names the label, offending relationship, segment index, and exact distance—guiding authors to adjust labelAt, labelDx, labelDy, or labelSegment properties.

How Relationship Crossing Detection Works

The proper crossing check prevents semantically unrelated relationships from visually intersecting, which could imply false connections.

Segment Pair Intersection Testing

Archify enumerates all unrelated relationship pairs (different collectionIds) and tests every segment combination:

// geometry.mjs – proper crossing detection (around line 432)
if (segmentIntersectsSegment(aSeg, bSeg)) {
  const point = calculateIntersection(aSeg, bSeg);
  issues.push({
    code: 'composition/proper-crossing',
    point,                    // [x, y] intersection coordinate
    left: leftRelation,        // first relationship
    right: rightRelation,      // second relationship
    message: `[composition/proper-crossing] ${diagramType} ${describe(left)} crosses ${describe(right)} at [${point}]`
  });
}

The segmentIntersectsSegment() helper performs the core geometric intersection test in geometry.mjs.

Severity by Quality Profile

Profile Crossing Severity Rationale
showcase Error Professional diagrams must never have accidental crossings
standard Warning Acceptable for draft quality
minimal Warning Lenient for exploration

This mapping lives in archify/bin/archify.mjs alongside the code-to-action configuration at line 184.

Composition Check Orchestration

All checks flow through a central pipeline. The runCompositionChecks(diagram, qualityProfile) function in geometry.mjs aggregates results, which check-render-output.mjs merges into the final validation receipt (line 154):

// check-render-output.mjs – integrating composition results
const composition = runCompositionChecks(diagram, qualityProfile);
const receipt = {
  checks: [...],
  composition: {
    status: composition.issues.length ? 'fail' : 'pass',
    issues: composition.issues,
    metrics: composition.metrics
  }
};

The CLI then surfaces remediation hints based on issue codes.

CLI Validation Example

Run composition checks via the command line:

$ npx archify validate diagram.json --quality showcase --json

Example output with both violations:

{
  "checks": [...],
  "composition": {
    "status": "fail",
    "issues": [
      {
        "code": "composition/label-route-clearance",
        "clearance": 2,
        "threshold": 4,
        "message": "[composition/label-route-clearance] showcase dataflow label \"User\" is 2px from route (requires 4px)..."
      },
      {
        "code": "composition/proper-crossing",
        "point": [120, 45],
        "message": "[composition/proper-crossing] showcase dataflow relationship 'auth' crosses 'cache' at [120,45]"
      }
    ]
  }
}

Why Composition Checks Matter

  • Readability – Overlapping labels and crossing arrows create visual clutter that obscures diagram meaning
  • Correctness – A crossing often signals unintended logical relationships in the underlying model
  • Automation – Deterministic geometry enables consistent enforcement across all diagram types (dataflow, architecture, workflow)

The separation from source model validation means Archify catches rendering artifacts that model checks cannot—such as label placement algorithms producing overlaps or route bundling creating accidental intersections.

Summary

  • Archify composition checks run post-render on coordinate data, not the source model
  • Label-route clearance enforces 4px minimum distance between labels and foreign relationship routes via segmentRectClearance() in geometry.mjs
  • Proper crossing detection prevents unrelated relationships from intersecting using segmentIntersectsSegment()
  • Quality profiles control severity—showcase treats crossings as errors, other profiles as warnings
  • Issue messages include precise measurements and property names (labelAt, labelDx, etc.) for direct remediation
  • The orchestration flows through runCompositionChecks()check-render-output.mjs → CLI reporting with archify.mjs severity mappings

Frequently Asked Questions

How do I fix a label-route clearance violation in Archify?

Adjust the label positioning properties on the parent relationship. The issue message specifies which relationship and segment triggered the violation. Modify labelAt (segment index), labelDx (horizontal offset), labelDy (vertical offset), or labelSegment to increase distance from the foreign route. The showcase quality profile requires 4px minimum clearance.

Why does Archify detect crossings that don't look like intersections in my diagram?

Archify tests mathematical segment intersection, not just visual overlap. Rounded line caps, thick strokes, or anti-aliasing may make lines appear separated when their centerlines actually cross. The point coordinate in the issue message shows the exact intersection location. Increase corridorPadding or adjust route waypoints to separate the lines.

Where are composition check thresholds configured?

Quality-specific thresholds reside in archify/bin/archify.mjs (line 184–190). The showcase profile hardcodes 4px for label-route clearance. Custom profiles can override these values by passing a modified qualityProfile object to runCompositionChecks(). The geometry.mjs file contains the measurement logic but not the threshold values.

Can I disable specific composition checks?

The CLI does not support disabling individual checks directly. Create a custom quality profile with adjusted severity mappings—set composition/proper-crossing or composition/label-route-clearance to 'ignore' in your profile configuration. Pass this profile via --quality ./my-profile.json when running validations.

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 →