Skip to content

The reports bucket

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/reports-bucket/.
Write a script that reads estate.json and index.json at the top of my reports prefix with a read-only identity, validates each against the JSON Schema the page names, and prints every waiting wave with its project, age and report.
Read only: write nothing to the bucket.
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`.

reports.bucket names an S3 or GCS bucket or an Azure Blob container, and terragucci writes under one prefix in it (reports.prefix, empty by default). A release adds keys and never moves one, so a program can rely on the layout below.

Key Written by What it is
<prefix>/index.json, index.html every upload every project’s runs, newest first
<prefix>/<project>/index.json, index.html every upload one project’s runs, newest first
<prefix>/<project>/inventory.json a tf-apply wave’s upload the resources each root holds, from its newest applied wave
<prefix>/<project>/changes.json a tf-apply wave’s upload what each applied wave did to each resource, newest first
<prefix>/<project>/migrations/<name>.json wave 1 of tf-apply, when it runs a state migration the migration’s record: each root’s state version and digest before and after, never a state’s contents
<prefix>/<project>/states.json a tf-apply wave’s upload the state version id each root’s applies left, newest first; never a state’s contents
<prefix>/<project>/edges.json an upload whose roots read another root’s state, or a tf-apply wave that changed a root each root’s reads, its newest plan and its newest apply that changed it; never a state’s contents
<prefix>/<project>/ephemeral.json the ephemeral job and the sweep, each time a pull request’s copy applies or is destroyed the live copies: each pull request’s roots and state keys, its commit, when it applied and when it expires (terragucci.ephemeral/v1, the rows of the estate’s projects[].ephemeral)
<prefix>/<project>/<yyyy>/<mm>/<commit>/<stage>[-wave-<n>]/ every upload one run’s report directory, below
<prefix>/<project>/runs/<commit>/run.json, run.html each tf-apply wave job the run view: every wave of the commit’s apply, its roots and what they read, where it stands, its blast radius and its timeline; terragucci estate reads it for the dependency graph
<prefix>/traces/<trace id>.html an upload whose run sent a trace a page that forwards to the run’s report.html
<prefix>/estate.json, estate.html terragucci estate every project’s latest plan, drift check and apply waves
<prefix>/history.json, history.html terragucci estate every resource address with each apply that changed it
<prefix>/dora.json terragucci estate the four DORA metrics per project and for the estate, week by week
<prefix>/audit.jsonl, audit.html, audit.json terragucci audit the audit trail, its page and its summary
<prefix>/views/ nothing kept for a viewer’s own files
Part Value
<project> the repo’s <host>/<path>, such as github.com/acme/infra, slashes included; a repo with no git remote is named after its directory
<yyyy>/<mm> the month the run finished, in UTC
<commit> the full SHA
<stage> tf-plan, tf-drift or tf-apply; a tf-apply directory ends in -wave-<n>
File What it is
report.json the report, terragucci.report/v1; see Report JSON schema
report.html the report as a page, with report.json inline
note.md the pull request note
summary.txt the grouped plan as text
gitlab-terraform.json GitLab’s reports:terraform counts
roots/<root>/plan.txt, roots/<root>/plan.json each root’s full plan, and its JSON with sensitive values redacted
roots/<root>/cost.json the estimator’s output, with cost set
intent.json the description check’s decision, after respond description

Links inside a run’s files are relative, so they resolve wherever the bucket is served. A row’s path in an index.json is relative to that index.

Each object a program reads names its schema in its schema field. The package’s dist/ directory ships the matching JSON Schema:

Object schema JSON Schema
report.json terragucci.report/v1 dist/report.schema.json, also exported as @intentius/terragucci/report.schema.json
index.json terragucci.report-index/v1 dist/report-index.schema.json
estate.json terragucci.estate/v1 dist/estate.schema.json
each line of audit.jsonl terragucci.audit/v1 dist/audit.schema.json
inventory.json terragucci.inventory/v1 dist/inventory.schema.json
changes.json terragucci.changes/v1 dist/changes.schema.json
history.json terragucci.history/v1 dist/history.schema.json
states.json terragucci.state-versions/v1 dist/state-versions.schema.json
edges.json terragucci.state-edges/v1 dist/state-edges.schema.json
dora.json terragucci.dora/v1 dist/dora.schema.json
run.json terragucci.run/v1 dist/run.schema.json

Within v1 a release only adds fields, and an existing field keeps its meaning. A reader checks schema and ignores fields it does not know. The schemas leave objects open, so a validator accepts a field a later release added.

Terminal window
npm pack @intentius/terragucci
tar -xzf intentius-terragucci-*.tgz package/dist/estate.schema.json

Report JSON schema lists the fields of index.json, estate.json, inventory.json, changes.json, history.json, states.json and edges.json, Delivery metrics the fields of dora.json, and The audit trail the fields of an audit entry.

terragucci never writes or reads under <prefix>/views/. A tool that renders your reports, such as a static page built in a scheduled job, writes its files under <prefix>/views/<tool>/. An upload whose project name would start with views is refused before anything is written; give the repo a git remote.

Whatever serves the bucket serves views/ too. A presigned link opens one object, and the front door serves every key under the prefix to whoever your identity provider signs in.

To read An identity needs
every project’s runs and the estate GetObject on <prefix>/*index.json and <prefix>/estate.json
every project’s resources GetObject on <prefix>/*inventory.json
every root’s state versions GetObject on <prefix>/*states.json
every root’s cross-state edges GetObject on <prefix>/*edges.json
every live ephemeral environment GetObject on <prefix>/*ephemeral.json
every resource’s history GetObject on <prefix>/history.json, or on <prefix>/*changes.json for the rows without approvers
a run’s report GetObject on <prefix>/*/report.json
the audit trail GetObject on <prefix>/audit.jsonl
the delivery metrics GetObject on <prefix>/dora.json

A reader needs no list permission: an index row names each run’s directory, and the report names each root’s plan files.

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.