Skip to content

The CLI's JSON output

llms.txtlists every page for an agent
Optional: hand this page to your coding agentThe steps work by hand too.
Show the whole prompt
Read https://intentius.io/terragucci/reference/cli-json/.
Write a script that runs `npx terragucci plan --json` and branches on the envelope's `exit` and `status` and on `results.roots`, printing each failed root's summary.
Read only. Never apply, approve (a pull request review or `terragucci approve`), override a policy denial (`terragucci override`), use `--mode apply`, or merge; never touch `.chant/allowed_signers` or `chant/lifecycle`.

With --json, these commands print only one JSON object on stdout.

{
"schema": 1,
"command": "init",
"exit": 0,
"status": "ok",
"results": {}
}
Field Holds
schema The envelope version. It changes only when a field is removed or changes meaning; new fields can appear without a bump.
command init, reconcile, plan, stage, rollout, respond, config check or query.
exit The process exit code.
status ok for exit 0, failed for 1, usage for 2, waiting for 3.
results What the command found or did, as below. null when the command could not run.
error Present when results is null: why it could not run.

--json leaves the exit codes as they are. stage tf-apply refuses --json and writes its outcome to a file instead, so no envelope carries code 4.

init --dry-run --json computes everything and writes nothing.

Field Holds
dryRun Whether the run wrote files.
roots Each root as path and reason, such as backend s3, cloud block, choudoufu live block (a choudoufu estate), provider aws or matches roots glob <glob>.
layers Roots grouped in apply order; roots in one layer can apply together.
binary, version, forge Each as value and reason, where the reason names the file, flag or detection that decided it.
image The CI image the pipeline runs in.
files Each file as path, status (created, updated or unchanged) and content.
notes Settings the pipeline does not act on, and flags the config overrides.
configNote Whether a terragucci.yml was used or written.

results holds mode (dry-run or apply) and projects, with these fields per project:

Field Holds
key The project, as <host>/<path>.
status unchanged, would-change, pull-request or failed.
changes The files, as in init’s files.
pullRequest The pull request’s URL, when one was opened.
error Why the project failed.
tips On a dry run with tips on, advice on the project’s setup, as rule, root, message and url.

The exit code is 1 when any project failed.

results.roots has one entry per root, in apply order:

Field Holds
root the root’s path
ok whether it planned
summary the plan’s Plan: or No changes. line, or the failure
results field Holds
stage the stage that ran
change_set the set digest
files the report files
uploaded the bucket copy; null without reports.bucket
issue tf-drift only: action (opened, updated, closed, left-open or none), issue and error

A root that refused to plan exits 1.

On every exit but a usage error, stage tf-apply writes its wave’s outcome to the file TG_OUTCOME_JSON names. With --rest the file holds the last wave that ran. The generated apply jobs set the variable when notify is on, and terragucci notify reads the file. A waiting wave’s file carries the terragucci approve command that approves it and where its gate’s record lives on chant/lifecycle.

{
"schema": "terragucci.outcome/v1",
"status": "waiting",
"exit": 3,
"wave": 2,
"roots": ["envs/prod/app", "envs/prod/db"],
"line": "wave 2 waits: terragucci approve wave-2 --plan jcs1-sha256:9f2c...",
"set_digest": "jcs1-sha256:9f2c...",
"gate": { "name": "wave-2", "branch": "chant/lifecycle", "path": "_gates/tf-apply.jsonl" },
"approval": "waiting",
"approval_mode": "pr-review",
"approve_command": "terragucci approve wave-2 --plan jcs1-sha256:9f2c...",
"waiting_since": "2026-10-08T14:02:11.000Z",
"review": { "pull_request": 12, "url": "https://github.com/acme/infra/pull/12/files" }
}
Field Holds
schema terragucci.outcome/v1. It changes only when a field is removed or changes meaning; new fields can appear without a bump.
status, exit applied (0), waiting (3), refused (4; 5 when another run’s apply holds a resource it changes; 6 when a newer push superseded it) or failed (1)
wave, roots the wave and its roots (units in a Terragrunt repo); roots is empty when the repo has no such wave
line the line the job’s terragucci/apply status carries, when the wave wrote one (TG_OUTCOME)
set_digest the set digest over the roots that change: what an approval binds
gate when a gate held the wave: its name and the branch and path of its ledger
approval waiting, approved or not-required
approval_mode with a gate: ledger, pr-review or sealed, the mode in force at base
approve_command waiting, or refused because the plans moved after an approval or a review: the terragucci approve command for set_digest, with --sign under sealed
waiting_since waiting: when the wave began waiting for an approval of this digest
review waiting under approval: pr-review: the pull_request whose approving review of its head would approve the wave, and the url to review it on
refused why the wave applied nothing although it planned: reason (approval, review, override or policy), the digest approved and by whom, and the roots that moved or were denied
policy_denied the roots the policy denied, when no override lets them through
failed_roots failed: the roots that failed to plan or apply

results holds the state the run left the rollout in.

Field Holds
kind, name module or provider, and the module or provider address.
from, to The version that moves and the one it moves to.
discovered Where to was found, when no version was named: a tag, or an OCI repository.
mode dry-run or apply.
status complete, opened, would-open, waiting or stopped, with stop saying why it stopped.
waves wave, canary and parts: project, roots, branch, state, pullRequest, pending, failed, files.
roots project, root, state (from, to, refused or elsewhere), version, reason.
tips Each refused root’s tip, as rule, project, root and message.

A part’s state is applied, nothing-to-move, opened, would-open, open, waiting-apply, failed, closed or not-reached. Exit 3 means waiting; 1 means stopped.

results field Holds
event, response, text the event, the response it got and the text printed
skipped, data, proposals, agent_input set only when the response has them
exit set when the command exits other than 0

respond rollout with no module puts mode and rollouts in data: for each rollout in flight, kind, name, from, to, wave (its newest), waves, action (ran, waiting, stopped, done or failed), reason, pullRequests, and result, the rollout when it ran.

Exit 0 when handled, and 1 when a rollout respond rollout continued could not run. An unknown event or a missing flag exits 2 with results null.

terragucci config check [--config <file>] lists every problem, and for .ts checks that folding and running agree.

results field Holds
file the config file read
ok whether it has no problems
problems a list of strings; a config with problems exits 2
approval for a repo’s own config with no problems: mode (ledger, pr-review or sealed), source (the key, identity.gates, or the default) and a note when the repo should change something
warnings present when there are some: each role that reaches another environment’s state, as text; warnings leave the exit code 0
state_access with oidc.roles and no problems: one entry per role and stage, with role, stage (plan or apply), environment (the glob, or plan_role/apply_role), roots, states (the state keys its roots’ backends name) and reads (other environments’ states they read)

terragucci query "<statement>" --json prints the rows the statement returned.

results field Holds
columns the column names, in order
rows one object per row, by column name; SQL NULL is null
tables the row count of each table: inventory, changes, history, audit and edges

terragucci

These docs count page views and clicks with PostHog. They set no cookies, store nothing in your browser, and send nothing when your browser asks not to be tracked.