Skip to content

Run selection commands from the project root. rootform add writes the exact identity to rootform.lock; commit that file with the change that needs it. Install, add, and vendor explains the states involved. For a Dialect still being edited, follow Use a local Dialect.

The sections below are separate recipes, not one continuous lock-file history. Start each from the selection state it describes. If you reuse a project after remove or an embedded-content exclusion, restore the selection before a later locked check; --locked verifies a selection but does not recreate one.

Add local content

From a checkout of the repository, make a small project with the public baseline Pack and synthetic commerce plan. This keeps the example selection separate from the repository's own lock. Plan JSON and saved plans can contain secrets in real projects; keep them out of Git and public artifacts. Rootform reads them locally and runs neither Terraform nor OpenTofu.

mkdir -p content-demo/policies
cp -R policy-packs/baseline/. content-demo/policies/
cp examples/playground/commerce-platform/head/plan.json content-demo/plan.json
cp examples/playground/commerce-platform/head/plan.tfplan content-demo/plan.tfplan
cd content-demo
Shell

From content-demo/, adopt the reviewed source:

rootform add policy-packs ./policies
rootform init . --locked --offline --no-input
rootform list policy-packs --format wide
Shell

The list result shows the selected name, version, and Policy count. add compiles the pack, records its project-relative path and compiled content digest, and creates rootform.lock if needed. The later commands verify and inspect the exact selection. Commit the pack source and lock together. Neither add nor init installs a local source in your Rootform home. To select a local Dialect, use rootform add dialects ./dialects/payments from a project with that source directory.

Add published content

Get a reviewed OCI reference from the publisher. A tag resolves once when add runs; a digest reference names the artifact directly. Rootform verifies the artifact, installs it in your Rootform home, and records its exact identity without a mutable tag. These addresses illustrate the accepted form; replace them with references for content you trust:

rootform add dialects \
registry.example.com/acme/rootform/payments:dialect-payments-0.1.0
rootform add policy-packs \
registry.example.com/acme/rootform/baseline:policy-pack-baseline-0.1.0
Shell

Each successful change prints rootform.lock updated and a line naming the added unit. Repeating the same add leaves the file untouched and prints rootform.lock already matches; nothing changed. To make several additions one project change, pass their references to one add command for the same family. If a requested unit fails verification, the lock stays unchanged.

Installing an OCI unit with rootform install only prepares this machine; it does not select the unit for this project. Use add for project adoption.

Change or drop a selection

For a local source, edit it, then check the edited Pack for one command. The override uses the source without changing rootform.lock. This synthetic plan has two baseline targets, so a passing check reports two passes and exits 0:

rootform check plan.json --plan-file plan.tfplan --policy-pack ./policies
Shell

Without the override, commands refuse a selected local source that differs from the lock. Record the reviewed edit before normal runs:

rootform update policy-pack baseline
Shell

rootform.lock updated means the lock now records the new source digest. A second update with unchanged source reports that the lock already matches.

An OCI selection needs a new reference because its tag was never saved. The new reference must resolve to the same owner or pack name:

rootform update dialect payments \
registry.example.com/acme/rootform/payments:dialect-payments-0.2.0
Shell

To drop a selection, use its owner or pack name:

rootform remove policy-packs baseline
Shell

The lock records the removal; ./policies remains on disk. In a vendored project, add, update, and remove also update the affected .rootform/ family with the lock. Storage reference defines that coupling and recovery when vendored bytes differ.

Replace or exclude an embedded Dialect

This optional recipe applies only to a project that intentionally replaces or excludes embedded aws. It is separate from the commerce example above. An external Dialect with the same owner as an embedded Dialect needs explicit replacement; this example assumes a valid local aws Dialect source:

rootform add dialects ./dialects/aws --replace
Shell

Without --replace, the owner collision stops before the lock changes. Removing the replacement makes the embedded owner active again:

rootform remove dialects aws
Shell

The lock drops the replacement, so later runs use embedded aws again.

To exclude an embedded owner without replacing it, use --embedded; add the bare owner to include it again:

rootform remove dialects aws --embedded
rootform add dialects aws
Shell

The first command records exclude dialect aws; the second records include dialect aws. Inspect the next run's interpreted instance count before adopting an exclusion, since it changes architecture meaning.

The reserved rf vocabulary cannot be excluded or replaced. A selected Policy Pack that needs a Dialect symbol can prevent an incompatible removal or replacement; Rootform checks linking before writing the lock.

Vendor selected content

Vendor each external family selected by the project's lock. Each command requires at least one selection in its family; neither command vendors embedded Dialects or the RF Vocabulary:

rootform vendor dialects --offline
Shell

See Dialect vendoring for its destination and exact behavior. For a selected Policy Pack, run:

rootform vendor policy-packs --offline
Shell

See Policy Pack vendoring. Omit --offline only when Rootform may acquire missing selected OCI content. The generic rootform vendor command copies every selected family.

Prepare another machine or CI runner

For the local content-demo recipe, restore its Pack if you ran the removal example, then commit the lock with its source:

rootform add policy-packs ./policies
Shell

Clone a project whose committed lock still selects the Dialect and Policy Pack you intend to use. The following commands prepare that selection and run the final check:

rootform init . --locked --no-input
rootform run plan.json --plan-file plan.tfplan --locked --no-serve -o analysis.json
rootform check analysis.json --locked
Shell

Project prepared confirms the selection is present and verified. analysis.json is a saved Form. rootform run analyzes it and exits 0 on success; rootform check evaluates selected Policies, exits 0 when all pass, 1 on a violation, and 3 when no decision is possible. init may fetch only OCI digests recorded in the lock. Add --offline when selected content is available at its local path, installed, or vendored and network access must be disabled. init verifies an existing vendor tree, including missing, extra, or changed content; it never rewrites rootform.lock. Normal analysis does not acquire content. CI should use the committed lock and never run add.