infra-setup · diff

git:20260805.ff0eb1f to git:20261018.2621782

172 added, 142 removed. Audit A to A.

---
name: infra-setup
- description: "Agent-first, human-in-the-loop bootstrap for a Terraform + HCP + Cloudflare + GitHub SaaS infra repo. Reads a repo-local config (.claude/infra-copilot.local.md) then wires HCP state, the Cloudflare token, and the GitHub App, imports existing resources, and runs the first plan. Trigger on: 'set up infra', 'bootstrap this repo', 'run infra-setup', 'onboard a new org', '/infra-setup'."
+ description: "Greenfield bootstrap of a Terraform + Cloudflare + GitHub infra repo with either HCP Terraform (cloud block) or object-storage backend (GCS/S3/Azure + GitHub Actions). Wires state, the Cloudflare token, and the GitHub App, then reaches a green first plan on both leaves. Use when nothing is wired up yet. Not for adopting resources that already exist (infra-skills:infra-import), nor for provisioning new ones in a working repo (infra-skills:infra-add)."
+ allowed-tools: Read, Bash, Edit, Write, Glob, Grep, AskUserQuestion
---
- # infra-setup
-
- Agent-runnable bootstrap for this repo. You (the agent) execute it end-to-end, pausing
- only for the steps a human irreducibly must do. Keep this file as the **router**: it
- carries the protocol (actor model, handoff, resume) and routes to `references/` for the
- per-provider detail and to the repo's canonical `docs/` for the fine print.
-
- > **This is a Skill, not a script.** There is no `infra-setup` executable. Drive it by
- > reading this file and the manifest, then running each step. A human invokes it with
- > `/infra-setup` or by saying "set up the infra."
-
- > **Orchestrates, does not duplicate.** Authoritative per-step detail lives in
- > [`references/docs/setup.md`](references/docs/setup.md) (bootstrap) and
- > [`references/docs/import.md`](references/docs/import.md) (Cloudflare migration). This
- > skill adds the *actor split* and *resume protocol* on top. When a step says "see
- > `setup.md#3`", read that section.
-
- ## The one idea
-
- **The human is the browser and the keyholder. Everything scriptable is the agent's.**
-
- There is exactly one thing a human must do that an agent cannot: sit at a browser, sign
- up for a SaaS, and mint the first credential. Once an HCP token exists (from
- `terraform login`), the agent creates workspaces, sets variables, reads plans, and
- confirms applies **over the HCP API** — no more clicking. So the human surface shrinks to
- three action kinds:
-
- 1. **Sign up** for a service (browser-only).
- 2. **Mint a credential** in a dashboard (browser-only — no API bootstraps the first token).
- 3. **Paste a secret** into HCP (browser-only — the agent must never see the plaintext).
+ <!--
+ AI-RULEZ :: GENERATED FILE — DO NOT EDIT
+ Content-Hash: blake3:c27192b9b60d9469534ce08d052f117682a29b92e1b85ef1c8d42a95a7bcc5f3
+ Source-Hash: blake3:38aa282b91a5aa18d87830dea0171bc65c256b604a715b949c5845a8b1ce8e56
+ Schema-Version: v1
+ -->
- Everything else — verifying, creating workspaces, importing resources, first plan — is yours.
+ # infra-setup
- ## Step 0 — read the repo config (AGENT, always first)
+ Greenfield bootstrap. You (the agent) execute it end-to-end, pausing only for the steps a
+ human irreducibly must do. This file is a **router**: the reusable machinery — actor
+ model, handoff block, resume scan, preflight — lives in
+ [`../infra/references/protocol.md`](../infra/references/protocol.md); the per-step manifest in
+ [`../infra/references/steps.yaml`](../infra/references/steps.yaml) (**phases 0–4**); per-provider detail and
+ the canonical docs under [`../infra/references/`](../infra/references/).
- Before the resume scan, read `.claude/infra-copilot.local.md` from the current repo and
- export the shell vars every check depends on. Full schema + the export block:
- [`references/config.md`](references/config.md). If the file is missing, emit the handoff
- block, show the schema, offer to scaffold from `references/infra-copilot.local.md.example`,
- and wait — never guess org/domain/IDs.
+ > **This is a Skill, not a script.** There is no `setup` executable. Drive it by reading
+ > this file, the protocol, and the manifest, then running each step. A human invokes it
+ > with `/infra-skills:infra-setup` or by saying "set up the infra."
- ## Actors
+ ## Scope
- Every step in [`references/steps.yaml`](references/steps.yaml) is tagged with who performs it:
+ `setup` owns the cold start: from an empty repo to green plans on both leaves.
- | Tag | Meaning | Your behaviour |
- |---|---|---|
- | **`AGENT`** | You run it (shell, `gh`, `terraform`, HCP API). | Execute. Verify with the step's `check`. Continue on green. |
- | **`HUMAN`** | Irreducibly human (signup, dashboard, secret paste). | **Stop.** Emit the handoff block. Wait for the human to reply `done`. Then run the `check` before continuing. |
+ The mode sections below describe each implementation's duties for the leaves routed to
+ it, not a repository-wide either/or. Load and validate `leaf_backends` with the default
+ in config before preflight. In mixed repositories, establish both service prerequisites,
+ configure only each service's effective bootstrap subset, and verify credentials/plans
+ on each leaf's selected implementation. Additional providers join the service inventory
+ but their leaf setup remains Phase 6. Do not recreate or reconnect a migrated HCP leaf.
+ Synchronize Actions' static `CLOUDFLARE_BACKEND` and `GITHUB_BACKEND` values with effective
+ config in the cutover PR and verify plan/apply workflow agreement before proceeding.
+ For existing HCP state, follow
+ [`the migration runbook`](../infra/references/docs/object-storage-state.md#migrating-from-hcp),
+ not a fresh backend initialization. See
+ [`operation selection`](../infra/references/operations.md#selection-and-resume).
- ### The handoff block
+ ### HCP implementation (effective HCP leaves)
- When a step is `HUMAN`, do **not** guess or fake it. Stop and print exactly this shape, then wait:
+ | # | Phase | Actors | Deep dive |
+ |---|---|---|---|
+ | 0 | **Toolchain + HCP bootstrap** — commit reviewed pins, sign up, `terraform login`, get the pivot token | `HUMAN` then `AGENT` | [`../infra/references/docs/setup.md#6`](../infra/references/docs/setup.md#6-local-development), [`../infra/references/hcp.md`](../infra/references/hcp.md), [`../infra/references/docs/setup.md#1`](../infra/references/docs/setup.md#1-hcp-terraform--organization) |
+ | 1 | **HCP workspaces** — create `cloudflare` + `github-org`, VCS + safety toggles | `AGENT` (API) + `HUMAN` VCS OAuth | [`../infra/references/hcp.md`](../infra/references/hcp.md), [`../infra/references/docs/setup.md#2`](../infra/references/docs/setup.md#2-hcp-terraform--workspaces) |
+ | 2 | **Cloudflare** — mint scoped token, paste into HCP, verify | `HUMAN` mint/paste, `AGENT` verify | [`../infra/references/cloudflare.md`](../infra/references/cloudflare.md) |
+ | 3 | **GitHub** — create + install the GitHub App, paste creds into HCP | `HUMAN` create/install/paste, `AGENT` verify | [`../infra/references/github.md`](../infra/references/github.md) |
+ | 4 | **Narrow the credential, then first plan** — hand off to a plan-only HCP identity, then `init` + speculative `plan` per leaf, read via API | `HUMAN` handoff, then `AGENT` | [`../infra/references/steps.yaml`](../infra/references/steps.yaml) (`hcp-apply-scope`), [`../infra/references/docs/hcp-api.md`](../infra/references/docs/hcp-api.md) |
- ```
- ┌─ HUMAN ACTION NEEDED ─────────────────────────────
- │ Step: <id> — <title>
- │ Why: <one line — what this unblocks>
- │ Do this:
- │ 1. <precise, copy-pasteable instruction, with URL>
- │ 2. …
- │ When done, reply "done" and I'll verify.
- └───────────────────────────────────────────────────
- ```
+ ### Object-storage implementation (effective object-storage leaves)
- After the human replies, run the step's `check`. If it fails, re-emit the handoff with
- what you observed — never silently proceed past a red check.
+ | # | Phase | Actors | Deep dive |
+ |---|---|---|---|
+ | 0 | **Toolchain + state bucket** — commit reviewed pins, create versioned bucket, configure `backend.tf` blocks | `HUMAN` then `AGENT` | [`../infra/references/docs/object-storage-state.md#object-storage-backend`](../infra/references/docs/object-storage-state.md#object-storage-backend) |
+ | 1 | **GitHub Actions CI** — create plan/apply workflows, configure GitHub Environment protection | `AGENT` then `HUMAN` | [`../infra/references/docs/object-storage-ci.md#github-actions`](../infra/references/docs/object-storage-ci.md#github-actions) |
+ | 2 | **Cloudflare** — mint scoped token, add `CLOUDFLARE_API_TOKEN` to GitHub Actions secrets, verify | `HUMAN` mint/save, `AGENT` verify | [`../infra/references/cloudflare.md`](../infra/references/cloudflare.md) |
+ | 3 | **GitHub** — create + install GitHub App, add secrets (`GH_APP_ID`, `GH_APP_INSTALLATION_ID`, `GH_APP_PEM`) to GitHub Actions | `HUMAN` create/install/save, `AGENT` verify | [`../infra/references/github.md`](../infra/references/github.md) |
+ | 4 | **First plan** — verify `plan-cloudflare` and `plan-github` jobs succeed in GitHub Actions | `AGENT` | [`../infra/references/steps.yaml`](../infra/references/steps.yaml), [`../infra/references/docs/object-storage-ci.md#github-actions`](../infra/references/docs/object-storage-ci.md#github-actions) |
- ## Resume protocol
+ Adopting resources that already exist (a live domain, existing repos)? That's
+ **infra-skills:infra-import** (Phase 5), run after this reaches green plans.
- This skill is **idempotent and resumable**. On every run, before doing anything, walk
- [`references/steps.yaml`](references/steps.yaml) top to bottom and run each step's `check`
- to discover *where setup already is*. Resume at the first step whose check is red. An
- all-green repo means "already set up, nothing to do."
+ > **⚠️ Pre-existing resources — stop before applying.** Unlike the old monolith, `setup`
+ > ends at green *speculative* plans (phase 4) and does **not** auto-import. If the phase-4
+ > plan shows resources as `will be created` that you know already exist live — a domain
+ > already serving traffic, repos already on GitHub — do **not** apply: an apply would
+ > recreate or clobber them. Run **infra-skills:infra-import** first to adopt them (the plan
+ > should then read *imports, not creates*), and only then apply.
- ```text
- for step in steps.yaml:
- if run(step.check) is green: skip, print "✓ {step.id}"
- else: resume here
- ```
+ ## Workflow
- Never assume state from memory or a prior session — always re-check.
- See [`references/steps.yaml`](references/steps.yaml) for the runtime contract (which shell
- vars to export before running any check).
+ 1. **Read config first** (shared protocol, Step 0). Load `.infra-copilot/config.md`, or
+ use `.claude/infra-copilot.local.md` as the migration fallback, and export the org
+ vars. If both are missing → handoff, offer to scaffold, wait.
+ For a new setup, recommend **object-storage** first. Explain HCP's managed runs and
+ UI, its free tier's 500-resource limit, and this workflow's required paid tier with
+ team management for the plan-only credential, even below 500 resources. Ask for the
+ choice using the shared protocol, then always write `backend: object-storage` or
+ `backend: hcp` explicitly.
+ Existing configs without `backend` stop for the migration handoff; existing `cloud {}`
+ blocks prompt an offer to record `backend: hcp`, never an automatic mode switch.
+ See [`../infra/references/config.md`](../infra/references/config.md).
+ 2. **Bootstrap preflight**, then **resume scan** over phases 0–4 of
+ [`../infra/references/steps.yaml`](../infra/references/steps.yaml). On a cold repo, check that `mise` itself
+ is available, then scan `toolchain-pin` before running the pin-dependent preflight
+ checks. Once it is green, finish preflight, handle the optional `repo-config-sync` step,
+ print `✓`, and continue through every selected service's bootstrap members. Full contract:
+ [`../infra/references/protocol.md`](../infra/references/protocol.md).
+ 3. **Respect the actor split.** Run `AGENT` steps yourself. On a `HUMAN` step, stop, emit
+ the handoff block, wait for `done`, re-run the `check` — never fake a signup, a
+ dashboard click, or a secret paste.
+ 4. **Route to the deep-dives** under `../infra/references/` for the fine print; don't duplicate them.
- ## Preflight (AGENT)
+ ### Phase notes
- Confirm your toolbox. All of these are yours to install if missing — none need a human.
+ **HCP mode:**
- ```sh
- terraform version # ≥ 1.9 — provisioning + import blocks
- gh --version # GitHub CLI — repo ops, Pages, App install checks
- jq --version # JSON wrangling for HCP/Cloudflare/GitHub APIs
- curl --version # HCP + Cloudflare REST
- ```
+ - **Phase 0 — Toolchain + HCP bootstrap.** The first `HUMAN` step chooses exact tool
+ versions, reviews the whole `mise.toml`, and commits it with `mise.lock`; this must
+ happen before pin-dependent preflight. If the consuming repository ships an executable
+ `scripts/sync-config.sh`, stop for a human to review and run it next, then verify its
+ deterministic changes and canonical config were committed together;
+ repositories without the helper skip this step. Then `HUMAN` signs up + runs
+ `terraform login`, after which you own the HCP API. Toolchain sequence:
+ [`../infra/references/docs/setup.md#6`](../infra/references/docs/setup.md#6-local-development).
+ HCP commands + verify: [`../infra/references/hcp.md`](../infra/references/hcp.md#phase-0--bootstrap).
+ - **Phase 1 — HCP workspaces.** Only HCP-routed bootstrap leaves get workspaces
+ (`cloudflare` for Cloudflare, `github-org` for GitHub).
+ A human does the one-time GitHub↔HCP VCS connection (browser); create the selected subset via the API with
+ the right working dir, path-scoped triggers, remote execution, and auto-apply **off**.
+ `create_ws` helper + safety rationale: [`../infra/references/hcp.md`](../infra/references/hcp.md#phase-1--workspaces).
+ - **Phase 2 — Cloudflare.** You can't mint a scoped token from nothing and must never see
+ the plaintext — minting/pasting are `HUMAN`, verifying is `AGENT`.
+ [`../infra/references/cloudflare.md`](../infra/references/cloudflare.md).
+ - **Phase 3 — GitHub.** The `github-org` workspace authenticates as a **GitHub App**, not
+ a PAT. Creation + install are browser flows; three creds get pasted into HCP.
+ [`../infra/references/github.md`](../infra/references/github.md).
+ - **Phase 4 — First plan.** Prove every credential end-to-end. Per leaf: `terraform init`
+ then speculative `terraform plan` (runs in HCP). A VCS-connected workspace **allows
+ `plan` but blocks `apply`** from the CLI — intentional. Read plans without the UI via
+ [`../infra/references/docs/hcp-api.md`](../infra/references/docs/hcp-api.md). Green on both leaves =
+ credentials proven.
- These are the human-readable checks; the manifest's `preflight` block in
- [`references/steps.yaml`](references/steps.yaml) enforces the version floor (Terraform ≥ 1.9)
- programmatically — run those to gate, not just `terraform version`.
+ **Object-storage mode:**
- Then detect the credential the whole flow pivots on:
+ - **Phase 0 — Toolchain + state bucket.** Tool versions are committed in `mise.toml` +
+ `mise.lock`. `HUMAN` creates the versioned, private state bucket with locking configured.
+ `AGENT` writes `backend.tf` blocks in each leaf pointing to the state bucket.
+ [`../infra/references/docs/object-storage-state.md#object-storage-backend`](../infra/references/docs/object-storage-state.md#object-storage-backend).
+ - **Phase 1 — GitHub Actions CI.** `AGENT` creates `.github/workflows/terraform-plan.yml` and
+ `terraform-apply.yml`. `HUMAN` restricts the `production` GitHub Environment to `main` and adds
+ required reviewers where the plan offers them, or locks an `Apply gate` decision.
+ [`../infra/references/docs/object-storage-ci.md#github-actions`](../infra/references/docs/object-storage-ci.md#github-actions).
+ - **Phase 2 — Cloudflare.** `HUMAN` mints scoped token and adds `CLOUDFLARE_API_TOKEN` to
+ GitHub Actions secrets; `AGENT` verifies.
+ [`../infra/references/cloudflare.md`](../infra/references/cloudflare.md).
+ - **Phase 3 — GitHub.** `HUMAN` creates/installs GitHub App and adds `GH_APP_ID`,
+ `GH_APP_INSTALLATION_ID`, and `GH_APP_PEM` to GitHub Actions secrets; `AGENT` verifies.
+ [`../infra/references/github.md`](../infra/references/github.md).
+ - **Phase 4 — First plan.** Trigger or inspect GitHub Actions plan workflows for `cloudflare`
+ and `github` leaves; verify both jobs succeed. Align required status check job names.
+ [`../infra/references/docs/object-storage-ci.md#github-actions`](../infra/references/docs/object-storage-ci.md#github-actions).
- ```sh
- jq -re '.credentials["app.terraform.io"].token' ~/.terraform.d/credentials.tfrc.json \
- && echo "HCP token present — agent can drive the API" \
- || echo "No HCP token yet — first HUMAN step will mint one"
- ```
+ ## Validation
- ## Phases
+ Setup is complete when you can report:
- Run in order. Each routes to a `references/` deep-dive and the canonical `docs/` section.
+ - ✓ `.infra-copilot/config.md` explicitly records the chosen `backend`.
- | # | Phase | Actors | Deep dive |
- |---|---|---|---|
- | 0 | **HCP bootstrap** — sign up, `terraform login`, get the pivot token | `HUMAN` then `AGENT` | [`references/hcp.md`](references/hcp.md), [`references/docs/setup.md#1`](references/docs/setup.md#1-hcp-terraform--organization) |
- | 1 | **HCP workspaces** — create `cloudflare` + `github-org`, set VCS + safety toggles | `AGENT` (API) + `HUMAN` VCS OAuth | [`references/hcp.md`](references/hcp.md), [`references/docs/setup.md#2`](references/docs/setup.md#2-hcp-terraform--workspaces) |
- | 2 | **Cloudflare** — mint scoped token, paste into HCP, verify | `HUMAN` mint/paste, `AGENT` verify | [`references/cloudflare.md`](references/cloudflare.md) |
- | 3 | **GitHub** — create + install the GitHub App, paste creds into HCP | `HUMAN` create/install/paste, `AGENT` verify | [`references/github.md`](references/github.md) |
- | 4 | **First plan** — `init` + speculative `plan` per leaf, read via API | `AGENT` | [`references/docs/setup.md#6`](references/docs/setup.md#6-local-development) |
- | 5 | **Migration** — adopt existing resources with import blocks (no re-create) | `AGENT` run, `HUMAN` discovery token | [`references/migration.md`](references/migration.md) |
- | 6 | **GCP** *(optional, template only)* — not provisioned today | design decision first | [`references/gcp.md`](references/gcp.md) |
+ **For every effective HCP leaf and the shared HCP service:**
- ### Phase 0 — HCP bootstrap
- The only unavoidable cold-start; produces the token that lets you script the rest.
- `HUMAN` signs up + runs `terraform login`; then you own the HCP API. Commands and verify:
- [`references/hcp.md`](references/hcp.md#phase-0--bootstrap).
+ - ✓ `mise.toml` + `mise.lock` are reviewed, committed together, exact-pinned, and
+ installable with `MISE_LOCKED=1`.
+ - ✓ HCP org `$ORG` + project `infra` reachable via API.
+ - ✓ Every HCP-routed bootstrap workspace exists, VCS-linked, auto-apply off, fork speculative plans off.
+ - ✓ Each selected workspace uses the exact Terraform version committed in `mise.toml`.
+ - ✓ Its required variables are present: `cloudflare_api_token` only for HCP-routed Cloudflare;
+ `github_app_id`, `github_app_installation_id`, `github_app_pem` only for HCP-routed GitHub.
+ - ✓ `terraform plan` is green on every HCP-routed bootstrap leaf.
+ - ✓ `hcp-apply-scope` green — the credential in use cannot apply. It is a `HUMAN`
+ step like `cf-token` and `gh-app`: stop there, hand off, and continue when it turns
+ green. Setup is not complete while the agent still holds the apply-capable user
+ token from `terraform login`.
- ### Phase 1 — HCP workspaces
- Two workspaces (`cloudflare`, `github-org`), one per leaf. A human does the one-time
- GitHub↔HCP OAuth (browser); you create both workspaces via the API with the right working
- dir, path-scoped triggers, remote execution, and auto-apply **off**. Ready-to-run
- `create_ws` helper + the safety-toggle rationale: [`references/hcp.md`](references/hcp.md#phase-1--workspaces).
+ **For every effective object-storage leaf and the shared runner service:**
- ### Phase 2 — Cloudflare
- You can't mint a scoped Cloudflare token from nothing, and must never see the plaintext —
- so minting/pasting are `HUMAN`, verifying is `AGENT`. Full walkthrough:
- [`references/cloudflare.md`](references/cloudflare.md).
+ - ✓ `mise.toml` + `mise.lock` are reviewed, committed together, exact-pinned, and
+ installable with `MISE_LOCKED=1`.
+ - ✓ State bucket created, versioned, private, with locking configured.
+ - ✓ `backend.tf` blocks configured in each object-storage-routed bootstrap leaf.
+ - ✓ GitHub Actions workflows committed (`terraform-plan.yml`, `terraform-apply.yml`) and production environment configured.
+ - ✓ Required Actions secrets are present: `CLOUDFLARE_API_TOKEN` only for runner-routed Cloudflare;
+ `GH_APP_ID`, `GH_APP_INSTALLATION_ID`, `GH_APP_PEM` only for runner-routed GitHub.
+ - ✓ Each object-storage-routed bootstrap leaf's plan job is green (`plan-cloudflare` or `plan-github`).
+ - ✓ Required status checks in branch protection match workflow job names.
- ### Phase 3 — GitHub
- The `github-org` workspace authenticates as a **GitHub App**, not a PAT. Creation +
- install are browser flows; three creds get pasted into HCP. Walkthrough incl. the
- manifest-flow shortcut: [`references/github.md`](references/github.md).
+ If the domain/repos already exist, continue with **infra-skills:infra-import** to adopt them
+ (plan should then show imports, not creates). Otherwise day-to-day work follows your
+ repo's own contributor guide.
- ### Phase 4 — First plan (AGENT)
- Prove every credential end-to-end. Per leaf: `terraform init` then `terraform plan`
- (speculative, runs in HCP). A VCS-connected workspace **allows `plan` but blocks `apply`**
- from the CLI — intentional. Read plans without the UI via
- [`references/docs/hcp-api.md`](references/docs/hcp-api.md). Green on both leaves = credentials proven.
+ ## Guardrails
- ### Phase 5 — Migration (adopt existing resources)
- If the domain/repos already exist, **import** them so Terraform manages them without
- recreating. Canonical runbook: [`references/docs/import.md`](references/docs/import.md);
- cross-provider pattern: [`references/migration.md`](references/migration.md). Success signal:
- `terraform plan` shows every existing resource as **"will import"**, nothing as **"will create"**.
+ `setup` ends at green **speculative** plans and does not apply. If a phase-4 plan shows
+ resources as `will be created` that you know already exist live — a domain already
+ serving traffic, repos already on GitHub — do **not** apply: an apply would recreate or
+ clobber them. Run **infra-skills:infra-import** first, so the plan reads *imports, not
+ creates*.
- ### Phase 6 — GCP (template, optional)
- **Not provisioned today.** GCP is not a managed provider here. Adopting it is a
- **locked-design-decision change** — update the repo's locked design decisions doc and its
- Terraform layout README first, then follow the same actor split. Template:
- [`references/gcp.md`](references/gcp.md).
+ Never fake a `HUMAN` step. A signup, a dashboard click and a secret paste are the
+ human's, and the agent must never see a pasted secret in plaintext. On a red check after
+ a human replies `done`, re-emit the handoff with what you observed rather than
+ proceeding.
- ## Done signal
+ ## Example
- Setup is complete when you can report:
+ A resumed run prints what is already green and stops at the first red step:
- - ✓ HCP org `$ORG` (<your-org>) + project `infra` reachable via API.
- - ✓ Workspaces `cloudflare` and `github-org` exist, VCS-linked, auto-apply off, fork speculative plans off.
- - ✓ All sensitive vars present (`cloudflare_api_token`; `github_app_id`, `github_app_installation_id`, `github_app_pem`).
- - ✓ `terraform plan` green on both leaves.
- - ✓ Existing resources imported (plan shows imports, no creates) — if migrating.
+ ```text
+ ✓ toolchain-pin ✓ hcp-login ✓ hcp-signup ✓ hcp-verify
+ ✓ vcs-connect ✗ workspaces-create ← resume here
+ ```
- Then day-to-day work follows your repo's own contributor guide.
+ Everything green means the scope is already done and there is nothing to do.
## Configuring for your org
All org-specific values — HCP org, GitHub org, apex domain, Cloudflare account/zone IDs,
- managed repos, and the HCP status-check ID — live in one place:
- `.claude/infra-copilot.local.md` (schema and export block: [`references/config.md`](references/config.md)).
- Fill it in once and re-run this skill from Phase 0 — the resume protocol handles the rest.
+ managed repos, HCP status-check ID — live in `.infra-copilot/config.md` (schema +
+ export block: [`../infra/references/config.md`](../infra/references/config.md)). Fill it in once and re-run —
+ the resume protocol handles the rest.