Skip to content

run compiles one plan or state export into a Form, opens a saved Form, or compares two accepted inputs. It detects their kind from content. A plan or state export is analyzed with the active Dialects; a saved Form is validated and loaded without reinterpretation.

Accepted inputs

InputForm
Plan JSON from show -json on a saved planPlanned stage, available earlier stages, drift and internal comparisons
State JSON from show -jsonOne Recorded stage
Saved FormIts saved stages, facts, closures, and evidence
-One of those JSON forms on standard input

With --diff <input>, each operand is a plan, a state, or a saved single-input Form; a comparison Form reopens alone and is never a --diff operand. At most one operand may read standard input. A configuration directory and a binary saved plan are not analysis inputs. --project <dir> selects project Dialect content; it does not read that directory as infrastructure evidence. See Choose an input.

Usage

rootform run <input> [--diff <input>] [options]
SHELL

Options

Inputs and stages

FlagTypeDefaultDescription
--after-stagestring""stage of the second input to compare: planned|refreshed|recorded; default: Planned for a plan, Recorded for a state
--before-stagestring""stage of the first input to compare: planned|refreshed|recorded; default: Planned for a plan, Recorded for a state
--diffstring""compare with a second input: a plan, a state, or a saved single-input Form
--stagestring""stage the summary leads with, for one input: planned|refreshed|recorded; default: Planned for a plan, Recorded for a state

Output

FlagTypeDefaultDescription
--detailsboolfalseadd semantics, closure counts, and diagnostic codes; a Markdown summary and the summary beside the explorer then list every entry
--formatstring""format of standard output, or of a single -o file without a recognized extension: text|json|markdown|html; default: text
-o, --outputstringArray[]write file; its extension selects the format: .json (the Form), .txt, .md, or .html; repeatable

Explorer

FlagTypeDefaultDescription
--no-browserboolfalseserve the explorer without opening a browser
--no-serveboolfalseexit once the outputs are written instead of serving the explorer
--portint21717serve the explorer on loopback port; 0 picks a free port; default: 21717

Rootform project

FlagTypeDefaultDescription
--dialectstringArray[]use Dialect source dir for this command only; repeatable
--lockedboolfalserefuse to run unless rootform.lock is valid
--projectstring""read rootform.lock from project dir; paths stay relative to the working directory; default: the working directory

Advanced evidence settings

FlagTypeDefaultDescription
--diff-plan-filestring""pair the --diff plan JSON with its saved plan file, as --plan-file does
--plan-completestring""declare the plan complete; the only value is attested
--plan-filestring""pair the plan JSON with the saved plan file it was exported from, to enrich it; pairing compares version, timestamp, and configuration shape
--producerstring""declare the tool that produced the input: terraform|opentofu
--provider-mapstringArray[]map an observed provider to a binding, as observed=binding; repeatable
--require-enrichmentboolfalserefuse the input when its saved plan file does not pair with the plan JSON

Global options

FlagTypeDefaultDescription
-h, --helpboolfalseshow how to use rootform run
--colormodeautocolor human output: auto|always|never; default: auto
--no-pagerboolfalseprint a long report in full instead of opening it in less

Examples

Analyze one plan, then save its Form:

rootform run plan.json --plan-file plan.tfplan --require-enrichment --no-serve -o analysis.json
Shell

The summary goes to standard output, and Wrote analysis.json to standard error. The status is 0; a saved plan that fails verification exits 3 because of --require-enrichment. The quickstart reads the same summary step by step.

Compare two plan exports and save a Markdown report:

rootform run base/plan.json --plan-file base/plan.tfplan \
--diff head/plan.json --diff-plan-file head/plan.tfplan \
--no-serve -o comparison.md
Shell

The comparison summary goes to standard output. comparison.md contains a Markdown review with bounded lists; --details includes every entry. See Review with Markdown. Differences are not failures: the status is 0.

--stage selects the reported stage of one input. With --diff, use --before-stage and --after-stage; a missing or ambiguous stage is refused with available choices. A plan defaults to planned; a state defaults to recorded. The saved Form keeps every stage its input supports, whatever stage the summary reports; rootform check chooses the stage it evaluates on its own.

Serve or export

By default, run starts a loopback-only server, opens a browser, and stays in the foreground until interrupted. --no-browser leaves browser launch to you. --port 0 selects an available port. --no-serve writes requested outputs and exits. The server analyzes once; it does not watch files or replan. See Explore a Form.

See Outputs and exit status for the complete file-format, stream, collision, and write-failure contract.

Project selection

Embedded Dialects work without a lock. --locked requires a valid rootform.lock for the selected project. --dialect selects local Dialect sources for this analysis; an override cannot be combined with --locked. run does not select or evaluate Policies. Use rootform check for a separate Policy gate.

--plan-file verifies and enriches the first plan; --diff-plan-file does the same for the second. --require-enrichment refuses a failed pairing. --producer, --provider-map, and --plan-complete=attested record operator claims rather than facts established by the plan. See plan inputs.

Exit status

Status 0 means the Form was produced or opened; 2 means the command was used incorrectly; 3 means an input was refused, rootform.lock is invalid, or a requested stage is unavailable; 4 means an input or output file, or the explorer, failed. Architectural differences and reported drift do not by themselves make the command fail. Read the exact output contract.