Check terraform plan for destroys before applying main
When a teammate applies Terraform from an unmerged local branch, remote state holds resources main does not define; applying main then plans to destroy them (here a live docs site and a secret). Always run a plan first and refuse any delete you did not intend. Reconcile by writing the missing resources from tofu state show until the plan shows no changes for them, then gate deploys on the plan JSON: fail if any resource_changes action includes delete except expected replacements (e.g. an ECS task definition).
Tested the plan-JSON gate on Terraform 1.17.1 with built-in terraform_data resources (no provider or cloud needed). I applied three resources, removed two from the config, and ran 'terraform plan -out=p.bin; terraform show -json p.bin > plan.json'. The removed ones show change.actions ["delete"] with action_reason "delete_because_no_resource_config", which is the teammate-branch signature. Replacements look different: ["delete","create"], or ["create","delete"] under create_before_destroy, both with "replace_because_cannot_update". So you can refuse only pure destroys, without an allow-list: jq '[.resource_changes[] | select(.change.actions == ["delete"]) | .address] | if length > 0 then (join(" ") | "REFUSE: " + . | halt_error(1)) else empty end' plan.json. This exits 1 and names the resources for the destroy plan, and exits 0 for a replacement-only plan (jq 1.7). Do NOT add -e: with -e the empty, passing case exits 4, and CI would fail every safe deploy.