How Archify Canonicalizes Inputs for the `compare` Command

Archify validates JSON snapshots against the Architecture schema, sorts facts lexicographically by ID, prunes non-schema fields, and normalizes paths to create deterministic inputs before calculating diffs.

When you run archify compare architecture <base>.json <head>.json, the tool processes raw snapshots through a strict canonicalization pipeline. This ensures that only well-formed, schema-conformant data participates in the diff calculation, guaranteeing that repeated runs on identical inputs yield reproducible artifacts and receipts.

The Five-Step Canonicalization Pipeline

The compare command in the tt-a1i/archify repository implements a deterministic, ordered workflow to transform arbitrary snapshots into a canonical representation.

Step 1: Schema Validation of Raw Inputs

Before any structural transformations occur, Archify validates each input file against the Architecture schema. This initial gate catches malformed data early, preventing invalid fields from propagating into the comparison logic. According to the test suite in archify/test/architecture-delta.test.mjs (lines 480–487), the validator rejects snapshots that violate type constraints or required field definitions before proceeding to sorting or pruning.

Step 2: Lexicographic Sorting of Facts

After validation, authored facts—including nodes, relationships, and labels—are sorted deterministically by their IDs. As implemented in archify/test/architecture-delta.test.mjs (lines 511–515), this lexicographic sort ensures that identical snapshots always produce the same internal ordering, regardless of the original file sequence. This step eliminates false positives caused by JSON key reordering.

Step 3: Pruning Non-Schema Fields

Any properties not explicitly defined in the Architecture schema are stripped from the payload. This pruning step, also covered in archify/test/architecture-delta.test.mjs (lines 480–487), canonicalizes the payload so that only the information required for semantic comparison remains. Extraneous metadata or deprecated fields cannot influence the diff calculation.

Step 4: ID and Path Normalization

IDs are normalized to a stable string form, and file-system paths undergo case-sensitivity checks. The implementation in archify/test/output-path.test.mjs (lines 78–86) demonstrates that Archify rejects comparisons when either target would alias the artifact path—for example, if the same path differs only by case. This prevents accidental overwrites and ensures cross-platform consistency.

Step 5: Pre-Flight Verification

Immediately before writing the three-state artifact (Before, Delta, After), Archify re-validates both inputs and the receipt path. As shown in archify/test/architecture-delta.test.mjs (lines 465–472), the system aborts the operation if any input has changed since the initial canonicalization, preserving the integrity of previously trusted artifacts.

Deterministic Receipt Generation

The canonicalization process culminates in a side-car JSON receipt that records the command type (compare), completeness status (complete), and the list of changes. Because inputs are already canonicalized when the receipt is generated, the output is reproducible from the same snapshot pair. The test coverage in archify/test/architecture-delta.test.mjs (lines 270–277) validates that these receipts remain stable across multiple executions.

Practical Usage Examples

Use the CLI to compare architecture snapshots with automatic canonicalization:


# Basic compare with HTML and JSON output

archify compare architecture base.json head.json diff.html --json

# Debug mode exposes validation, sorting, and pruning steps

archify compare architecture base.json head.json diff.html \
  --json --debug

For programmatic access, import the compareArchitecture function:

import { compareArchitecture } from "archify";

const base = readJson("base.json");
const head = readJson("head.json");

// Performs validation → canonical sorting → pruning internally
const receipt = compareArchitecture(base, head);
console.log(receipt.changes);   // added / removed / changed facts

Key Implementation Files

The canonicalization logic is distributed across the following source files:

  • archify/test/architecture-delta.test.mjs – Demonstrates the validation-then-canonicalization flow, fact sorting, and receipt generation.
  • archify/test/output-path.test.mjs – Tests case-only path collisions and pre-flight checks before committing artifacts.
  • archify/scripts/update-contract.mjs – Provides version-comparison utilities used by the CLI’s pre-flight logic.
  • archify/scripts/package-smoke.mjs – Invokes the compare command in smoke-tests to verify deterministic output.
  • archify/test/cli.test.mjs – Confirms that the CLI prints the correct usage string for the compare command.

Summary

  • Schema validation occurs first to reject malformed inputs before transformation.
  • Lexicographic sorting by ID ensures deterministic ordering regardless of file structure.
  • Field pruning removes non-schema properties that could introduce noise.
  • Path normalization prevents case-sensitivity collisions and cross-platform issues.
  • Pre-flight checks guarantee artifact integrity immediately before writes.
  • Reproducible receipts are generated only after full canonicalization is confirmed.

Frequently Asked Questions

What happens if a JSON input fails schema validation?

Archify rejects the comparison immediately and exits with an error. The validation step in archify/test/architecture-delta.test.mjs (lines 480–487) ensures that malformed data never reaches the sorting or diffing stages, preventing false positives.

How does Archify handle file paths that differ only by case?

The tool detects case-only collisions during the normalization phase. As tested in archify/test/output-path.test.mjs (lines 78–86), Archify aborts the operation if either input path would alias the output artifact path, protecting against accidental overwrites on case-insensitive file systems.

Can I invoke the compare logic programmatically without the CLI?

Yes. Import compareArchitecture from the archify package to run the full canonicalization pipeline—including validation, sorting, and pruning—directly within your JavaScript code. The function accepts parsed JSON objects and returns a receipt with the changes array.

Why are non-schema fields pruned during canonicalization?

Pruning ensures that only semantically relevant data influences the diff. By removing undefined or extraneous properties, Archify guarantees that two snapshots with identical schema-defined content produce identical canonical representations, regardless of irrelevant metadata differences.

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 →