# How the Archify Lifecycle Renderer Handles State Machines: From JSON IR to Deterministic SVG

> Discover how Archify's lifecycle renderer transforms state machine JSON into SVG diagrams. Learn about input validation, geometry computation, and rendering states and transitions for clear visualization.

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

---

**The Archify lifecycle renderer converts declarative state-machine JSON into deterministic SVG diagrams by validating the input against a strict schema, computing horizontal rail geometry with band separators, and rendering states, retry loops, and wait transitions using a shared geometry engine.**

The Archify lifecycle renderer processes deterministic state-machine visualizations by ingesting typed JSON IR and emitting reproducible HTML/SVG outputs. According to the tt-a1i/archify source code, the renderer implements a multi-stage pipeline that validates input structure, calculates geometric layouts, and applies lifecycle-specific styling to transitions including retries and waits.

## Input Model and Schema Validation

The renderer expects a typed JSON IR that describes **states** and **transitions** with strict structural requirements. The input must contain a top-level object with `type: "lifecycle"` and two primary arrays: `states[]` (each with an `id`, `label`, and optional `meta`) and `transitions[]` (each with `from`, `to`, and optional `kind` such as `retry`, `wait`, or `exit`).

Before any geometry calculation begins, the shared validator at `archify/renderers/shared/validator.mjs` runs the incoming IR against the lifecycle schema. Any missing required fields or malformed edges produce machine-readable diagnostics that the CLI reports immediately, preventing invalid renders.

```json
// lifecycle-example.json – minimal state-machine IR
{
  "type": "lifecycle",
  "id": "agent-run",
  "states": [
    { "id": "queued",   "label": "Queued" },
    { "id": "planning", "label": "Planning" },
    { "id": "executing","label": "Executing" },
    { "id": "reviewing","label": "Reviewing" },
    { "id": "completed","label": "Completed", "kind": "terminal" }
  ],
  "transitions": [
    { "from": "queued",    "to": "planning" },
    { "from": "planning",  "to": "executing" },
    { "from": "executing", "to": "reviewing" },
    { "from": "reviewing", "to": "completed" },
    { "from": "executing", "to": "queued",    "kind": "retry" },
    { "from": "executing", "to": "reviewing", "kind": "wait" }
  ]
}

```

## Geometry Construction and Rail Layout

The core rendering logic resides in `archify/renderers/lifecycle/render-lifecycle.mjs`. This module builds a single horizontal **rail** that represents the primary execution flow, positioning each state along the rail based on the order defined in the `states` array with uniform spacing.

To maintain readability, the renderer groups states into **bands** (logical phases) and draws thin separator lines between them. This banding ensures that retry or exit arrows never cross unrelated portions of the diagram, preserving visual clarity even for complex state machines with multiple terminal exits.

```bash

# Generate a deterministic HTML file for the lifecycle diagram

node archify/bin/archify.mjs render lifecycle lifecycle-example.json \
  --output lifecycle-diagram.html --quality showcase

```

## Handling Special Transitions: Retries, Waits, and Exits

The lifecycle renderer treats transition `kind` values as rendering instructions rather than semantic metadata. **Retry** transitions are rendered as curved arcs that loop back to earlier states, creating visual feedback loops without confusing the primary left-to-right flow. **Wait** transitions appear as muted arrows that indicate pauses in execution flow, distinct from standard active transitions.

Terminal states (marked with `"kind": "terminal"`) receive special styling indicators that signal the end of the lifecycle. The renderer calculates collision-free paths for all transition types, ensuring that overlapping retry loops and forward edges remain distinguishable in the final SVG.

## Styling, Animation, and Export

Visual presentation draws from the shared layout utilities in `archify/renderers/shared/geometry.mjs`. The lifecycle renderer applies a specific color palette centered on `#be123c` to distinguish it from other Archify diagram types.

When the input IR contains an `animation` meta flag set to `trace`, the generated HTML includes a `<script>` tag that animates each transition in sequence, highlighting the active state and any waiting periods. The final output is a fully deterministic HTML file containing the SVG diagram plus the original IR embedded in a script tag. Re-rendering the same JSON always yields identical SVG output, ensuring reproducible documentation.

## Summary

- **Strict validation** occurs first via `archify/renderers/shared/validator.mjs` to ensure schema compliance before geometry calculation.
- **Horizontal rail layout** positions states linearly while **band separators** group logical phases to prevent edge collisions.
- **Special transition types** (retry, wait, exit) receive distinct geometric treatments—curved arcs, muted styling, and terminal indicators.
- **Deterministic output** guarantees that identical JSON inputs produce byte-identical HTML/SVG artifacts suitable for version-controlled documentation.

## Frequently Asked Questions

### What JSON schema does the Archify lifecycle renderer require for state machines?

The renderer requires a top-level object with `type: "lifecycle"` containing `states[]` (with `id`, `label`, optional `meta`) and `transitions[]` (with `from`, `to`, optional `kind`). The schema is validated against the shared validator in `archify/renderers/shared/validator.mjs` before rendering begins.

### How does Archify handle retry loops in lifecycle diagrams?

Retry transitions (marked `"kind": "retry"`) are rendered as curved arcs that loop back to earlier states in the rail. These arcs are geometrically isolated within their respective bands to prevent visual confusion with forward-progress transitions.

### What makes the Archify lifecycle renderer output deterministic?

The renderer emits self-contained HTML files with embedded SVG and the original IR inside a `<script>` tag. The geometry engine uses fixed spacing algorithms and consistent sorting, ensuring that identical JSON inputs always produce identical SVG coordinates and styling.

### How are wait transitions visually distinguished from standard transitions?

Wait transitions use muted arrow styling and reduced opacity compared to standard transitions. When animation is enabled via the `trace` meta flag, wait periods display as paused intervals between state highlights, visually indicating temporal delays in the lifecycle flow.