title: UCCA-TERRAFORM-RECONCILE — brief: fossils out, spine in, keep-current filed, runbook written doc_id: UCCA-TERRAFORM-RECONCILE-BRIEF-01 type: build brief — engine-side, Tim → Alex. Not a fence crossing. layer: ground canonical: false authored: 2026-07-04 NYC (queued since the spine sprint; gate opened by retirement §A completion) relates_to: ADR-0004 (Cloudflare runtime) · UCCA-TM-2026-07-03-C-TECH §3 (live table) · UCCA-STUCK-JOB-DETECTOR build (cron + version 2ce7f588) · retirement §A record · the Full Cycle rule · the keep-current rule (ratified, files under this brief) · UCCA-CAPTURE-OPS-SUCCESSOR-01 (downstream dependent)
Terraform Reconcile — build brief¶
The debt this pays. The entire live spine was provisioned by CLI during the build sprint; the Terraform layer still describes a world that predates it and carries RTOpacks-era fossils. Since the spine went live the debt has compounded: DLQ, detector cron, reasoner redeploys. This brief makes the declared world and the real world the same world, files the rule that keeps them the same, and writes the runbook while the lessons are fresh.
1. The contract (what "done" means)¶
terraform plan against account e5a98302 returns no changes — the
declared state matches live reality exactly — and a rule exists on the record
making that the permanent condition. The old console's "No drift" badge was
fiction; after this brief, drift-zero is checkable fact.
2. Scope¶
2.1 Fossils out. Every RTOpacks-shaped declaration leaves the UCCA Terraform: the five retired config-only workers' residue, the deleted rtopacks-docs Pages project, anything else whose subject is the client. Yellow-tape treatment per house rule — removal noted in the fossil ledger with what it was and why it left; never silent deletion.
2.2 Spine in. Import (not recreate) every live resource the CLI sprint
provisioned, so state adopts reality:
- Workers: ucca-gate · ucca-reasoner (incl. container/DO configuration
as far as the provider models it) · ucca-keys
- D1: ucca-input-path
- R2: ucca-artefacts
- Queues: ucca-jobs (producer/consumer bindings, max_retries) ·
ucca-jobs-dlq + the DLQ wiring
- The detector cron trigger on ucca-reasoner (/5)
- UCCA's own live proxies (docs-proxy, knowledge-proxy) — they stay live,
they enter state
- DNS/domain records serving the above (keys.ucca.online, ops.ucca.online,
docs/knowledge surfaces) as they actually exist
- ucca-ops — on narrow hold but live; state describes reality, so it
imports, annotated: narrow hold, dies when successor serves
- ucca-backup / ucca-backup-large — live/suspended reality respectively;
import as-is, annotated disposition pending* (this brief does not decide
their fate)
Enumerate the account first; anything live that fits no category above → stop-gate (§6), don't improvise a home for it.
2.3 What Terraform does NOT capture here. Worker code versions and deployments are not state — the register and build log own those. Secrets never enter state or the repo; bindings reference, never contain.
3. The keep-current rule (files under this brief; already ratified)¶
KEEP-CURRENT: Every infrastructure change lands in the Terraform repo with an Infrastructure-State snapshot update in the same pass as the change itself. CLI-first provisioning is permitted in emergencies only, and the import lands before the session closes. A deploy that changes infrastructure without its Terraform pass is incomplete work.
File it to the ruling ledger with its ratification date; cross-reference the Full Cycle rule.
4. RUNBOOK-SPINE-01 (written under this brief, to ground/)¶
The operator's document, seeded from the sprint's scars: - Auth ritual: source the vault token, confirm the account echoes e5a98302 before every command; the two client-pointing credentials on the machine and why they're never used. - Deploy: the wrangler flow, Docker requirement, Containers:Edit scope. - Queue semantics: async-ack model (hand off fast, ack on hand-off, D1 is truth) · the wedge failure signature and why sync-ack is forbidden · DLQ + explicit max_retries (the silent-drop default) · sleepAfter must exceed the longest job. - GLM operational notes: OpenAI-chat response shape, reasoning_content token appetite and the 8000 floor, intermittent Workers AI 502/read-timeouts → retry, 6–12 min unoptimised timing, cap 2. - Detector: what the sweep does, STUCK_DETECTOR_TIMEOUT semantics, where diagnostics stash, MAX_RUN 30m / cadence 5m. - Debug: tail commands, diagnostics paths in R2, cognitive_cost reads. - Job submission/polling: the POST/GET shapes, the proof-payload pointer.
5. Proof (BUILT ≠ PROVEN)¶
terraform plan→ no changes, output captured to the build log.- Account enumeration vs state file: every live resource either in state or explicitly annotated out-of-scope with a reason — zero unaccounted.
- Infrastructure-State snapshot updated (Full Cycle), register rows for the snapshot, the rule, and the runbook.
- One deliberately trivial change round-tripped through Terraform (e.g. a tag/comment), applied and reverted, proving the pipeline actually drives the account — imports alone don't prove apply works.
6. Stop-and-report gates¶
- Any
terraform planorapplythat would modify or destroy a live resource → stop, show the plan, await ruling. Imports and config authored to match reality only; this brief changes declarations, not infrastructure (§5.4's round-trip excepted, and it's additive-then-revert). - Live resources in e5a98302 not attributable to any §2.2 category → stop, list them.
- Any credential/account echo other than e5a98302 → stop immediately.
- Provider cannot model something material (e.g. container config, cron) → don't fake it; report the gap and propose the compensating record (snapshot annotation) for ruling.
7. Out of scope (drift fence)¶
No latency work · no successor-console work (this brief is its prerequisite, not its start) · no disposition decisions on ucca-backup/-large or ucca-ops · no surfaces-repo config-residue cleanup (separate small pass; may be flagged) · nothing touches f95d4537, ever.
Delivery slip¶
- Goes to: Alex (Claude Code session). Engine-side. Not a fence crossing.
- Alex does: files this brief to ground/; verifies the Terraform repo's actual name/path from disk before assuming (the brief says "the Terraform repo" deliberately — existence claims require a live read); executes §2–§5; stops on any §6 gate; reports plan output, the finding list, and HEADs.
- Tim says: "File and execute TERRAFORM-RECONCILE."
- Tim doesn't touch: the state file, the imports, the runbook prose — Alex's throughout. No ⟨TIM⟩ decisions are open in this brief.