schema_version: 1 to 2
Why use it: you still keep *.workflow.json files written against schema v1 with manually fixed geometry, and want to switch to v2's readable layout contract (automatic coordinate solving, with minimum clearance constraints).
What you get: a new v2 JSON file — or a set of diagnostics stating exactly where the v1 version cannot satisfy v2 constraints and needs manual fixing.
Applies only to workflow. Other types have no migration path.
export A=~/.claude/skills/archify
Run
node $A/bin/archify.mjs migrate workflow old.workflow.json new.workflow.json --to-schema 2 --json
Strict syntax, read from commandMigrate() in bin/archify.mjs: exactly three positional arguments (workflow, source, destination) and mandatory --to-schema 2. Any violation → rc 2 with:
Usage: archify migrate workflow <old.json> <new.json> --to-schema 2 [--json]
Source and destination must be two different files (migration/source-destination). No in-place overwrite, by design.
migrate no has the --qualityflag. It pins every stage according to the document's available meta.quality_profile (default standard) and actively removes any floating profiles in the environment.
Green path — verified
Run on the bundled v1 fixtures:
node $A/bin/archify.mjs migrate workflow \
$A/test/fixtures/v1-workflow-explicit-coordinates.workflow.json \
/tmp/migrated.workflow.json --to-schema 2
rc 0. Three other fixtures also give rc 0: v1-workflow-700x400.workflow.json, automatic-routing-node-border-clearance.workflow.json.
Red path — also verified, and you will encounter it
Not every v1 source migrates automatically. Run on test/fixtures/v1-baseline/agent-tool-call.workflow.json:
{
"ok": false,
"command": "migrate",
"type": "workflow",
"source": { "path": "…/v1-baseline/agent-tool-call.workflow.json", "sha256": "4903056b…", "bytes": 5360 },
"fromSchemaVersion": 1,
"toSchemaVersion": 2,
"preExistingDiagnostics": [],
"migrationDiagnostics": [],
"newSchemaDiagnostics": [
{
"code": "workflow/route-preset-conflict",
"severity": "error",
"message": "Workflow edge \"chat->planner\" cannot satisfy route preset \"drop\" under readable-v2 constraints (minimum 8px endpoint stubs, 16px interior turns, and 28px direct clearance)."
}
]
}
rc 1.
Three diagnostic groups, three different actions
The receipt splits into three arrays, don't mix them up:
| Array | Meaning | Action needed |
|---|---|---|
preExistingDiagnostics |
The v1 source was already wrong beforehand | Fix the v1 file first, then migrate again |
migrationDiagnostics |
The conversion itself failed (paths, duplicate files, unreadable JSON) | Fix the command line |
newSchemaDiagnostics |
Converted, but the result does not satisfy v2 constraints | Fix the geometry/route in the v2 version by hand |
workflow/route-preset-conflict above belongs to group three: the route preset drop of that edge cannot survive under the readable-v2 constraint (endpoint stub ≥8px, bend inside ≥16px, direct clearance ≥28px). The fix is to change the route preset or loosen the layout — not to force the tool.
After migrating
Always validate the new version before using it:
node $A/bin/archify.mjs validate workflow /tmp/migrated.workflow.json --quality showcase --json
v2 geometry diagnostics use the stable compiler receipt:
node $A/bin/archify.mjs validate workflow /tmp/migrated.workflow.json --layout-json
Internals of the solver no must be a control button for editing. Only affect through the fields declared in the source.
When do not migrate
From SKILL.md: keep schema_version: 1 when an existing source needs old fixed geometry — for example a diagram already printed in a document and the coordinates must match pixel for pixel. Workflow sources new always use v2.
The standard contract for layout, pins, migration and receipts is in renderers/workflow/README.md, section "Layout contracts".