Archify Compare Command: Rollback Path and Atomic Commit Explained

The Archify CLI ensures safe architecture updates by validating artifacts before any file system changes, then committing atomically with automatic rollback on failure.

Archify is a CLI-driven visual-architecture engine that treats infrastructure diagrams as versioned artifacts. The compare command sits at the heart of its delivery workflow, enabling teams to diff architecture changes, validate receipt integrity, and commit updates—or fully reverse them—without leaving the system in a partial state. This article breaks down how the compare command's rollback path and atomic commit mechanism work together to prevent corrupted deployments.

How the Archify Compare Command Works

The compare command in archify/bin/archify.mjs takes two architecture artifacts—an HTML rendering and a receipt JSON—and produces a validated diff ready for commit. The CLI entry point delegates to compareComparePair, which orchestrates the entire workflow from parsing through potential rollback.

The command structure follows this pattern:

node bin/archify.mjs compare path/to/prev.html path/to/next.html

Under the hood, Archify extracts htmlCandidate and receiptCandidate from the provided paths, then subjects them to strict validation before any permanent changes occur.

Pre-Commit Validation: The Fail-Fast Gate

Before touching the file system, Archify validates the receipt JSON against multiple criteria:

  • completeness === 'complete' — ensures the architecture generation finished
  • checksPassed === checkCount — confirms all quality gates passed

This validation lives early in archify/bin/archify.mjs (around line 677). If any check fails, the process aborts immediately with no side effects. This fail-fast design guarantees that invalid artifacts never reach the commit phase.

The validation step is critical for atomicity: by catching errors before the first write, Archify eliminates the need to undo partial work from malformed inputs.

Atomic Commit Implementation in commitComparePair

Once validation succeeds, control passes to commitComparePair, also defined in archify/bin/archify.mjs. This function implements true atomicity through a staged commit pattern:

async function commitComparePair({ htmlCandidate, receiptCandidate, outputPath, receiptPath }) {
  const committed = [];

  // Write the new HTML
  await fs.promises.writeFile(outputPath, htmlCandidate);
  committed.push({ label: 'HTML', path: outputPath });

  // Write the new receipt
  await fs.promises.writeFile(receiptPath, receiptCandidate);
  committed.push({ label: 'Receipt', path: receiptPath });
}

The committed array serves as a transaction log. Every successful write is recorded with its label and path, enabling deterministic reversal if subsequent operations fail.

Staging and Finalization Strategy

While the simplified snippet above writes directly to target locations, the full implementation uses staging directories where possible, then performs atomic moves. This minimizes the window where files exist in an inconsistent state.

Automatic Rollback on Commit Failure

The rollback mechanism activates when any file operation throws. The catch block in commitComparePair implements reverse-order cleanup:

} catch (e) {
  const rollbackErrors = [];
  for (const item of [...committed].reverse()) {
    try { await fs.promises.unlink(item.path); }
    catch (err) { 
      rollbackErrors.push(`${item.label}: remove failed (${err.message})`); 
    }
  }
  // Surface error with rollback details
}

Key implementation details:

  • Iteration in reverse() order ensures dependency-sensitive cleanup (remove receipt before HTML if receipt depends on HTML location)
  • Each rollback attempt is wrapped in individual try/catch to continue past non-critical failures
  • Accumulated rollbackErrors provides complete visibility into what succeeded and what didn't

Error Taxonomy and Failure Modes

Archify distinguishes between two failure states with distinct error codes:

Error Code Meaning When It Occurs
delta/commit-failed Write operation failed, but rollback succeeded Initial fs.writeFile or fs.rename throws, all committed items removed
delta/commit-rollback-failed Write failed and rollback partially or fully failed Cleanup of committed items encountered errors, system may be in inconsistent state

This explicit taxonomy, defined in archify/bin/archify.mjs, enables operators to quickly assess severity and determine manual intervention needs.

Visualizing the Rollback Path: Exception Lanes in Architecture Diagrams

Archify's visual output reinforces the rollback concept through dedicated exception lanes in workflow diagrams. The workflow definition in archify/examples/deployment-release.lifecycle.json shows this structure:

  • Node "id":"rollback" with "lane":"exceptions"
  • Edge "from":"ready" to "rollback" marked "variant":"security"

These visual elements serve two purposes:

  1. Engineering clarity — developers see recovery paths as first-class workflow components
  2. Auditability — reviewers can trace exactly where and how the system returns to known-good states

The UI layer (viewer.lens.compare and related scripts) highlights the rollback node, making the recovery path instantly identifiable in generated guides.

Practical Examples: Running Compare and Triggering Rollback

Successful Compare and Commit


# Compare an architecture to itself (demo mode)

node bin/archify.mjs compare \
    examples/deployment-release.lifecycle.html \
    examples/deployment-release.lifecycle.html

This executes the full validation and commit path when the receipt validates successfully.

Provoking Rollback for Testing


# Point to a non-existent receipt to trigger failure

node bin/archify.mjs compare \
    examples/deployment-release.lifecycle.html \
    missing/receipt.json

Expected output includes error code delta/commit-failed or delta/commit-rollback-failed with populated rollbackErrors array detailing cleanup results.

Integration with Smoke Testing

The scripts/package-smoke.mjs harness exercises the compare command in CI pipelines. It:

  1. Generates architecture artifacts
  2. Invokes compare with validation enabled
  3. Asserts receipt integrity
  4. Verifies rollback behavior through intentional failure injection

This ensures the rollback path remains functional across releases.

File Responsibility Rollback Relevance
archify/test/guide.test.mjs Unit tests for generated guides Verifies rollback nodes appear in visual output
archify/recipes/scenarios.mjs High-level scenario definitions Includes "rollback" as a recoverable signal type
archify/examples/deployment-release.lifecycle.json Example workflow Demonstrates exception lane structure

Summary

  • Fail-fast validation in archify/bin/archify.mjs prevents invalid artifacts from reaching the file system
  • Atomic commit via commitComparePair uses a committed transaction log for deterministic writes
  • Automatic rollback reverses successful operations in reverse order when failures occur
  • Explicit error codes (delta/commit-failed vs delta/commit-rollback-failed) clarify recovery needs
  • Visual exception lanes in workflow diagrams make rollback paths auditable and reviewable

Frequently Asked Questions

How does Archify ensure no partial state during a failed compare?

Archify validates all inputs before the first file write, then records every successful operation in the committed array. If any subsequent write fails, the catch block iterates through committed in reverse order and removes each file. This guarantees either complete success or complete reversion—no intermediate states persist.

What is the difference between delta/commit-failed and delta/commit-rollback-failed?

delta/commit-failed means the initial commit operation failed but cleanup succeeded—the system returned to its original state. delta/commit-rollback-failed indicates a more serious condition where both the commit and the subsequent rollback encountered errors, potentially leaving the system in an inconsistent state requiring manual intervention.

Where is the rollback path visually defined in Archify workflows?

The rollback path appears as an exception lane in workflow JSON files like archify/examples/deployment-release.lifecycle.json. Look for nodes with "lane":"exceptions" and edges connecting failure states to the rollback node. The UI layer renders these in a distinct visual style to highlight recovery routes.

Can I test the rollback behavior without modifying source code?

Yes. Invoke node bin/archify.mjs compare with a non-existent receipt path or invalid JSON. This triggers validation or commit failure and exercises the full rollback mechanism. The scripts/package-smoke.mjs harness includes automated tests that verify this behavior in CI environments.

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 →