Archify Validate Command Diagnostic Codes and Fixes: A Complete Guide to Automated Diagram Verification

The archify validate command runs the renderer in diagnostic-only mode to emit structured JSON diagnostics containing specific codes like clean-flow/edge-through-node and actionable supportedFixes arrays that enable automated diagram repair.

The archify validate command serves as the formal verification stage for diagram specifications, translating geometric and composition errors into machine-readable diagnostic objects. According to the tt-a1i/archify source code, this CLI tool parses low-level rendering failures and presents them as namespaced codes with explicit fix suggestions, enabling both manual correction and automated repair pipelines.

How the Validate Command Parses Environment and Flags

CLI Entry Point and Quality Flags

In archify/bin/archify.mjs, the validate sub-command initializes the rendering environment through the rendererEnv() function. This utility constructs the process environment by conditionally injecting the ARCHIFY_QUALITY_PROFILE, ARCHIFY_REPO_ROOT, and ARCHIFY_DIAGNOSTIC_FORMAT variables based on CLI flags.

// archify/bin/archify.mjs
function rendererEnv(quality, repoRoot, diagnosticJson = false) {
  return {
    ...(quality ? { ARCHIFY_QUALITY_PROFILE: quality } : {}),
    ...(repoRoot ? { ARCHIFY_REPO_ROOT: repoRoot } : {}),
    ...(diagnosticJson ? { ARCHIFY_DIAGNOSTIC_FORMAT: 'json' } : {}),
  };
}

The function accepts a diagnosticJson boolean that triggers JSON diagnostic output when the user passes the --json flag.

JSON Diagnostic Mode Activation

When validation runs, the CLI spawns the renderer binary with stdio: 'pipe' and the prepared environment. Setting ARCHIFY_DIAGNOSTIC_FORMAT: 'json' instructs the renderer to emit structured diagnostic payloads on stderr instead of generating image files.

const render = runNode([rendererPath(type), inputPath, outputPath], {
  stdio: 'pipe',
  env: rendererEnv(quality, repoRoot, true),
});

Running the Renderer in Diagnostic-Only Mode

Capturing Renderer Failures

If the renderer exits with a non-zero status, the rendererFailure() function in archify.mjs parses the stderr JSON payload. It extracts the diagnostics array only when the payload contains ok: false and a valid array of diagnostic objects.

function rendererFailure(result) {
  if (result.error) { … }
  try {
    const payload = JSON.parse((result.stderr || '').trim());
    if (payload?.ok === false && Array.isArray(payload.diagnostics)) {
      return { error: payload.error, diagnostics: payload.diagnostics };
    }
  } catch { /* fail-closed */ }
  …
}

This fail-closed approach ensures that malformed JSON does not crash the validator, while valid diagnostic arrays propagate upstream for processing.

Core Diagnostic Data Structure

The Diagnostic Object Schema

All diagnostics share a uniform shape created by the diagnostic() factory function defined at lines 49-58 of archify.mjs. The schema includes six required fields that provide complete context for automated fix engines.

function diagnostic({ code, message, subject = {}, evidence = {}, supportedFixes = [], severity = 'error' }) {
  return { code, severity, message, subject, evidence, supportedFixes };
}
  • code: A short, namespaced identifier (e.g., clean-flow/edge-through-node).
  • subject: Identifies the offending object via relationship index, edge ID, or composition check name.
  • evidence: Raw values triggering the failure, including coordinates, clearance distances, and direction vectors.
  • supportedFixes: An array of human-readable suggestions that downstream tools translate into concrete JSON edits.

Severity Levels and Subject Identification

The severity field accepts error, warning, or info values, though thevalidate command primarily emits error level diagnostics for blocking issues. The subject object varies by diagnostic type but consistently provides enough metadata to locate the problematic diagram element without parsing the message string.

Geometry-Level Diagnostics: The Clean-Flow Suite

The renderer's geometry module at archify/renderers/shared/geometry.mjs performs low-level geometric validation, emitting clean-flow namespaced codes when relationship routing violates layout constraints.

Endpoint Side Direction Errors (clean-flow/endpoint-side-direction)

