Skip to content

rootform run analyzes inputs and produces a Form. rootform check evaluates selected Policies against a plan, state, or saved Form and produces separate Policy results. A written file alone does not prove success: check the relevant exit status and standard error. A comparison can contain changes or indeterminate entries while analysis returns 0.

Keep standard output and errors separate

Without --format, standard output carries the human summary. For run, it includes stage, instance, fact, closure, drift, and diagnostic counts as available. For check, it reports evaluation counts and the verdict, per side for a comparison Form. Standard error carries progress, warnings, the loopback server address for run, and failures. Do not merge it into machine-readable standard output.

Without an -o file, --format selects the standard output format. run supports JSON, text, Markdown, and HTML; check supports text, JSON, Markdown, and SARIF. --no-serve writes files and exits; the normal run mode serves the result in the foreground. check never serves. --no-browser changes browser launch, not the server or output.

Read long reports

On an interactive terminal, a long text report or help opens in less once every requested file is written. Enter advances one line, Space one page, b goes back a page, and q quits; quitting never changes the exit status. With --no-pager, a pipe or a file, a CI run, TERM=dumb, or no less installed, Rootform prints the whole report without waiting. ROOTFORM_PAGER names another pager, or disables paging when set to an empty value. The summary printed beside the explorer and JSON, SARIF, Markdown, and HTML output never open a pager.

Text reports list every entry at the chosen depth: every change of a comparison, every violated or indeterminate evaluation with all its evidence, and every row of an explanation. --details adds depth, such as semantics, diagnostic codes, and passed evaluations. The summary beside the Explorer previews each group instead and states how many entries it shows. A Markdown report is a review document with a bounded preview; see Review with Markdown.

Choose an output file

Repeat -o to write several views:

ExtensionCommandContent and use
.jsonrunForm. Reopen with run, inspect stages and evidence, or process as data.
.mdrunMarkdown review of the architecture and its changes.
.txtrunPlain-text report for terminal-oriented review.
.htmlrunSelf-contained interactive Explorer for browser review without a server.
.jsoncheckStructured Policy result.
.mdcheckMarkdown review of the Policy outcomes.
.txtcheckPlain-text Policy report.
.sarif, .sarif.jsoncheckSARIF 2.1.0 Policy result; keep as a build artifact.

The JSON Form is reusable input. Plan Forms can contain stages, internal comparisons, and a drift report; cross-input results have kind: "comparison". check loads a saved Form without recompiling it. Reports and HTML exports are outputs, not analysis inputs. Each -o file takes its format from its extension. Without -o, --format sets the format of standard output. When exactly one -o file has an extension that names no format, --format sets that file's format and standard output keeps the text summary; without --format, that file is refused. --format is also refused when it contradicts an extension or when more than one -o is given. -o - is refused: standard output already carries the summary or the --format output. For check, .html is refused even with --format: the interactive export belongs to run. Each refusal exits 2.

rootform run plan.json --plan-file plan.tfplan --no-serve \
-o analysis.json -o architecture.md -o architecture.html
Shell

All requested formats render before the first file is written. A duplicate target, a format-extension conflict, or an output path that resolves to an input, including through a link, is a usage error (2). Files are written through temporary files in their target directories, then renamed into place individually. If a later write fails, earlier successful files remain and the failed target is reported; exit status is 4.

Review with Markdown

A Markdown report is a review document for a pull request, a merge request, or a CI job summary. Both begin with ## Rootform. run adds ### Architecture; check adds ### Policies. A conclusion or verdict comes first, with evidence limits and comparison scope kept visible. A comparison check states its overall verdict and scope before separate #### Before and #### After sections, each with its stage, counts, and verdict. A ### Details section puts provenance in a collapsible block.

By default, a run report shows at most ten entries in each list, spread over their statuses where applicable. A check report shows at most ten evaluations per outcome and five evidence lines per evaluation. Shortened lists state their shown and total counts. --details includes every entry and evidence line, adds depth such as semantics and diagnostic codes, and includes passed Policy evaluations. Long change and evaluation lists remain collapsible, with all entries inside when --details is set. Values from the input, such as addresses and names, are escaped or written as code, so they cannot add links, markup, or folds.

CLI Markdown reports are standalone and each begins with ## Rootform. The GitHub Action combines the CLI Architecture and Policies sections under one Rootform heading using the reports already produced by the CLI; it does not reparse the Form. See the canonical GitHub Actions integration. CLI reports do not link to other files; publish the Form, Policy result, SARIF, or HTML export separately when reviewers need them.

Analysis exit status

ExitExact condition
0The Form was produced or opened.
2The command was used incorrectly.
3An input was refused, rootform.lock is invalid, or a requested stage is unavailable.
4An input, output, or rootform.lock file, or the explorer, failed.

A difference, an indeterminate comparison entry, or reported drift is not an analysis failure by itself.

Policy check exit status

ExitExact condition
0Every selected Policy passed on every requested side.
1A selected Policy was violated on a requested side.
2The command was used incorrectly.
3No verdict: indeterminate, no target, nothing selected, a side that could not be evaluated, an input that was refused, or an invalid rootform.lock.
4An input, report, or rootform.lock file could not be read or written.

Reports are written for every verdict. No selected Policies means no compliance claim. For Policy coverage and results, see Check a Form with Policies and Understand Policy outcomes.

Read the Policy result

The Policy result JSON has one architectures entry per evaluated architecture: one for a plan or state, and one per evaluated side, Before then After, for a comparison. Each entry holds its stage, status, Policy Packs, Policies, evaluations, violations, diagnostics, and summary. The top-level scope, selection, and status describe the whole check; scope is absent when the check stopped before choosing what to evaluate. See the Policy result contract for exact fields.

Interpret SARIF

SARIF has one run per evaluated architecture, like the Policy result. Each run's properties carry that architecture's status and the overall status. A Policy rule ID is <pack>/<policy>. A pass uses kind: pass and level: none, a confirmed violation uses kind: fail and level: error, and an indeterminate evaluation uses kind: review and level: none. Result properties name the evaluated stage. A Policy execution failure appears under toolExecutionNotifications.

Each Policy result names its instance address as a logical location and its stage in the result properties; SARIF from Rootform has no file locations. Ingestion by a code-scanning service is not tested. Keep the SARIF log as an artifact. The report carries no attribute values, secrets, or configuration text. It still exposes instance addresses and Policy outcomes; apply your sharing rules before uploading it.

Use the HTML export

.html embeds the Explorer and a display copy of the Form in one file. It opens from disk, makes no network requests, and needs no server or neighboring files. The display copy keeps only the Dialect definitions the analysis uses and leaves out external identities that a Dialect records for the JSON Form only; it cannot be reopened as an input. The local server binds 127.0.0.1 and serves the same display copy, never the plan or state files. The reusable .json Form keeps the complete data; review both before sharing. See security guidance and the Form contract.

Expect deterministic results

Given the same accepted inputs, selected Dialects, operator claims, and Rootform binary, the Form and reports are deterministic. The plan or state export's completeness and uncertainty remain visible; a partial or targeted plan cannot become a proof of absence through output formatting.