Date: 2026-07-25. Branch: dc-dc-stage4-phase3-maas-deploy. Status: ADVISORY / planning input. Adopts nothing. docs/CURRENT-STATE.md remains the sole status authority (GA-R1). Authored in the Chat design seat; PINNED for a dedicated operator planning session. Companion to: docs/audit/decision-recon-20260725.md, docs/audit/committee-20260724-track2-bundle-render.md, and the PROPOSED NetBox-coupling decision in docs/design-decisions.md.
A PLAN, not a decision. Deliberately NOT a D-NNN entry: the operator asked for a recommendation plus a dedicated planning session, so the target operating model is not ripe for ratification. Implement NOTHING from this file.
Authored against repo HEAD bc9a2df.
================================================================================
================================================================================
Draft changes in NetBox -> a tool or queued item reads the changes; operator approves before anything begins -> OpenTofu / MAAS / Juju (whichever the change requires) processes the deployment, assignment or change -> the process is as automated and self-healing as possible without operator interaction -> operator is notified on completion, with logs entered and artifacts created -> operator is given next-step instructions derived from the process
This is the standard source-of-truth-driven infrastructure automation shape. The three recommendations below are refinements to it, not a different mechanism.
================================================================================
================================================================================
Approving "someone changed a prefix in NetBox" does not tell the operator what will happen to the cloud. Approving "here is the resulting overlay diff, the tofu plan, and the validator report" does.
NetBox draft -> renderer emits artifacts onto a git branch -> THE BRANCH DIFF IS THE CHANGE REQUEST -> operator approves the diff -> apply (tofu -> MAAS -> Juju, each gated as today)
git revert); audit for free (the diff IS the record, with reviewer and timestamp attached).================================================================================
================================================================================
SAFE, unattended -- CONVERGENT RE-ASSERT of declarative state:
provider-bundle-check.py, cloud-assert.sh) These read, compare and report. Run them on a timer.NOT SAFE unattended -- AUTONOMOUS REMEDIATION of observed drift:
RECOMMENDATION: self-healing is READ / VERIFY / REPORT plus idempotent re-assert. Drift detection emits an alert AND a proposed remediation diff; the mutation stays gated. The automation's job is to make the operator's decision instant and well-evidenced, not to make it unnecessary.
================================================================================
================================================================================
No NetBox branching plugin is required. Code built the source separation in bc9a2df:
netbox/prod-draft-dump.py -> netbox.baldurkeep.com, FROZEN v1 reference (4.5.8), read-only for the duration of VR1 netbox/office1-record-dump.py -> office1-netbox 10.10.1.10:8000, the VR1 WORKING APEX / "the RECORD" (4.6.4). Read-only, token from environment, never embedded or printed, one script per SOURCE so the source can never be confused netbox/draft/vr1-draft.json (draft) vs netbox/draft/vr1-office1-current-20260725.json (record snapshot)
So: DIFF DRAFT AGAINST RECORD, and that diff is the intent change feeding the same approval gate in section 2. Low-tech, already committed, keeps write-back deferred per DOCFIX-195, and adds no new dependency to the airgap mirror (D-107).
================================================================================
================================================================================
GitBucket has no Actions-style CI runner, so "the renderer runs automatically" needs a host: a jumphost systemd timer, or a NetBox webhook plus a worker. Either way an automated push needs a GitBucket credential over HTTPS basic auth, because SSH access is v2-deferred. That is a security-ledger row (credential scope, storage, rotation), NOT a design decision, and it should be opened before any automated push exists.
SEQUENCING NOTE: the operator intends to migrate from GitBucket to an in-house product, SpryGit. The runner and API surface this operating model needs are therefore REQUIREMENTS INPUT for SpryGit -- captured in docs/audit/sprygit-requirements-inputs-20260725.md. Do not design around GitBucket's current limits as if they were permanent.
================================================================================
================================================================================
================================================================================
================================================================================
The operator asked for best-practice workflow options grounded in real-world documentation and processes used by datacenters running this stack. That research has NOT been done; nothing in this file is its result. Candidate sources:
terraform-provider-juju; Juju bundle/overlay lifecycle practice.For each: what the pattern is, who runs it at datacenter scale on this stack, where the approval gate sits, what it automates unattended, and what it deliberately refuses to automate. Deliverable: options with trade-offs plus a recommendation measured against the Roosevelt-delta fitness function.