When a relationship's source or target side annotation conflicts with the actual geometric direction of the rendered segment, the validator records a clean-flow/endpoint-side-direction diagnostic. The check compares the declared fromSide or toSide against the segment's axis and direction.

recordDiagnostic({
  code: 'clean-flow/endpoint-side-direction',
  severity: 'error',
  message,
  subject: relationshipSubject(...),
  evidence: { … },
  supportedFixes: [routeHint],
});

Trigger condition: The rendered segment runs opposite to the declared side annotation. Suggested fix: Adjust the fromSide/toSide properties or modify route/via coordinates to align the segment with the expected axis.

Edge Through Node Violations (clean-flow/edge-through-node)

If a relationship line crosses the bounding box of an opaque node that is not its source or target, the renderer flags clean-flow/edge-through-node. This check prevents visual ambiguity by ensuring edges do not pass through unrelated containers.

recordDiagnostic({
  code: 'clean-flow/edge-through-node',
  severity: 'error',
  message,
  subject: relationshipSubject(...),
  evidence: {
    obstacleKind,
    obstacleId: obstacle.id,
    segmentIndex: hitSegment,
    from: points[hitSegment],
    to: points[hitSegment + 1],
    clearancePx: clearance,
  },
  supportedFixes: [routeHint],
});

The evidence object includes the obstacleId, segment coordinates, and clearancePx value, providing precise data for algorithms that automatically reroute the edge around the obstacle.

Composition-Level Validation Codes

After successful rendering, archify/scripts/check-render-output.mjs executes a composition checker that validates higher-level visual rules. The checkerDiagnostics function in archify.mjs maps these checks to Archify diagnostic codes.

Artifact and Layout Diagnostics

Composition diagnostics cover layout quality rather than geometric correctness. Key codes include:

  • artifact/label-route-clearance: Labels overlap routed edges.
  • composition/desktop-readability: Diagram density exceeds 1440px viewport limits.
  • composition/micro-segment: Segment shorter than 8px.
  • composition/short-interior-segment: Interior turn shorter than 16px.
  • composition/proper-crossing / composition/ambiguous-corridor: Edge corridors intersect improperly.

Mapping Fixes to Composition Issues

The COMPOSITION_FIXES map in archify.mjs (lines 22-34) associates each composition code with specific supportedFixes arrays. For example, artifact/label_route_clearance suggests enlarging the viewBox, moving the label, or increasing clearance values.

for (const issue of checker?.composition?.issues || []) {
  if (issue.severity !== 'error') continue;
  diagnostics.push(diagnostic({
    code,
    severity,
    message: `Final artifact failed ${code}.`,
    subject: relationship ? { relationship } : { check: 'composition' },
    evidence,
    supportedFixes: COMPOSITION_FIXES[code] || [],
  }));
}

Formatting and Reporting Diagnostic Output

Human-Readable vs JSON Output Modes

The reportValidateFailure function routes diagnostics through formatDiagnostics(), which produces either structured JSON or plain text based on the --json flag. In text mode, the function concatenates codes, messages, and fix suggestions into readable lines.

function formatDiagnostics(error, diagnostics = []) {
  if (!diagnostics.length) return error;
  return [
    error,
    ...diagnostics.map(entry => {
      const fix = entry.supportedFixes?.length ? ` Fix: ${entry.supportedFixes.join('; ')}.` : '';
      return `[${entry.code}] ${entry.message}${fix}`;
    })
  ].join('\n');
}

JSON Receipt Structure

When --json is specified, the command outputs a complete receipt object:

{
  "schemaVersion": 1,
  "ok": false,
  "command": "validate",
  "stage": "render",
  "type": "architecture",
  "input": "/path/diagram.json",
  "error": "Validated snapshot failed validation",
  "diagnostics": [
    {
      "code": "clean-flow/edge-through-node",
      "severity": "error",
      "message": "[clean-flow/edge-through-node] architecture connections[0] \"checkout\" -> \"database\" crosses container \"auth\" ...",
      "subject": { "relationship": { "collection": "connections", "index": 0, "id": "checkout" } },
      "evidence": {
        "obstacleKind": "container",
        "obstacleId": "auth",
        "segmentIndex": 2,
        "from": [120, 84],
        "to": [140, 100],
        "clearancePx": 2
      },
      "supportedFixes": [
        "adjust fromSide/toSide, set route/via or channel coordinates, or move the obstacle"
      ]
    }
  ]
}

Automating Fixes with Diagnostic Receipts

Shell Script Auto-Repair Example

The JSON output enables automated repair workflows. The following bash script extracts clean-flow/edge-through-node diagnostics and applies a coordinate shift to bypass the obstacle:

#!/usr/bin/env bash
set -euo pipefail

DIAG=$(archify validate architecture diagram.json --json | jq -r '
  .diagnostics[]
  | select(.code=="clean-flow/edge-through-node")
  | .evidence
')

if [[ -n $DIAG ]]; then
  OBSTACLE_ID=$(echo "$DIAG" | jq -r .obstacleId)
  FROM=$(echo "$DIAG" | jq -r '.from | @csv')
  TO=$(echo "$DIAG" | jq -r '.to | @csv')
  jq --argjson from "[$FROM]" \
     --argjson to "[$TO]" \
     --arg obs "$OBSTACLE_ID" \
     '.connections[] |= if .from==$obs or .to==$obs then .route=[($from|.[0]+10),($from|.[1])] else . end' \
     diagram.json > diagram.fixed.json
  echo "Applied a fix → saved as diagram.fixed.json"
fi

Node.js Fix-Engine Implementation

For Node.js environments, consume the receipt programmatically:

import fs from 'fs';
import { spawnSync } from 'child_process';

const result = spawnSync('archify', ['validate', 'architecture', 'diagram.json', '--json'], {
  encoding: 'utf8'
});
const receipt = JSON.parse(result.stdout);

receipt.diagnostics
  .filter(d => d.code.startsWith('clean-flow/'))
  .forEach(d => {
    console.log(`Fix needed for ${d.subject.relationship.id}: ${d.supportedFixes[0]}`);
    // Automated fix logic: modify diagram.json based on d.evidence coordinates
  });

Summary

  • The archify validate command emits structured diagnostic objects with stable, namespaced codes rather than unstructured error strings.
  • Geometry diagnostics (clean-flow/*) identify routing violations like edges passing through unrelated nodes or segments contradicting side annotations.
  • Composition diagnostics (artifact/*, composition/*) catch layout quality issues such as label overlap or viewport density problems.
  • Each diagnostic includes a supportedFixes array containing actionable suggestions that automated tools or human authors can implement.
  • The --json flag activates machine-readable output suitable for CI/CD pipelines and automated repair scripts.
  • The test suite in archify/test/repair-receipt.test.mjs guarantees diagnostic consistency between validate and deliver commands, ensuring reliable downstream integration.

Frequently Asked Questions

What triggers the clean-flow/edge-through-node diagnostic code?

This code fires when a relationship line segment intersects the bounding box of a node that is neither its source nor target, as implemented in archify/renderers/shared/geometry.mjs lines 376-395. The diagnostic includes evidence fields for obstacleId, segmentIndex, and clearancePx to pinpoint exactly which segment crosses which obstacle.

How do I enable JSON output for the validate command?

Pass the --json flag when invoking the command. This sets the ARCHIFY_DIAGNOSTIC_FORMAT=json environment variable internally, causing the renderer to emit a structured JSON receipt on stdout containing the full diagnostics array with codes, evidence, and supported fixes.

Can Archify automatically fix diagrams, or does it only report issues?

The validate command performs diagnostic-only reporting; it does not modify source files. However, the supportedFixes array in each diagnostic object provides explicit instructions that external scripts or fix-engines can execute to automate repairs, as demonstrated in the shell and Node.js examples above.

What is the difference between validate and deliver diagnostics?

Both commands emit identical diagnostic structures, verified by the test suite at archify/test/repair-receipt.test.mjs lines 117-124. While validate runs in diagnostic-only mode without producing final artifacts, deliver performs the same checks while generating output files, ensuring consistency between pre-flight validation and production builds.

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 →