XanCloud/xancloud-iac, blueprints/landing-zone-basic (an AWS landing-zone accelerator: VPC + CloudTrail + account-level IAM baseline), pinned by tag v0.2.0 and commit 7bc78ff79df4f914921cf04fd9728d09526c93bd

Source: https://github.com/XanCloud/xancloud-iac.git at v0.2.0.

Set: core. Lane: opentofu-native.

Why it is in the core set: a real project built for OpenTofu specifically, so OpenTofu-only surface is exercised

Clear. Every headline stage passes.

StageVerdictDurationDetail
Cold deploypass31s28 resources, genuinely cold, genuinely unmarked
Migratepass52slive-import -approve completed cleanly against the cold state
Replan from nothingpass3sno resource change proposed
No-op applypass3sgenuine no-op (0 added, 0 changed, 0 destroyed); tofu-estate-tagged object count unchanged at 21
Drift and reconvergepass7sone object tampered (Name tag), exactly module.vpc.aws_vpc.this[“main”] proposed by both choudoufu and stock with the identical change, apply changed 1 and the Name tag reads back as configured
Renamepass10smoved block: aws_iam_role.flow_logs renamed with zero churn (0 add, 1 change, 0 destroy), marker rewritten in place; live-mv: aws_eip.nat renamed with zero churn, marker rewritten in place; stock oracle over the same two-object rename on cold_deploy’s own state also shows zero churn (0 add, 0 change, 0 destroy); both live ids unchanged, read via the AWS CLI
Remove a blockpass18schoudoufu: deleting aws_vpc_endpoint.s3’s block (the S3 gateway endpoint, a standalone leaf nothing else in the module references) proposed exactly one destroy (0 add, 0 change, 1 destroy), applied cleanly (0 added, 0 changed, 1 destroyed), the endpoint is genuinely gone from the live account (describe-vpc-endpoints on the old id reports State=deleted or nothing at all, read via the AWS CLI, not choudoufu’s own report), and the next plan is empty; the E-ORACLE stock oracle (on cold_deploy’s own state, before any tag was ever written) also proposes exactly one destroy for the same object; classifyOrphans did not withhold the destroy because no other aws_vpc_endpoint.s3 block is declared anywhere in this config
Change countpass29schoudoufu: dropping “logs” from var.vpcs.main.vpc_endpoints destroyed exactly module.vpc.aws_vpc_endpoint.interface[“main-logs”] (0 add, 0 change, 1 destroy), leaving every sibling for_each member (main-ssm’s live id and tofu-address marker checked directly) untouched; adding it back created exactly the same key under a NEW live id (0 add -> 1 add, 0 change, 0 destroy) while main-ssm stayed untouched throughout; the next plan is empty; the F-ORACLE stock oracle on the identical for_each set, applied on cold_deploy’s own state, shows the identical shape: destroy the dropped key only, create it back under a new id, every sibling key’s id unchanged both times
Replace with create_before_destroypass8schoudoufu: changing module.vpc.aws_iam_role.flow_logs_renamed’s ForceNew name argument proposed a forced replace at the same declared address (Plan: 3 to add, 0 to change, 3 to destroy., cascading into the flow log’s iam_role_arn and the inline role policy, both keyed to the role at creation time with no update path), applied cleanly; the old role is confirmed gone via the AWS CLI (NoSuchEntity) and the new role (xancloud-dev-main-flow-logs-role-v2) carries the marker; the local record store’s record at the same address now names the new object’s name, not the destroyed one (xancloud-dev-main-flow-logs-role -> xancloud-dev-main-flow-logs-role-v2); the next plan proposes no resource action; stock oracle on cold_deploy’s own state (REPLACE-ORACLE) also proposes replacing the role at the same address (Plan: 3 to add, 0 to change, 3 to destroy., plan only, not applied - it shares floci’s account with $ESTATE); BREAK=replace confirms a manufactured marker collision is reported loudly (“Two live resources claiming one slot”) rather than silently proposed as nothing. Scope note: this exercises OpenTofu’s default destroy-then-create ordering, not the create_before_destroy variant the stage’s Title names - see this section’s own header comment.
Crash between create and destroynot run
Teardownnot run
Plan, review, applypass15sone argument edited (module.vpc.aws_default_security_group.this[“main”]’s tags gain Reviewed=yes - a single for_each instance nothing else in the module references), “plan -out=approved.tfplan” wrote a 38413-byte stock-format plan file whose whole change set is one update on module.vpc.aws_default_security_group.this[“main”]; the world then moved out of band (vpc-18308830’s Name tag, through the AWS CLI, never through choudoufu) and “apply approved.tfplan” refused with “The approved plan no longer matches the live system” at exit 3, classifying the drift under “This apply would do, and the approved plan does not include:” and naming both module.vpc.aws_vpc.this[“main”] and the live vpc-18308830 it was computed against, with “Exit status 3” spelled out for a pipeline; nothing was applied - sg-ccb1df730bbb514fb still carried no Reviewed tag, read back through the AWS CLI rather than from the absence of an “Apply complete!” line. Inverted control on the same run (the shape live/smoke/scenarios/apply-what-was-approved.sh reasons out): with the tag put back and nothing else changed, the IDENTICAL file applied - 0 added, 1 changed, 0 destroyed - and sg-ccb1df730bbb514fb read back with Reviewed=yes, so the refusal is earned by the drift and not handed out to every plan file. BREAK_APPROVAL=1 asserts stage 12’s own recorded Break line (apply the planfile after a mutation and expect success) and correctly fails
Greenfield applypass37s28 resources from nothing (matching stage 1’s stock cold-deploy count exactly), all markers verified via the AWS CLI, 28 records in the local record store (#364 A2), replan empty, object-by-object comparison against stock’s still-pristine cold deploy on $ENDPOINT matches on tagged-object count (21), VPC CIDR, subnet/NAT-gateway/VPC-endpoint counts and account alias
Strict profile (not a headline stage)not run

Last run at commit 933618dec4 on 2026-09-08T22:17:50Z, exit code 0, against emulator image ghcr.io/lex00/floci@sha256:a39185cc3971d0188663d61043cb038dff1260d8a975b1aa72c4e2bb1feac3cb. Stale: the current pin is ghcr.io/lex00/floci@sha256:d9207de14c919f4bfa50e956376cc441970f3679aabfdd43f3dbf4b779b20805. Total run time 3m33.4s. Oracle: stock terraform 1.16.1, stock tofu 1.12.6 (matches the current pin).

Landed 2026-08-19, the fifth OpenTofu-native estate. Genuinely different from every prior crossing in this lane. OpenTofu-native evidence: README/badges state “OpenTofu-first … native state encryption, S3 locking without DynamoDB, no vendor lock-in”, required_version >= 1.11.0, and docs/TROUBLESHOOTING.md carries a dedicated real-usage “OpenTofu general” section (tofu init -upgrade) rather than just a badge - weaker than corpus-hongbomiao’s genuine .tofu files (this ships plain .tf), comparable to sumaform/overture-tiles. Several other candidates evaluated and rejected first (an account-singleton-heavy 0-star repo, a devtool’s test fixture masquerading as an estate, multiple 0-1-star scaffolds). cold_deploy genuinely passes (28 resources, plain tofu apply, unmodified). migrate genuinely passes: live-import 22 of 28 eligible (21 VERIFIED, 1 DRIFTED), -approve 22 newly stamped, 6 correctly UNTAGGABLE, 0 failed. test_plan BLOCKED, deterministically asserted (Plan: 2 to add, 3 to change, 1 to destroy, all 5 addresses traced to three independent, filed, evidence-backed gaps, not routed around); the VPC’s own marker re-verified directly against the AWS CLI after state deletion, BREAK=1 confirmed load-bearing. Six real floci gaps filed with full evidence: lex00/floci#73 (S3Control PutPublicAccessBlock unimplemented), #74 (IAM UpdateAccountPasswordPolicy unsupported), #75 (IAM Access Analyzer - whole missing service), #76 (EC2 ModifyInstanceMetadataDefaults unsupported), #77 (CloudTrail tagging trio missing, blocks any tagged aws_cloudtrail), #78 (EC2 CreateFlowLogs ignores TagSpecifications) - none fixed, per this session’s standing instruction. Two choudoufu gaps filed: INTENTIUS/choudoufu#327 (aws_nat_gateway’s ForceNew args read null from a stateless prior, forcing a spurious replace), #328 (aws_default_security_group.revoke_rules_on_delete, write-only with no live representation, always diffs) - not fixed. A REAL BUG found and fixed along the way, outside this task’s own estate work: #325’s marker-alias fix (merged just before this crossing started) double-counted a live object when an estate declares BOTH sides of a default-adopter pair (this module does, aws_default_security_group next to an unrelated aws_security_group) - both scanType passes appended an identical claimant, producing a false “Two live resources claiming one address” collision on a single real object (confirmed via direct AWS CLI query). Fixed with claimantAlreadyPresent (dedupe by import ID), covered by a new regression test reproducing the exact real-world error text before the fix and passing after. Stages 4-5 not attempted - both need a genuinely empty first plan. Merged to local main as 62e63a3eb5 (crossing: 427977009a, the discovery double-count fix: 3bdceb43e3); rebased onto a concurrent sibling’s internal/live/identity work mid-session, one conflict (the generated identity-golden.txt) resolved by regenerating, not hand-merging; justfile gained recipe demo-corpus-xancloud-iac; live/corpus-manifest.json gained the pin. Re-verified 2026-08-19 after #327’s fix (56e807062e/b5bb09d27e, generic - reuses #275’s existing residueCandidates/ResidueStore mechanism unchanged, adding one new call site: live-import’s Approve now records residue for every eligible instance using the migrated state’s own real prior value, not #327-specific): plan moved from 2 to add/3 to change/1 to destroy down to 1 to add/1 to change/0 to destroy - aws_nat_gateway.this[“main-0”] no longer proposes a spurious replace. Remaining test_plan blockers are exactly the still-unfixed floci gaps (#73-#78, S3Control/IAM password policy/IAM Access Analyzer/EC2 metadata defaults/CloudTrail tagging/EC2 flow logs), not a choudoufu-side gap. A residual, lower-severity, choudoufu-specific diff on regional_nat_gateway_address (pure-Computed set(object), harmless) remains and was deliberately not filed - residueCandidates correctly excludes pure-Computed attributes, and broadening that needs its own corpus-wide validation before it’s safe (risk: masking real out-of-band drift). Follow-up pass 2026-08-20 (this session): #73/#74/#75 fixed and closed (lex00/floci commits 51c00478/08d92407/be3f7ffd - S3 account-level PutPublicAccessBlock, IAM UpdateAccountPasswordPolicy, AccessAnalyzer as a whole new service), joining #76/#77/#78 which other concurrent sessions closed the same night (all six of the floci gaps this estate originally filed are now closed). Re-pinned floci-image to be3f7ffd (sha256:8a882bcc, CI+GHCR-publish both green) and regenerated floci-capabilities.json (verified additive: one digest block added, none removed, no existing block changed). Re-crossed for real against the new pin, the script AS COMMITTED (still setting TF_VAR_cloudtrail_enabled=false and the three iam_baseline_enable_* toggles off, so the five originally-toggled-off features are not re-exercised by this run - re-enabling them is separate, larger follow-up work, not attempted here). Real result: stage 1 PASS (28 resources, unchanged); stage 2 PASS (22 stamped: 21 VERIFIED + 1 DRIFTED, 6 UNTAGGABLE, 0 failed - unchanged from before); stage 3 still FAILS the script’s own hard-coded assertion (which expects the stale ‘Plan: 2 to add, 3 to change, 1 to destroy.’ shape from before tonight’s floci fixes), but the REAL diagnostic surface changed: only two addresses appear in the plan now, not five - ‘module.vpc.aws_nat_gateway.this[“main-0”] will be updated in-place’ (the pre-existing, previously-noted harmless regional_nat_gateway_address residual, #327 itself still holding - no force-replace) and, newly, ‘module.vpc.aws_flow_log.cloudwatch[“main”] must be replaced’ - a force-replace that could not appear before tonight because the flow log was never migrated at all (floci#78 blocked its tag write, so live-import never had a marker to find). This is very likely the same #327-shaped bug class (a ForceNew argument reading null from a stateless prior) now hitting aws_flow_log instead of aws_nat_gateway, not yet diagnosed or filed as its own issue - flagged here rather than assumed. A second confirmatory run was attempted to capture the exact ‘Plan: N to add, M to change, K to destroy’ totals line and pin down the flow_log diff further, but was lost to a session interruption before completing; the two-address finding above is from one complete, real, natural-exit run and was not re-confirmed a second time this session. The script’s own hard-coded assertion (both the exact-string check and the per-address list) is now stale relative to the pin and needs updating by whoever picks this back up, once the flow_log diff is diagnosed. Stages 4-5 remain not_run (unchanged - both need a genuinely empty first plan, which this has not yet reached). RESOLVED as #347 (2026-08-20, 2cb473affd/27cafb1650): the flow_log diff was diagnosed - iam_role_arn (ForceNew) reads null on the stateless prior because floci’s own FlowLogService never learns or emits it at all (Ec2QueryHandler.handleCreateFlowLogs ignores DeliverLogsPermissionArn; handleDescribeFlowLogs never returns it), confirmed via TF_LOG=trace straight through Ratification.Approve’s residue classification (#327’s residueCandidates/ResidueStore mechanism correctly DECLINES to record it, since both classification reads come back empty on any prior, not just the stateless one - the opposite of #327’s shape, where the provider preserves without truly reading). Confirmed parity label 1, “OpenTofu fails here too”: the PLAIN cold-deploy state (written by a real, non-choudoufu tofu apply) already carries iam_role_arn="" immediately after apply, so a stock stateful tofu plan would show the identical perpetual diff. Filed as lex00/floci#87 (open, emulator gap, not a choudoufu defect). run.sh’s stage-3 assertions were updated to match reality: 2 addresses (aws_flow_log.cloudwatch[“main”] must be replaced; aws_nat_gateway.this[“main-0”] will be updated in-place, #327’s own still-harmless residual) and “Plan: 1 to add, 1 to change, 1 to destroy.” RE-VERIFIED 2026-08-21 (this session, worktree live/reverify-limitations, floci pinned at the current e61a987/d65baf42 image): real re-run of run.sh, exit 0, every hard-coded assertion passed byte-for-byte against the #347 shape above - same 2 addresses, same summary line, same 28/22/21+1/6/0 stage 1-2 counts. lex00/floci#87 confirmed still OPEN (not narrowed by the e61a987 re-pin, which addressed #86/#88 only). None of tonight’s #331/#337/#340/#343/#344 admission/identity/record-store changes touched this estate. Wall unchanged; stages 4-5 remain not_run. UPDATE 2026-08-21 (lex00/floci#87 FIXED via lex00/floci#96, PR squash-merged as 17c7f7ef, published sha256:cdd50ec04a1a13461035657bdd9ec2ed377ac48925e76495a73c9674b5cbd9f9, verified via the GHCR packages API and docker buildx imagetools inspect on both the :17c7f7e and :latest tags): CreateFlowLogs/DescribeFlowLogs now carry DeliverLogsPermissionArn. Re-pinned floci-image to this digest and regenerated floci-capabilities.json (verified additive: one digest block added - 87 services, 747 type rows, matching every prior digest’s shape - none removed, no existing block changed). Re-crossed for real against the new pin: stage 1 PASS (28 resources, unchanged); stage 2 PASS (22 stamped: 21 VERIFIED + 1 DRIFTED, 6 UNTAGGABLE, 0 failed - unchanged from before). Stage 3 (test_plan) genuinely changed shape: aws_flow_log.cloudwatch[“main”] no longer appears anywhere in the plan - the force-replace lex00/floci#87 caused is gone. The plan is narrower but NOT empty: ‘Plan: 0 to add, 1 to change, 0 to destroy.’, the sole remaining address module.vpc.aws_nat_gateway.this[“main-0”] will be updated in-place - the same pre-existing, harmless #327 regional_nat_gateway_address residual this estate has carried since before #87 was ever diagnosed. run.sh’s stage-3 header and assertions rewritten to match this reality (single-address plan, exact ‘Plan: 0 to add, 1 to change, 0 to destroy.’ string, an explicit assertion that aws_flow_log no longer appears), re-run clean end to end (exit 0, no FAIL), and BREAK=1 re-confirmed load-bearing (the VPC identity check fails exactly as designed against a wrong expected address). test_plan stays ‘fail’ by this repo’s own convention (a first plan must be empty to pass) - #327’s own NAT-gateway residual is the estate’s only remaining wall, unchanged in kind from before, just no longer sharing the plan with #87. Stages 4-5 remain not_run: both still need a genuinely empty first plan, which this estate has not yet reached. NOT a new estate at full parity - one wall cleared (lex00/floci#87), one wall (#327, already tracked, not this session’s to fix) remains. UNIT gauntlet:corpus-xancloud-iac/test_plan (2026-08-21, orchestrator-run worker): stage 3 (test_plan) is now PASS. Root cause traced and fixed generically, not scoped around: aws_nat_gateway.this[“main-0”] regional_nat_gateway_address (Computed only - this NAT gateway has connectivity_type=public, not “regional”, confirmed directly against floci’s own DescribeNatGateways response, which carries no such field for this object at all) was showing “+ regional_nat_gateway_address = (known after apply)” on every stateless first plan. internal/live/projection/residue.go’s residueCandidates and fillResidue used to refuse a purely-Computed attribute a residue candidacy at all (“it cannot be set in configuration, so there is nothing to remember”) - that reasoning undercounted a real case: the provider’s Read does not re-derive this attribute from a bare identity-only prior, it leaves whatever the prior held (null), and OpenTofu marks a null Computed attribute unknown forever. Fixed by dropping the Required/Optional restriction from both functions, keeping every other exclusion (identity, sensitive, write-only, NestedType) - safety comes from classifyResidue’s own two-read discriminator, not from that schema-shape filter. internal/live/projection/residue_test.go and internal/live/liveimport/residue_test.go updated to match (arn, Computed-only in the lambda-like fixture, is now a legitimate candidate; a new TestFillResidueFillsAComputedOnlyAttribute pins the positive case). Re-crossed for real: stage 1 PASS (28 resources, unchanged); stage 2 PASS (22 stamped, unchanged); stage 3 now PASS - “No changes. Your infrastructure matches the configuration.”, BREAK=1 re-confirmed load-bearing against the VPC identity check. Stages 4-5 remain not_run: not yet written, since stage 3 only just started passing in this run - a follow-up unit’s work, not attempted here.

Reproduce it#

go run ./tools/gauntlet run corpus-xancloud-iac

Needs Docker (the emulator is pulled at the pinned digest), the AWS CLI, and a stock terraform or tofu binary on PATH for the cold deploy. The script is live/e2e/corpus-xancloud-iac/run.sh; BREAK=1 corrupts its assertions to show they are load-bearing.