# How the Archify Compare Command Generates Its Machine Receipt

> Learn how the Archify compare command creates its machine receipt. It validates snapshots, computes deltas, escapes JSON, and embeds it in HTML.

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

---

**The `archify compare` command generates a deterministic machine receipt by validating two architecture snapshots, computing their delta through the `compareArchitecture()` function, serializing the result with HTML-safe JSON escaping, and embedding it as a `<script>` tag in the generated HTML artifact.**

The machine receipt is the cryptographic backbone of Archify's **Architecture Delta** feature. This JSON document proves that a comparison between two architecture snapshots was performed correctly, capturing exactly what changed and how the comparison was verified. Understanding how this receipt is built helps developers integrate Archify into CI/CD pipelines, automate architectural governance, and build trust in automated architecture reviews.

## How the Receipt Generation Works

The receipt creation follows a strict three-stage pipeline implemented across `archify/delta/architecture-delta.mjs` and `archify/bin/archify.mjs`. Each stage is deterministic, versioned, and designed for both human inspection and machine parsing.

### Stage 1: Building the Receipt with `compareArchitecture()`

The core logic resides in `archify/delta/architecture-delta.mjs` at **lines 26-33**. The `compareArchitecture()` function takes three parameters:

```javascript
export function compareArchitecture(base, head, evidence = {}) {
  // Validation and indexing logic
  // Delta computation
  // Receipt assembly
}

```

**Input validation** starts with `requireComparableShape()` to ensure both snapshots follow the expected schema. Then `stableIndex()` and `boundaryIndex()` create fast lookup structures for components, connections, and boundaries.

**Proof level determination** is critical for trust. The function checks:

```javascript
const proofLevel = (baseRepository && headRepository && evidence.baseVerified && evidence.headVerified &&
                   /^[a-f0-9]{40}$/.test(baseRepository.revision) && /^[a-f0-9]{40}$/.test(headRepository.revision))
                  ? 'revision-pinned' : 'authored';

```

- **`'revision-pinned'`** — Both snapshots have verified 40-character SHA-1 revisions and explicit verification flags
- **`'authored'`** — Default level when revision verification is incomplete

**Entity comparison** proceeds through `compareEntities()` for each type:

| Entity | Fields Compared | Identity Key |
|--------|-----------------|--------------|
| Components | `COMPONENT_FIELDS` | `components[].id` |
| Connections | `CONNECTION_FIELDS` | `connections[].id` (required) |
| Boundaries | `BOUNDARY_FIELDS` | `boundaries[].kind + boundaries[].label` (derived) |

The final receipt object contains:

```javascript
{
  schemaVersion: 1,
  ok: true,
  command: 'compare',
  type: 'architecture',
  comparatorVersion: COMPARATOR_VERSION,
  canonicalVersion: CANONICAL_VERSION,
  completeness: 'complete',
  proofLevel,           // 'revision-pinned' or 'authored'
  base: { title, rawSha256?, revision? },
  head: { title, rawSha256?, revision? },
  summary: { /* counts of added/changed/removed/moved */ },
  changes: { components, connections, boundaries },
  identity: { /* how to address each element */ },
  view: { visualPreset },
  limitations: [ /* known constraints */ ]
}

```

### Stage 2: Safe JSON Serialization

Before embedding, the receipt must not break HTML parsing. The `safeJson()` helper at **lines 24-25** of `architecture-delta.mjs` performs character escaping:

```javascript
const safeJson = (value) =>
  JSON.stringify(value, null, 2)
          .replaceAll('<', '\\u003c')
          .replaceAll('>', '\\u003e')
          .replaceAll('&', '\\u0026');

```

This transforms dangerous characters into Unicode escapes:

- `<` becomes `\u003c`
- `>` becomes `\u003e`
- `&` becomes `\u0026`

The result can safely reside inside a `<script>` tag without risking HTML injection or parsing errors.

### Stage 3: CLI Embedding and File Writing

The CLI in `archify/bin/archify.mjs` orchestrates the final output at **lines 250-267**:

```javascript
// Generate the receipt object
const receipt = compareArchitecture(base, head, { baseVerified, headVerified });

// Determine output paths
const receiptPath = options.receipt || compareReceiptPath(outputPath);

// Render HTML with embedded receipt
await writeFile(outputPath, renderArchitectureDiff({
  // ... diagram rendering ...
  receiptScript: `<script id="archify-compare-receipt" type="application/json">${safeJson(receipt)}</script>`
}));

// Write standalone receipt.json when --receipt flag is used
if (options.receipt) await writeFile(receiptPath, JSON.stringify(receipt, null, 2));

```

**Receipt path resolution** at **lines 295-306** (`compareReceiptPath`) ensures the standalone file lands adjacent to the HTML artifact by default.

## Running `archify compare` and Inspecting the Receipt

Generate a comparison with embedded receipt:

```bash
node archify/bin/archify.mjs compare architecture \
  examples/checkout-platform-delta/base.json \
  examples/checkout-platform-delta/head.json \
  delta.html --receipt delta-receipt.json

```

Inspect the embedded receipt in the HTML:

```bash
grep -A5 'archify-compare-receipt' delta.html | head -20

```

Typical output structure:

```json
{
  "schemaVersion": 1,
  "ok": true,
  "command": "compare",
  "type": "architecture",
  "comparatorVersion": "2.13.0",
  "proofLevel": "revision-pinned",
  "base": {
    "title": "Checkout Platform v2.1",
    "rawSha256": "a3f7c9...",
    "revision": "8a4b2c6d9e1f3a5b7c9d0e2f4a6b8c0d1e3f5a7b9"
  },
  "head": {
    "title": "Checkout Platform v2.2",
    "rawSha256": "b8e2d4...",
    "revision": "9c5d3e7f1a3b5c7d9e1f3a5b7c9d1e3f5a7b9c0d2"
  },
  "summary": {
    "components": { "added": 2, "removed": 1, "changed": 3, "moved": 0 },
    "connections": { "added": 1, "removed": 0, "changed": 2, "rerouted": 1 },
    "boundaries": { "added": 0, "changed": 0, "removed": 0 }
  }
}

```

## How the Archify Viewer Consumes the Receipt

When the generated HTML opens in the Archify viewer, it locates the script element by ID:

```javascript
const script = document.getElementById('archify-compare-receipt');
const receipt = JSON.parse(script.textContent);

```

The viewer uses this data to:

- Render the delta diagram with added/removed/changed styling
- Display the provenance banner (revision SHAs, verification status)
- Enable filtering by change type

If the receipt is missing or fails parsing, the viewer shows: *"Review unavailable · compare identity mismatch"* (handled at **lines 732-735**).

## Receipt Verification for Automated Systems

The machine receipt enables fully automated architecture governance. Key verification points:

- **`ok: true`** — Comparison succeeded without errors
- **`proofLevel: 'revision-pinned'`** — Highest confidence, both snapshots cryptographically anchored
- **`rawSha256`** — Content hash for external verification of snapshot integrity
- **`completeness: 'complete'`** — All entities were comparable (no partial data)

Automated agents should reject receipts with `proofLevel: 'authored'` for production deployments unless additional verification is applied.

## Summary

- **`compareArchitecture()`** in `archify/delta/architecture-delta.mjs` builds the receipt by validating snapshots, computing entity deltas, and determining proof level based on revision verification
- **`safeJson()`** escapes HTML-sensitive characters to prevent injection and parsing errors
- The CLI in `archify/bin/archify.mjs` embeds the receipt as `<script id="archify-compare-receipt">` and writes standalone JSON with `--receipt`
- Receipts carry **`proofLevel`** distinguishing cryptographically verified (`revision-pinned`) from manually authored comparisons
- The Archify viewer parses the embedded script to render interactive deltas and provenance information

## Frequently Asked Questions

### What is the difference between proof levels in the Archify machine receipt?

The **`'revision-pinned'`** proof level indicates both snapshots have verified 40-character SHA-1 Git revisions and explicit verification flags, enabling cryptographic trust. The **`'authored'`** level (default) means the comparison relies on manually created snapshots without anchored revisions. Automated systems should require `revision-pinned` for production gates.

### How can I extract the machine receipt from a generated HTML file?

Parse the HTML to find `<script id="archify-compare-receipt" type="application/json">` and extract its text content. The JSON is HTML-escaped (Unicode escapes for `<`, `>`, `&`) but standard JSON parsers handle this transparently. Alternatively, use the `--receipt <path>` flag when running `archify compare` to generate a standalone `.json` file.

### Why does the receipt use HTML character escaping inside the script tag?

The **`safeJson()`** function escapes `<`, `>`, and `&` to Unicode sequences (`\u003c`, `\u003e`, `\u0026`) preventing the receipt from breaking out of its `<script>` container or interfering with HTML parsing. This ensures the receipt survives email transmission, web hosting, and viewer rendering without corruption.

### Where is the machine receipt schema versioned and validated?

The receipt declares **`schemaVersion: 1`** in its root object. The Archify viewer at **lines 732-735** validates receipt presence and parsing, displaying *"Review unavailable · compare identity mismatch"* on failure. The test suite in `archify/test/architecture-delta.test.mjs` enforces deterministic output and shape compliance for each release.