Core estates clear and all estates clear, read from artifacts the test suite writes, are the headline: the answer to whether choudoufu works across real-world configurations, which is the question a customer is asking. An estate is a real OpenTofu or Terraform configuration, pinned by commit, run through every active stage below side by side with stock OpenTofu against the pinned emulator. It is clear when every headline stage passes - an active stage not marked “no” in the Headline column below. A stage marked “tier-1 gated” activates on a fast fixture rather than on per-estate sections (#999): an estate that has never run it stays clear, but a genuine fail on it still breaks clear.
Estates below were last measured against different emulator pins: 26 against ghcr.io/lex00/floci@sha256:a39185cc3971d0188663d61043cb038dff1260d8a975b1aa72c4e2bb1feac3cb, 1 against ghcr.io/lex00/floci@sha256:d9207de14c919f4bfa50e956376cc441970f3679aabfdd43f3dbf4b779b20805 (current pin) (last_run.date ranges from 2026-09-08T22:17:50Z to 2026-09-09T01:54:39Z across these rows, not one shared measurement). The current pin is ghcr.io/lex00/floci@sha256:d9207de14c919f4bfa50e956376cc441970f3679aabfdd43f3dbf4b779b20805; a row not measured against it is stale evidence, not a failure - go run ./tools/gauntlet next surfaces it as work.
The behaviors-proven line above counts how many of the 14 stages below have
a FAST tier-1 fixture (live/behaviors.json) - a small, purpose-built script
that runs in minutes rather than an estate’s own hours - whose representative
set (a real count block, a real for_each map, a module-nested case, and,
for a stage touching identity resolution, one fixture per identity kind)
all pass. A stage with no tier-1 fixture is not unproven - it is proven
by the estates above, just slowly; this number says only how many stages
have a fast signal for contributors.
The stages#
| Stage | Status | Headline | What a pass proves | |
|---|---|---|---|---|
| 1 | Cold deploy | active | yes | The estate is real and buildable: the stock binary applies the unmodified configuration against the emulator, with no live block and no choudoufu involved. |
| 2 | Migrate | active | yes | choudoufu live-import -approve against the stock state file binds every instance: each state entry becomes a marker on the resource, a record, or an identity derived from the declaration, and the summary line reports zero skipped. |
| 3 | Replan from nothing | active | yes | With the state file deleted, choudoufu live-plan is empty, and a representative set of rendered identities equals what the AWS CLI reports for the same objects. |
| 4 | No-op apply | active | yes | Applying the empty plan changes nothing: the estate’s tagged-object count before and after is identical. |
| 5 | Drift and reconverge | active | yes | One live object is mutated out of band through the AWS CLI; the next plan proposes fixing exactly that object and nothing else, and apply reconverges it. |
| 6 | Rename | active | yes | Renaming a resource through a moved block and through choudoufu live-mv both produce zero churn: no destroy, no create, the marker rewritten in place. |
| 7 | Remove a block | active | yes | Deleting a resource block destroys the object under the default policy, in an order the cloud accepts, including blocks for untaggable children whose parents stay. |
| 8 | Change count | active | yes | Scaling a count block down and back up destroys and creates only the instances stock would, and every surviving instance keeps its identity. |
| 9 | Replace with create_before_destroy | active | yes | A forced replacement under create_before_destroy creates the new object, destroys the old one, and the next plan is empty with no marker collision. |
| 10 | Crash between create and destroy | active | yes (tier-1 gated) | A replace interrupted after the create and before the destroy is recovered by the next plan without a human: the old object is destroyed, the new one is bound. |
| 11 | Teardown | active | yes (tier-1 gated) | choudoufu apply -destroy removes every object the estate owns in one apply, in an order the cloud accepts, and leaves nothing marked. |
| 12 | Plan, review, apply | active | yes | plan -out followed by apply <planfile> applies when the world has not moved and refuses, naming the mismatch, when it has. |
| 13 | Greenfield apply | active | yes | Applying the same configuration from an empty account with choudoufu directly, no migration, produces the same objects stock’s cold deploy produced, plus markers. |
| 14 | Strict profile | active | no | With every strict toggle on, the estate is refused for exactly the things the toggles name (secrets stored, markers unrepaired, and so on) with the documented message, and for nothing else. |
Planned stages are listed so the target is visible. They do not count toward
clear until they are activated, and, for a headline stage, activating one
lowers the bars until the estates catch up - a non-headline stage can be
active, and measured per estate, without moving either bar. The full
definition of every stage, including what stock’s
answer is and how each check is proven non-vacuous, is
live/GAUNTLET.md.
The estates#
| Estate | Set | Lane | Clear | Stages |
|---|---|---|---|---|
| corpus-alb-complete | core | terraform-popular | yes | pass pass pass pass pass pass pass pass pass not run not run pass pass not run |
| corpus-autoscaling-complete | core | terraform-popular | yes | pass pass pass pass pass pass pass pass pass not run not run pass pass not run |
| corpus-dynamodb-table-basic | core | terraform-popular | yes | pass pass pass pass pass pass pass pass pass not run not run pass pass not run |
| corpus-ec2-instance-complete | core | terraform-popular | yes | pass pass pass pass pass pass pass pass pass not run not run pass pass not run |
| corpus-ecs-fargate | core | terraform-popular | yes | pass pass pass pass pass pass pass pass pass not run not run pass pass not run |
| corpus-eks-basic | core | terraform-popular | yes | pass pass pass pass pass pass pass pass pass not run not run pass pass not run |
| corpus-evoteum-modules | core | opentofu-native | yes | pass pass pass pass pass pass pass pass pass not run not run pass pass not run |
| corpus-giantswarm-crossplane | core | opentofu-native | yes | pass pass pass pass pass pass pass pass pass not run not run pass pass not run |
| corpus-hongbomiao-harbor | core | opentofu-native | yes | pass pass pass pass pass pass pass pass pass not run not run pass pass not run |
| corpus-hongbomiao-labelbox | core | opentofu-native | yes | pass pass pass pass pass pass pass pass pass not run not run pass pass not run |
| corpus-hongbomiao-storage | core | opentofu-native | yes | pass pass pass pass pass pass pass pass pass not run not run pass pass not run |
| corpus-iam-policy | core | terraform-popular | yes | pass pass pass pass pass pass pass pass pass not run not run pass pass not run |
| corpus-iam-read-only-policy | core | terraform-popular | yes | pass pass pass pass pass pass pass pass pass not run not run pass pass not run |
| corpus-lambda-simple | core | terraform-popular | yes | pass pass pass pass pass pass pass pass pass not run not run pass pass not run |
| corpus-leynos-monitoring | core | opentofu-native | yes | pass pass pass pass pass pass pass pass pass not run not run pass pass not run |
| corpus-overture-tiles | core | opentofu-native | yes | pass pass pass pass pass pass pass pass pass not run not run pass pass not run |
| corpus-rds-complete-postgres | core | terraform-popular | yes | pass pass pass pass pass pass pass pass pass not run not run pass pass not run |
| corpus-s3-bucket-complete | core | terraform-popular | yes | pass pass pass pass pass pass pass pass pass not run not run pass pass not run |
| corpus-security-group-complete | core | terraform-popular | yes | pass pass pass pass pass pass pass pass pass not run not run pass pass not run |
| corpus-simpleinfra-dns | core | terraform-popular | yes | pass pass pass pass pass pass pass pass pass not run not run pass pass not run |
| corpus-sqs-basic | core | terraform-popular | yes | pass pass pass pass pass pass pass pass pass not run not run pass pass not run |
| corpus-sumaform-aws | core | opentofu-native | yes | pass pass pass pass pass pass pass pass pass not run not run pass pass not run |
| corpus-vpc-complete | core | terraform-popular | yes | pass pass pass pass pass pass pass pass pass not run not run pass pass not run |
| corpus-xancloud-iac | core | opentofu-native | yes | pass pass pass pass pass pass pass pass pass not run not run pass pass not run |
| reference-ec2-vpc | core | reference | yes | pass pass pass pass pass pass pass pass pass pass not run pass pass pass |
| terralith-scale | core | reference | yes | pass pass pass pass pass pass pass pass pass not run not run pass pass not run |
| corpus-mastino-dns | growing | published-deployment | yes | pass pass pass pass pass pass pass pass pass not run not run pass pass not run |
Run time#
27 of 27 estates have a recorded run duration, totaling 2h43m55.7s, but not from one sweep: 7m15.2s across 1 estate(s) at commit 0a3d554c04; 2h36m40.5s across 26 estate(s) at commit 933618dec4. This total spans different commits, not a single board run, and excludes 0 estate(s) with no recorded duration yet.
| Estate | Total | Per-stage (active stages, seconds recorded this run) |
|---|---|---|
| corpus-alb-complete | 7m15.2s | cold_deploy 1m26s, migrate 1m7s, test_plan 4s, test_apply 5s, drift_reconverge 39s, day2_rename 16s, day2_remove 22s, day2_count 47s, day2_replace 33s, plan_approval 22s, greenfield 1m34s |
| corpus-autoscaling-complete | 6m57s | cold_deploy 1m32s, migrate 1m16s, test_plan 4s, test_apply 5s, drift_reconverge 9s, day2_rename 17s, day2_remove 14s, day2_count 56s, day2_replace 18s, plan_approval 21s, greenfield 1m44s |
| corpus-dynamodb-table-basic | 4m0s | cold_deploy 22s, migrate 1m28s, test_plan 2s, test_apply 3s, drift_reconverge 6s, day2_rename 11s, day2_remove 6s, day2_count 31s, day2_replace 13s, plan_approval 12s, greenfield 46s |
| corpus-ec2-instance-complete | 6m39.2s | cold_deploy 55s, migrate 31s, test_plan 5s, test_apply 3s, drift_reconverge 7s, day2_rename 15s, day2_remove 29s, day2_count 2m9s, day2_replace 49s, plan_approval 16s, greenfield 1m0s |
| corpus-ecs-fargate | 9m27.4s | cold_deploy 1m27s, migrate 1m27s, test_plan 29s, test_apply 6s, drift_reconverge 11s, day2_rename 52s, day2_remove 16s, day2_count 1m5s, day2_replace 17s, plan_approval 28s, greenfield 2m49s |
| corpus-eks-basic | 15m27.2s | cold_deploy 1m22s, migrate 1m29s, test_plan 18s, test_apply 20s, drift_reconverge 41s, day2_rename 1m18s, day2_remove 1m1s, day2_count 3m47s, day2_replace 1m1s, plan_approval 1m43s, greenfield 2m25s |
| corpus-evoteum-modules | 2m26.1s | cold_deploy 13s, migrate 42s, test_plan 3s, test_apply 3s, drift_reconverge 5s, day2_rename 10s, day2_remove 7s, day2_count 13s, day2_replace 13s, plan_approval 12s, greenfield 25s |
| corpus-giantswarm-crossplane | 2m3.7s | cold_deploy 5s, migrate 23s, test_plan 3s, test_apply 2s, drift_reconverge 5s, day2_rename 10s, day2_remove 5s, day2_count 40s, day2_replace 7s, plan_approval 11s, greenfield 12s |
| corpus-hongbomiao-harbor | 3m11.2s | cold_deploy 15s, migrate 14s, test_plan 2s, test_apply 3s, drift_reconverge 5s, day2_rename 9s, day2_remove 7s, day2_count 46s, day2_replace 7s, plan_approval 12s, greenfield 1m11s |
| corpus-hongbomiao-labelbox | 3m2.6s | cold_deploy 16s, migrate 38s, test_plan 3s, test_apply 4s, drift_reconverge 6s, day2_rename 11s, day2_remove 8s, day2_count 25s, day2_replace 8s, plan_approval 15s, greenfield 49s |
| corpus-hongbomiao-storage | 3m31.2s | cold_deploy 20s, migrate 42s, test_plan 3s, test_apply 3s, drift_reconverge 6s, day2_rename 14s, day2_remove 7s, day2_count 24s, day2_replace 13s, plan_approval 15s, greenfield 1m4s |
| corpus-iam-policy | 2m54.7s | cold_deploy 16s, migrate 17s, test_plan 2s, test_apply 3s, drift_reconverge 5s, day2_rename 9s, day2_remove 8s, day2_count 41s, day2_replace 7s, plan_approval 12s, greenfield 54s |
| corpus-iam-read-only-policy | 3m4.6s | cold_deploy 15s, migrate 1m4s, test_plan 2s, test_apply 3s, drift_reconverge 5s, day2_rename 10s, day2_remove 7s, day2_count 19s, day2_replace 7s, plan_approval 19s, greenfield 33s |
| corpus-lambda-simple | 2m54.9s | cold_deploy 13s, migrate 14s, test_plan 2s, test_apply 5s, drift_reconverge 19s, day2_rename 25s, day2_remove 12s, day2_count 27s, day2_replace 18s, plan_approval 14s, greenfield 25s |
| corpus-leynos-monitoring | 1m29.6s | cold_deploy 6s, migrate 24s, test_plan 2s, test_apply 2s, drift_reconverge 4s, day2_rename 6s, day2_remove 5s, day2_count 15s, day2_replace 5s, plan_approval 9s, greenfield 11s |
| corpus-overture-tiles | 7m6.3s | cold_deploy 55s, migrate 1m9s, test_plan 9s, test_apply 3s, drift_reconverge 7s, day2_rename 47s, day2_remove 52s, day2_count 47s, day2_replace 7s, plan_approval 12s, greenfield 1m57s |
| corpus-rds-complete-postgres | 12m2.7s | cold_deploy 1m45s, migrate 45s, test_plan 8s, test_apply 4s, drift_reconverge 8s, day2_rename 16s, day2_remove 1m30s, day2_count 52s, day2_replace 2m51s, plan_approval 20s, greenfield 3m22s |
| corpus-s3-bucket-complete | 8m34.6s | cold_deploy 1m14s, migrate 1m26s, test_plan 4s, test_apply 11s, drift_reconverge 20s, day2_rename 23s, day2_remove 19s, day2_count 56s, day2_replace 20s, plan_approval 34s, greenfield 2m47s |
| corpus-security-group-complete | 3m42.9s | cold_deploy 22s, migrate 1m16s, test_plan 4s, test_apply 4s, drift_reconverge 7s, day2_rename 14s, day2_remove 11s, day2_count 28s, day2_replace 11s, plan_approval 18s, greenfield 27s |
| corpus-simpleinfra-dns | 8m22.1s | cold_deploy 1m9s, migrate 39s, test_plan 6s, test_apply 12s, drift_reconverge 22s, day2_rename 16s, day2_remove 25s, day2_count 51s, day2_replace 1m8s, plan_approval 44s, greenfield 2m30s |
| corpus-sqs-basic | 10m36.6s | cold_deploy 56s, migrate 2m1s, test_plan 3s, test_apply 3s, drift_reconverge 5s, day2_rename 9s, day2_remove 49s, day2_count 1m55s, day2_replace 1m15s, plan_approval 14s, greenfield 3m6s |
| corpus-sumaform-aws | 10m29.1s | cold_deploy 1m13s, migrate 3m12s, test_plan 12s, test_apply 11s, drift_reconverge 21s, day2_rename 41s, day2_remove 23s, day2_count 2m8s, day2_replace 1m13s, plan_approval 54s, greenfield 2m21s |
| corpus-vpc-complete | 4m52.8s | cold_deploy 25s, migrate 1m29s, test_plan 4s, test_apply 3s, drift_reconverge 7s, day2_rename 14s, day2_remove 20s, day2_count 1m34s, day2_replace 20s, plan_approval 17s, greenfield 52s |
| corpus-xancloud-iac | 3m33.4s | cold_deploy 31s, migrate 52s, test_plan 3s, test_apply 3s, drift_reconverge 7s, day2_rename 10s, day2_remove 18s, day2_count 29s, day2_replace 8s, plan_approval 15s, greenfield 37s |
| reference-ec2-vpc | 4m21.7s | cold_deploy 1m29s, migrate 54s, test_plan 2s, test_apply 2s, drift_reconverge 5s, day2_rename 8s, day2_remove 6s, day2_count 17s, day2_replace 26s, day2_crash 35s, plan_approval 12s, greenfield 4s, strict 1s |
| terralith-scale | 5m35.4s | cold_deploy 2m5s, migrate 40s, test_plan 4s, test_apply 5s, drift_reconverge 33s, day2_rename 19s, day2_remove 7s, day2_count 17s, day2_replace 12s, plan_approval 12s, greenfield 1m1s, strict - |
| corpus-mastino-dns | 10m13.5s | cold_deploy 1m56s, migrate 43s, test_plan 5s, test_apply 8s, drift_reconverge 27s, day2_rename 19s, day2_remove 30s, day2_count 58s, day2_replace 46s, plan_approval 28s, greenfield 3m53s |
Live-AWS certification#
Separate from the two bars above, and never counted toward either of them: a real-AWS run for the named estate, at the date and account below, is evidence about ONE run against a real account, not a repeatable comparison against stock the way an emulator row is. See HANDOFF.md “What a measurement is worth” for why the two are never averaged together.
| Estate | Target | Region | Clear | Date | Ceiling |
|---|---|---|---|---|---|
| reference-ec2-vpc | aws | us-east-2 | yes | 2026-09-08T01:17:12Z | $5.00 |
| terralith-scale | aws | us-east-2 | yes | 2026-08-31T03:20:33Z | $15.00 |
To add an estate, see Add an estate.