# How Changes Are Classified in Archify's Architecture Delta: Semantic, Topology, and Geometry Detection

> Discover how Archify classifies architecture delta changes into semantic, topology, and geometry categories. Understand entity modifications for robust architecture validation.

- Repository: [tt-a1i/archify](https://github.com/tt-a1i/archify)
- Tags: deep-dive
- Published: 2026-08-28

---

**Archify's Architecture Delta turns two validated architecture snapshots into a deterministic proof by classifying every entity change into semantic, evidence, geometry, topology, or scope categories based on specific field differences.**

Archify is an open-source tool that generates architectural diagrams and delta proofs between versions. Understanding how the **Archify Architecture Delta** classifies changes is essential for interpreting diff reports and automating architectural governance. The classification engine, implemented in `archify/delta/architecture-delta.mjs`, examines components, connections, and boundaries to categorize modifications at the field level.

## The Five Classification Dimensions

The delta engine groups entity fields into five distinct classifications. Each entity type—**Component**, **Connection**, and **Boundary**—maps its internal fields to these classifications as defined in lines **L151-L162** of the core delta module.

### Component Classification Mapping

Components track identity through semantic and evidence fields, plus spatial positioning:

| Classification | Fields |
|---------------|--------|
| **semantic** | `type`, `label`, `sublabel`, `tag` |
| **evidence** | `sources` |
| **geometry** | `row`, `col`, `pos`, `size` |

### Connection Classification Mapping

Connections emphasize topology (endpoints) alongside semantic and routing geometry:

| Classification | Fields |
|---------------|--------|
| **topology** | `from`, `to` |
| **semantic** | `label`, `variant` |
| **geometry** | `fromSide`, `toSide`, `route`, `via`, `labelAt`, `labelDx`, `labelDy`, `labelSegment`, `width` |

### Boundary Classification Mapping

Boundaries track scope containment and padding adjustments:

| Classification | Fields |
|---------------|--------|
| **scope** | `wraps` |
| **geometry** | `pad` |

## Detecting Field-Level Changes with `fieldChanges`

The `fieldChanges` function (lines **L141-L148**) iterates over these classification groups to detect modifications. It compares normalized field values between *before* and *after* snapshots, returning both the classifications touched and the specific fields altered:

```javascript
function fieldChanges(before, after, groups) {
  const classifications = [];
  const changedFields = [];
  for (const [classification, fields] of Object.entries(groups)) {
    const changed = fields.filter(
      (field) => !equal(normalizedField(before, field), normalizedField(after, field))
    );
    if (changed.length) classifications.push(classification);
    changedFields.push(...changed.map((field) => `/${field}`));
  }
  return { classifications: sorted(classifications), changedFields: sorted(changedFields) };
}

```

A classification is recorded **if and only if** at least one field in that group differs between snapshots. Changed fields are prefixed with `/` to indicate JSON Pointer paths.

## Mapping Classifications to Human-Readable Statuses

Once classifications are identified, the `statusFor` function (lines **L163-L168**) derives the high-level change status. This mapping determines the final symbol displayed in delta reports:

```javascript
function statusFor(classifications, kind) {
  if (classifications.some(v => ['topology','semantic','scope'].includes(v))) return 'changed';
  if (classifications.includes('evidence')) return 'evidence-changed';
  if (classifications.includes('geometry')) 
      return kind === 'connection' ? 'rerouted' :
             kind === 'component'  ? 'moved' : 'geometry-changed';
  return 'same';
}

```

This logic yields the following delta symbols:

- **`+`** (`added`): New entity detected
- **`-`** (`removed`): Entity no longer present
- **`~`** (`changed`): Semantic, topology, or scope modification
- **`evidence-changed`**: Only `sources` list updated
- **`↔`** (`moved`/`rerouted`/`geometry-changed`): Pure geometry adjustment (components move, connections reroute, boundaries resize)

## Orchestrating the Comparison with `compareEntities`

The `compareEntities` function (lines **L170-L184**) orchestrates the complete diff. It walks the union of entity IDs from both snapshots, invokes `fieldChanges` for matches, and assigns statuses:

```javascript
function compareEntities(baseIndex, headIndex, kind, groups, describe) {
  const changes = [];
  const identityClassification = kind === 'connection' ? 'topology'
                            : kind === 'boundary'   ? 'scope'
                            : 'semantic';
  for (const id of sorted(new Set([...baseIndex.keys(), ...headIndex.keys()]))) {
    const base = baseIndex.get(id);
    const head = headIndex.get(id);
    if (!base)   changes.push({ ...describe(id, undefined, head), status: 'added',   classifications: [identityClassification], changedFields: [] });
    else if (!head) changes.push({ ...describe(id, base, undefined), status: 'removed', classifications: [identityClassification], changedFields: [] });
    else {
      const fields = fieldChanges(base, head, groups);
      const status = statusFor(fields.classifications, kind);
      if (status !== 'same') changes.push({ ...describe(id, base, head), status, ...fields });
    }
  }
  return changes;
}

```

Entities existing in only one snapshot receive an **identity classification** (`topology` for connections, `scope` for boundaries, `semantic` for components) to mark them as added or removed.

## Practical Usage Examples

### Generating Delta Reports via CLI

Use the CLI entry point at `archify/bin/archify.mjs` to generate HTML delta proofs:

```bash

# Compare two architecture JSON files and emit an HTML delta

archify compare architecture \
  snapshots/base.json snapshots/head.json \
  --output examples/checkout-platform-delta.html

```

The generated HTML contains a **Changes** list displaying:
- Entity kind (Component / Relationship / Boundary)
- Status symbol (`+`, `-`, `~`, or `↔`)
- Classification list (e.g., `semantic, geometry`)
- Exact changed fields (e.g., `/label, /row`)

### Programmatic Access to Classifications

Import `compareArchitecture` directly to inspect classifications programmatically:

```javascript
import { compareArchitecture } from './archify/delta/architecture-delta.mjs';
import base from './snapshots/base.json';
import head from './snapshots/head.json';

const receipt = compareArchitecture(base, head);
console.log(receipt.summary);           // { added: 2, removed: 1, changed: 4, ... }
console.log(receipt.changes[0]);        // { id:'c-42', status:'changed', classifications:['semantic','geometry'], changedFields:['/label','/row'] }

```

The `receipt.changes` array contains the complete classification payload for automation or custom reporting.

## Summary

- **Archify Architecture Delta** uses five classifications (**semantic**, **evidence**, **geometry**, **topology**, **scope**) to categorize every architectural change.
- Field mappings are defined per entity type in `archify/delta/architecture-delta.mjs`, lines 151-162.
- The `fieldChanges` function detects modified fields by classification group, while `statusFor` maps these to human-readable statuses like `moved`, `rerouted`, or `changed`.
- Pure geometry changes emit distinct symbols (`↔`) compared to semantic or topology changes (`~`), allowing precise communication of refactoring versus restructuring.
- The deterministic comparison algorithm ensures consistent, reproducible delta proofs across CLI and programmatic interfaces.

## Frequently Asked Questions

### What is the difference between topology and semantic classifications?

**Topology** classifications track structural relationships—specifically the `from` and `to` endpoints of connections. **Semantic** classifications track meaning and identity, including labels, types, tags, and variants. A connection changing its endpoint receives a `topology` classification (status: `changed`), while a connection keeping the same endpoints but changing its label receives only a `semantic` classification.

### How does Archify distinguish between a component moving versus a connection rerouting?

Both changes trigger the **geometry** classification, but the `statusFor` function (lines 163-168) checks the entity `kind` parameter. For components, geometry changes return `moved`; for connections, they return `rerouted`; for boundaries, they return `geometry-changed`. This distinction provides appropriate semantics for each entity type without requiring separate classification categories.

### Can I customize which fields trigger specific classifications?

Currently, the field-to-classification mappings are **hardcoded** in the `groups` objects within `compareEntities` invocations (around lines 151-162). To customize classifications, you would need to modify the source in `archify/delta/architecture-delta.mjs`, specifically the `groups` parameter passed to `fieldChanges` for each entity type.

### What happens if only the evidence/sources field changes?

If only the `sources` field differs, the entity receives an `evidence-changed` status rather than `changed`. This distinction allows reviewers to ignore updates that merely reflect new source code references (such as updated line numbers) while flagging actual architectural modifications for review.