Skip to content

Prove bootstrap inventory before declarative adoption #35

Closed

Description

@devantler

🤖 Generated by the Agentic Engineer

Summary

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.

Activity

  1. coderabbitai commented on Oct 29, 2026

    @coderabbitai
    🔗 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 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!

  2. self-assigned this
    on Oct 29, 2026
  3. moved this to 🫴 Ready in 🌊 Project Boardon Oct 29, 2026
  4. moved this from 🫴 Ready to 🏃🏻‍♂️ In Progress in 🌊 Project Boardon Oct 29, 2026
  5. added 2 commits that reference this issue on Oct 29, 2026
  6. devantler commented on Oct 29, 2026

    @devantler
    ContributorAuthor

    🤖 Generated by the Agentic Engineer

    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.

  7. added a commit that references this issue on Oct 29, 2026
  8. moved this from 🏃🏻‍♂️ In Progress to 🫴 Ready in 🌊 Project Boardon Oct 29, 2026
  9. devantler commented on Oct 29, 2026

    @devantler
    ContributorAuthor

    🤖 Generated by the Agentic Engineer

    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.

  10. 17 remaining items

  11. added a commit that references this issue on Nov 1, 2026
  12. devantler commented on Nov 1, 2026

    @devantler
    ContributorAuthor

    🤖 Generated by the Agentic Engineer

    #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.

  13. added a commit that references this issue on Nov 2, 2026
  14. devantler commented on Nov 2, 2026

    @devantler
    ContributorAuthor

    🤖 Generated by the Agentic Engineer

    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.

  15. added a commit that references this issue on Nov 2, 2026
  16. devantler commented on Nov 2, 2026

    @devantler
    ContributorAuthor

    🤖 Generated by the Agentic Engineer

    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.

  17. added 2 commits that reference this issue on Nov 2, 2026
  18. devantler commented on Nov 2, 2026

    @devantler
    ContributorAuthor

    🤖 Generated by the Agentic Engineer

    #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.

  19. added 2 commits that reference this issue on Nov 2, 2026
  20. devantler commented on Nov 2, 2026

    @devantler
    ContributorAuthor

    🤖 Generated by the Agentic Engineer

    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.

  21. devantler commented on Nov 2, 2026

    @devantler
    ContributorAuthor

    🤖 Generated by the Agentic Engineer

    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.

  22. moved this from 🫴 Ready to ✅ Done in 🌊 Project Boardon Nov 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Fields

Priority

None yet

Start date

None yet

Target date

None yet

Effort

None yet

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions