# How Archify Preserves Geometry During Workflow Schema Migration: A 3-Step Technical Approach

> Learn how Archify preserves geometry during schema migration. Discover the 3-step technical approach that isolates rank plans and re-projects pins for seamless updates.

- Repository: [tt-a1i/archify](https://github.com/tt-a1i/archify)
- Tags: technical-explanation
- Published: 2026-09-09

---

**Archify preserves diagram geometry during schema migration by isolating the rank plan from routed coordinates, then re-projecting only the necessary X pins onto the new column structure using a deterministic piecewise-linear mapping function.**

When upgrading workflows from **schema-v1** to **schema-v2**, Archify ensures that visual layouts remain pixel-perfect. The migration engine avoids the common pitfall of regenerating coordinates from scratch, which would destroy carefully authored edge paths. Instead, the system implemented in `archify/renderers/workflow/workflow-migration-geometry.mjs` separates semantic structure from geometric data, allowing safe transformation of only the metadata that must change.

## The Three-Step Geometry Preservation Strategy

Archify’s migration pipeline operates through three coordinated phases that progressively isolate, plan, and remap geometry without altering the underlying visual relationships.

### Step 1: Creating an Intrinsic Schema-v2 Copy

The `intrinsicWorkflow` function generates a baseline v2 document by cloning the original workflow and forcing the `schema_version` to **2**. Critically, this step only removes the `viewBox` metadata—which is unrelated to actual diagram geometry—while preserving all edge-shape definitions including paths, points, and channels.

```javascript
// archify/renderers/workflow/workflow-migration-geometry.mjs (Lines 12-17)
export function intrinsicWorkflow(workflow) {
  const intrinsic = clone(workflow);
  intrinsic.schema_version = TARGET_SCHEMA_VERSION;
  intrinsic.meta = { ...intrinsic.meta };
  delete intrinsic.meta.viewBox;
  return intrinsic;
}

```

By maintaining the original `via`, `labelAt`, and `channelX/Y` data intact, this function ensures that the migrated document retains its authored visual structure while meeting the new schema requirements.

### Step 2: Generating the Geometry-Free Planning Projection

Before calculating new column positions, Archify must determine the **readable rank plan** without interference from legacy coordinate values. The `planningWorkflow` function strips all routed geometry—removing concrete `via`, `labelAt`, and channel data—while preserving only the rank-affecting relationships between nodes.

```javascript
// archify/renderers/workflow/workflow-migration-geometry.mjs (Lines 25-42)
export function planningWorkflow(workflow) {
  const planned = intrinsicWorkflow(workflow);
  planned.edges = planned.edges.flatMap((edge) => { 
    // Geometry stripping logic while preserving connectivity
  });
  // Additional planning transformations...
  return planned;
}

```

This projection allows the compiler to compute optimal column positions based purely on graph topology, ignoring the old absolute coordinates that might constrain the new layout.

### Step 3: Remapping Absolute X Coordinates to the New Rank Plan

The final phase applies a deterministic coordinate transformation using three specialized functions:

- **`createHorizontalRankMapper`** builds a piecewise-linear function that maps each old column coordinate to its new position based on the rank plan calculated from the geometry-free projection.

- **`mapExplicitCoordinates`** walks every edge in the workflow, applies the mapper to each explicit X coordinate (`via`, `labelAt`, `channelX`), and records transformation details for auditing.

- **`createMappedWorkflowCandidate`** orchestrates the entire process, returning both the migrated document and an audit trail of changed coordinates.

```javascript
// Mapping creation – Lines 65-99
export function createHorizontalRankMapper(oldColumns, newColumns) { 
  // Returns piecewise-linear mapping function
}

// Apply mapping – Lines 7-31
export function mapExplicitCoordinates(workflow, mapX) { 
  // Transforms explicit X coordinates while preserving edge shapes
}

// Full candidate assembly – Lines 38-44
export function createMappedWorkflowCandidate(workflow, oldColumns, newColumns) {
  const document = clone(workflow);
  document.schema_version = TARGET_SCHEMA_VERSION;
  const mapX = createHorizontalRankMapper(oldColumns, newColumns);
  const changedCoordinates = mapExplicitCoordinates(document, mapX);
  return { document, changedCoordinates };
}

```

## Implementation Details in workflow-migration-geometry.mjs

The core migration logic resides in `archify/renderers/workflow/workflow-migration-geometry.mjs`, which exports utilities for both partial and complete transformations. The module ensures that **only horizontal (X) coordinates require remapping** while vertical (Y) positions and edge path geometries remain untouched.

Key implementation characteristics include:

- **Immutable transformations**: Every function clones the workflow rather than mutating the original, enabling safe rollback if migration fails.
- **Selective coordinate mapping**: The system distinguishes between implicit layout data (removed during planning) and explicit authored geometry (preserved and remapped).
- **Audit trail generation**: The `changedCoordinates` array provides complete transparency into which specific pixels shifted during migration.

## Complete Migration Workflow Example

Below is a practical implementation showing how these functions chain together to preserve geometry during schema upgrades:

```javascript
import {
  intrinsicWorkflow,
  planningWorkflow,
  createMappedWorkflowCandidate,
} from './workflow-migration-geometry.mjs';

// 1️⃣  Load a legacy workflow (schema-v1)
const legacyWorkflow = await fetch('workflow-v1.json').then(r => r.json());

// 2️⃣  Get a clean v2 copy (still with original geometry)
const intrinsic = intrinsicWorkflow(legacyWorkflow);

// 3️⃣  Build a geometry-free planning projection for rank calculation
const planning = planningWorkflow(legacyWorkflow);

// 4️⃣  Determine old and new column positions (example values)
const oldColumns = [0, 200, 400];
const newColumns = [0, 250, 500];

// 5️⃣  Create the final migrated workflow, mapping X pins onto the new plan
const { document: migratedWorkflow, changedCoordinates } =
  createMappedWorkflowCandidate(legacyWorkflow, oldColumns, newColumns);

// migratedWorkflow now has schema_version = 2 and retains all authored geometry.
// changedCoordinates lists every X coordinate that was adjusted.

```

This pattern ensures that when `schema_version` increments from 1 to 2, the visual diagram remains identical to the original authoring, with only the necessary metadata and column alignment updated.

## Summary

- **Geometry isolation**: The `planningWorkflow` function strips routed coordinates to calculate rank plans without legacy constraints.
- **Selective metadata removal**: `intrinsicWorkflow` removes only the `viewBox` property while preserving all path and edge definitions.
- **Deterministic remapping**: `createHorizontalRankMapper` applies piecewise-linear transformations to map old absolute X coordinates onto new column structures.
- **Audit transparency**: The migration returns both the transformed document and a complete list of changed coordinates for verification.
- **Zero geometry loss**: Edge shapes, paths, and visual relationships remain pixel-perfect throughout the schema upgrade process.

## Frequently Asked Questions

### What is the difference between `intrinsicWorkflow` and `planningWorkflow`?

**`intrinsicWorkflow`** creates a schema-v2 copy that preserves all original geometry including edge paths and coordinates, removing only the `viewBox` metadata. **`planningWorkflow`** generates a geometry-free projection used to calculate the new rank plan by stripping all routed coordinate data while maintaining node connectivity relationships. The intrinsic copy serves as the base for the final document, while the planning projection feeds the layout engine.

### Why does Archify remove viewBox metadata during migration?

The `viewBox` property in schema-v1 workflows contains viewport information that is semantically different from the actual diagram geometry. Because schema-v2 uses a different coordinate system or rendering approach for viewports, retaining the old `viewBox` would cause display errors. Removing it allows the renderer to generate appropriate viewport metadata for the new schema while keeping the actual diagram elements—nodes, edges, and paths—exactly where the author placed them.

### How does the horizontal rank mapper handle coordinate transformation?

The `createHorizontalRankMapper` function constructs a **piecewise-linear mapping** that aligns old column positions with new calculated ranks. When provided with arrays of old and new column coordinates (e.g., mapping `[0, 200, 400]` to `[0, 250, 500]`), it creates a deterministic function that linearly interpolates positions between column boundaries. This ensures that relative spacing within columns compresses or expands proportionally while maintaining the semantic "column membership" of each element during the schema migration.

### Will edge shapes and paths remain identical after schema migration?

**Yes**, authored edge shapes and paths remain identical because Archify only transforms the **explicit X coordinates** (`via`, `labelAt`, `channelX`) using the rank mapper, while preserving the underlying path definitions and Y coordinates. The migration process specifically avoids regenerating edge geometry from scratch, ensuring that manually routed connections, curved paths, and precise label positions survive the transition from schema-v1 to schema-v2 unchanged except for the necessary horizontal scaling to fit the new column structure.