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()ingeometry.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 witharchify.mjsseverity 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →