You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Prove bootstrap inventory before declarative adoption #35
Prove the current bootstrap inventory and its ownership before the first declarative migration.
Motivation
The connection and historical DNS recovery proofs do not establish the existing account configuration, independent state, or which records another controller manages. Importing without those facts risks conflicting writers and destructive changes.
Proposed Solution
Add a manually confirmed, main-only, first-attempt read-only workflow using a dedicated bootstrap reader from approved private custody. Bind the owned zone and account, collect complete DNS records, relevant bucket configuration and token policy metadata through fixed provider GET endpoints, and encrypt the bounded inventory to the existing infrastructure recovery recipient. Publish only ciphertext and closed result codes. Refuse incomplete pagination, duplicate or changed identities, unexpected responses and uncertain capabilities.
Classify the import set against the platform's declared writers before preparing a plan. Preserve ExternalDNS records and their registry entries, certificate challenge ownership, bucket data and existing token values. Current inventory is transient planning evidence; this does not add another permanent configuration backup.
Acceptance Criteria
Disabled or invalid dispatches make no provider call and do not read a credential; valid dispatches remain GET-only with fixed destinations and bounded responses.
Inventory completeness and binding controls reject partial, duplicate, changed, malformed and unauthorized responses without publishing a successful package.
Only authenticated ciphertext leaves private scratch; credentials, configuration and policies remain absent from logs.
A real confirmed main dispatch proves the available reads, or reports a closed unverified result without widening permissions.
The selected adoption set excludes existing controller-owned resources; import, state custody, no-destroy plan and human review still precede the first apply.
Part of #21. First migration remains under devantler-tech/monorepo#3274. No provider writes, token rotation or service cutover occur in this slice.
Check the box below or use the @coderabbitai plan command to generate an implementation plan and prompts that you can use with your favorite coding assistant.
Create Plan
🧪 Issue enrichment is currently in open beta.
You can configure auto-planning by selecting labels in the issue_enrichment configuration.
To disable automatic issue enrichment, add the following to your .coderabbit.yaml:
issue_enrichment:
auto_enrich:
enabled: false
💬 Have feedback or questions? Drop into our discord!
The diagnostic and its separate private reader binding are delivered through #36 and #37. Current main CI passed. The first confirmed account observation stopped safely without publishing an artifact or changing provider resources. A separate confirmed DNS snapshot succeeded and was recovered privately.
The private bootstrap handoff remains outstanding. Resume with a fresh confirmed main observation after that handoff, then finish the explicit adoption set. The first migration plan and apply remain unapproved. This card returns to Ready on that concrete prerequisite; it is not a completed migration or a verification parking lane.
The maintainer has answered the access decision: use existing approved access and do not create another credential. The earlier additional-reader handoff is withdrawn and must not be repeated as an unanswered ask.
Continue assessing the declarative path within that constraint. Complete inventory and ownership checks, independent state and recovery, a no-destroy plan, and first-apply review remain required. Partial provider reads and dashboard observations do not clear those gates. No provider change has been made.
#51 merged, and I ran the first confirmed plan on main at 698c02b22. It refused with CLOUDFLARE_BOOTSTRAP_PLAN=UNVERIFIED stage=state-boundary. No provider resource was changed and no proposal was exported. Encrypted diagnostics were uploaded and expire after one day; a new run recreates them.
What the stage shows: the plan itself passed the guard and the exact change boundary (one unchanged zone plus one new bucket), and the recovery payload checks found the expected zone. So the refusal comes from the stricter check that state holds exactly that one zone. I have not read the diagnostics, so the cause is not established. My best guess, untested, is that the imported state contains an extra entry that the test fixture does not, such as an empty placeholder for a resource with no instances.
Next: decrypt the diagnostics in private custody and read only the shape of the state's resource list (addresses and instance counts), then correct either the check or the fixture. I did not open the private identity from this scheduled run. This does not change the remaining gates here.
The state-boundary refusal is fixed by #52. The confirmed plan on main at 0925d1576 now ends with CLOUDFLARE_BOOTSTRAP_PLAN=ENCRYPTED review=required provider_writes=0, using the pinned OpenTofu 1.12.6.
Cause.tofu import keeps an entry with no instances for each declared for_each that is empty, and the old check required exactly one entry. The diagnostics were not needed: the shape reproduces offline, and this passing run confirms it was the only thing stopping that stage.
What this does and does not show. The run imported only into its own runner-local state, and the script has no apply path. It passed the exact boundary of one unchanged zone plus one new state bucket. The encrypted proposal expires on 2026-11-03 at 00:46 UTC, and a new run recreates it.
Not done. Nobody has read the encrypted proposal, the bucket does not exist, and no apply has run. First apply and recovery stay separate gates here, and both need the private recovery identity, which I did not open from a scheduled run.
PR #53 merged the real initial state/configuration recovery generation at 44f21303ed9d64c925e92214fe82347c2d208274. The expected reviewed head merged, and GitHub verifies the merge signature. Authenticated recovery passed again from a fresh archive of fetched main, using the independently held matching identity.
This completes retention of the initial imported generation in its owning repository. No provider resources or DNS records changed. Backend activation and the remaining adoption/recovery acceptance gates remain open; this is not a full migration receipt.
#53 and #54 have merged. Confirmed main-only run 41431272754, first attempt at 58d5e58aca7395406de45b9b7125a1b28d18f83b, passed in custody-check mode with provider_writes=0.
Independent readback verified the signed result commit 1677387276fb18e62a230d0de7796f6e88b14d21, its exact main parent, and the immutable result tag. The encrypted recovery package fetched from that tag authenticated successfully with the existing independent recovery identity. All three package files are byte-identical to the main source. This proves durable Git custody and authenticated recovery of the initial imported state; it neither creates the proposed storage nor proves a clean applied provider plan.
The first provider apply remains unrun pending its remaining provider prerequisite. No one-use apply payload has been uploaded, no new long-lived API credential was created, and no DNS or backend was changed.
The confirmed first apply 41466246062 passed at reviewed main 58d5e58aca7395406de45b9b7125a1b28d18f83b: CLOUDFLARE_BOOTSTRAP_APPLY=VERIFIED mode=apply provider_writes=1 custody=VERIFIED convergence=VERIFIED.
It applied the exact frozen proposal, creating the one protected state bucket while leaving the zone and DNS unchanged. Independent readback authenticated the signed result tag at c3c9428895d24617331710f87491beda78e2c7e9, its exact reviewed parent, the successful native custody receipt and both encrypted payloads. The resulting state preserves the imported lineage and contains exactly the zone and selected bucket. The temporary apply-data secret has been removed after that verification.
This completes the guarded first apply and its independent recovery proof. Remote backend migration, actual lock contention and recovery from a clean environment remain separate gates before general apply automation or later adoption.
Closing the inventory/adoption-preparation slice on its actual evidence. Confirmed inventory run 41465476663 passed and was independently authenticated; the inventory/dispatch/egress negative controls pass in the reviewed repository validation. The selected first adoption was limited to the owned zone and new protected state storage, preserving the declared DNS writers. The subsequent frozen proposal, custody proof and first apply are recorded above, including authenticated recovery of the preserved lineage.
The existing credential was sufficient; no additional long-lived reader credential was created. Independent remote backend locking and real-state migration remain open in #55, with the isolated prerequisite in #56. Closing this slice does not accept those downstream gates or complete the broader platform recovery work.
Activity
coderabbitai commentedon Oct 29, 2026
🔗 Related PRs
#37 - fix: separate bootstrap inventory credentials [merged]
#46 - fix: explain Cloudflare inventory failures [merged]
#47 - fix: accept supported R2 inventory responses [merged]
#32 - feat: prepare encrypted read-only DNS snapshots [merged]
📝 Issue Planner
Check the box below or use the
@coderabbitai plancommand to generate an implementation plan and prompts that you can use with your favorite coding assistant.🧪 Issue enrichment is currently in open beta.
You can configure auto-planning by selecting labels in the issue_enrichment configuration.
To disable automatic issue enrichment, add the following to your
.coderabbit.yaml:💬 Have feedback or questions? Drop into our discord!
chore: agent-claim #35 nonce=efa971ff36c2365bf001d5dcad6d1e54
chore: agent-claim #35 nonce=1a4c7dc13bd31d19cf7d6144dc4655d7
devantler commentedon Oct 29, 2026
The diagnostic and its separate private reader binding are delivered through #36 and #37. Current main CI passed. The first confirmed account observation stopped safely without publishing an artifact or changing provider resources. A separate confirmed DNS snapshot succeeded and was recovered privately.
The private bootstrap handoff remains outstanding. Resume with a fresh confirmed main observation after that handoff, then finish the explicit adoption set. The first migration plan and apply remain unapproved. This card returns to Ready on that concrete prerequisite; it is not a completed migration or a verification parking lane.
chore: agent-claim #35 nonce=ddf3b1959e839f9e204651d811d52868
devantler commentedon Oct 29, 2026
The maintainer has answered the access decision: use existing approved access and do not create another credential. The earlier additional-reader handoff is withdrawn and must not be repeated as an unanswered ask.
Continue assessing the declarative path within that constraint. Complete inventory and ownership checks, independent state and recovery, a no-destroy plan, and first-apply review remain required. Partial provider reads and dashboard observations do not clear those gates. No provider change has been made.
17 remaining items
chore: agent-claim #35 nonce=263acfeb191288197343eecf5a281053
devantler commentedon Nov 1, 2026
#51 merged, and I ran the first confirmed plan on
mainat698c02b22. It refused withCLOUDFLARE_BOOTSTRAP_PLAN=UNVERIFIED stage=state-boundary. No provider resource was changed and no proposal was exported. Encrypted diagnostics were uploaded and expire after one day; a new run recreates them.What the stage shows: the plan itself passed the guard and the exact change boundary (one unchanged zone plus one new bucket), and the recovery payload checks found the expected zone. So the refusal comes from the stricter check that state holds exactly that one zone. I have not read the diagnostics, so the cause is not established. My best guess, untested, is that the imported state contains an extra entry that the test fixture does not, such as an empty placeholder for a resource with no instances.
Next: decrypt the diagnostics in private custody and read only the shape of the state's resource list (addresses and instance counts), then correct either the check or the fixture. I did not open the private identity from this scheduled run. This does not change the remaining gates here.
chore: agent-claim #35 nonce=f28fd252c3d8c5c68149947259074307
devantler commentedon Nov 2, 2026
The state-boundary refusal is fixed by #52. The confirmed plan on
mainat0925d1576now ends withCLOUDFLARE_BOOTSTRAP_PLAN=ENCRYPTED review=required provider_writes=0, using the pinned OpenTofu 1.12.6.Cause.
tofu importkeeps an entry with no instances for each declaredfor_eachthat is empty, and the old check required exactly one entry. The diagnostics were not needed: the shape reproduces offline, and this passing run confirms it was the only thing stopping that stage.What this does and does not show. The run imported only into its own runner-local state, and the script has no
applypath. It passed the exact boundary of one unchanged zone plus one new state bucket. The encrypted proposal expires on 2026-11-03 at 00:46 UTC, and a new run recreates it.Not done. Nobody has read the encrypted proposal, the bucket does not exist, and no apply has run. First apply and recovery stay separate gates here, and both need the private recovery identity, which I did not open from a scheduled run.
chore: agent-claim #35 nonce=2759078ec80cb9bedc361d1bfaa3fb54
devantler commentedon Nov 2, 2026
PR #53 merged the real initial state/configuration recovery generation at
44f21303ed9d64c925e92214fe82347c2d208274. The expected reviewed head merged, and GitHub verifies the merge signature. Authenticated recovery passed again from a fresh archive of fetched main, using the independently held matching identity.This completes retention of the initial imported generation in its owning repository. No provider resources or DNS records changed. Backend activation and the remaining adoption/recovery acceptance gates remain open; this is not a full migration receipt.
chore: agent-claim #35 nonce=c58cac2058bb0eeb640b8442f1ed1a36
chore: agent-claim #35 nonce=5dddbc1c30f18c1a0accf436f5a3c3cb
devantler commentedon Nov 2, 2026
#53 and #54 have merged. Confirmed main-only run 41431272754, first attempt at
58d5e58aca7395406de45b9b7125a1b28d18f83b, passed in custody-check mode withprovider_writes=0.Independent readback verified the signed result commit
1677387276fb18e62a230d0de7796f6e88b14d21, its exact main parent, and the immutable result tag. The encrypted recovery package fetched from that tag authenticated successfully with the existing independent recovery identity. All three package files are byte-identical to the main source. This proves durable Git custody and authenticated recovery of the initial imported state; it neither creates the proposed storage nor proves a clean applied provider plan.The first provider apply remains unrun pending its remaining provider prerequisite. No one-use apply payload has been uploaded, no new long-lived API credential was created, and no DNS or backend was changed.
chore: agent-claim #35 nonce=699502e61b050bff886bb69facc255b3
chore: agent-claim #35 nonce=27f382084ca294b7697e65fe7a5bee9c
devantler commentedon Nov 2, 2026
The confirmed first apply 41466246062 passed at reviewed main
58d5e58aca7395406de45b9b7125a1b28d18f83b:CLOUDFLARE_BOOTSTRAP_APPLY=VERIFIED mode=apply provider_writes=1 custody=VERIFIED convergence=VERIFIED.It applied the exact frozen proposal, creating the one protected state bucket while leaving the zone and DNS unchanged. Independent readback authenticated the signed result tag at
c3c9428895d24617331710f87491beda78e2c7e9, its exact reviewed parent, the successful native custody receipt and both encrypted payloads. The resulting state preserves the imported lineage and contains exactly the zone and selected bucket. The temporary apply-data secret has been removed after that verification.This completes the guarded first apply and its independent recovery proof. Remote backend migration, actual lock contention and recovery from a clean environment remain separate gates before general apply automation or later adoption.
devantler commentedon Nov 2, 2026
Closing the inventory/adoption-preparation slice on its actual evidence. Confirmed inventory run 41465476663 passed and was independently authenticated; the inventory/dispatch/egress negative controls pass in the reviewed repository validation. The selected first adoption was limited to the owned zone and new protected state storage, preserving the declared DNS writers. The subsequent frozen proposal, custody proof and first apply are recorded above, including authenticated recovery of the preserved lineage.
The existing credential was sufficient; no additional long-lived reader credential was created. Independent remote backend locking and real-state migration remain open in #55, with the isolated prerequisite in #56. Closing this slice does not accept those downstream gates or complete the broader platform recovery work.