# Guarded Kubernetes plane automation `ops-mason plane` constructs small security foundations from an immutable, reviewed bundle. It is not a general Kubernetes deployment wrapper. ## Safety model Every bundle declares its exact object identities, source revisions, expected cluster context, namespace, dependency assertions, forbidden kinds, manifest hashes, approved construction plan, and evidence destination. Read-only commands (`render`, `preflight`, `verify`, `rollback-plan`) do not require approval. `apply` refuses unless all of these hold: 1. the construction plan is `status: approved` and names its approver/date; 2. `--confirm` exactly matches the plan ID; 3. `--expect-digest` exactly matches the freshly rendered bundle digest; 4. the repository is committed and clean; 5. the Kubernetes context, create RBAC, live-object drift, dependency assertions, client validation, and available server validation pass; 6. the bundle contains exactly the allowlisted objects, no Pod or Secret, no `data`/`stringData`, no cross-namespace object, and no token-bearing ServiceAccount. The executor applies one pinned manifest at a time with server-side apply and field manager `ops-mason`. Namespaced manifests receive server dry-run after the Namespace exists and before they are persisted. A failed partial apply is reported; the executor does not automatically delete a Namespace. Successful apply immediately performs metadata-only verification, checks that no Pod or Secret exists in the plane namespace, and writes JSON evidence with object UIDs/resource versions and generated rollback commands. It never reads or records a Secret value. ## Commands ```bash ops-mason plane render --bundle bundles/.yaml ops-mason plane preflight --bundle bundles/.yaml ops-mason plane apply --bundle bundles/.yaml \ --confirm \ --expect-digest ops-mason plane verify --bundle bundles/.yaml ops-mason plane rollback-plan --bundle bundles/.yaml ``` Rollback output is a plan, never an action. Review live inventory immediately before using it. ## Readiness gate `apply` checks `ops_mason.readiness.inspect_readiness` after approval/digest checks and before any Kubernetes command. `preflight` reports the result even when direct apply would be refused. | Verified target state | Direct apply under APPROVED | | --- | --- | | declared, installed, verified | Allowed with the existing approved-plan checks | | production-approved, including a later evidence lapse | Refused; use the manifest repository and ArgoCD | | deprecated | Retains the previous tier; missing history means production | | missing, unknown, invalid or stale readiness | Production; refused | | whitehat namespace, explicit founder placement of 2026-09-21 | Non-production, until a binding supersedes the placement | | rapp-policy-nexus, production tier | Transition only before 2026-12-21; evidence labels it production | ArgoCD now exists on railiance01, so the historical blanket transition for all production targets is not enabled. The policy-nexus transition remains bounded by its review date. The gate does not decide authorization or contact an authorization engine. Bundles include a reviewed namespace-to-binding mapping and a source pin: ```yaml readiness: target: {kind: rapp, rapp_id: rapp-user-engine, namespace: user-engine} source: repo: reef-railiance path: bindings/rapps.yaml revision: sha256: ``` The approved bundle is the mapping record: the namespace must match its object scope, and any namespace mapping in the source must agree. The only explicit namespace placement is `kind: namespace, namespace: whitehat` for bundle `whitehat-foundational-plane`, using the same pinned source so a newly declared whitehat binding invalidates the placement. Other namespace-only targets and platform objects remain production-tier. Use `--readiness-repo /path/to/reef-railiance` on `preflight` or `apply` to locate the source; the default is the sibling checkout. The gate verifies its file digest, commit ancestry, unchanged content through local HEAD, clean source file, and complete Git history. Refresh that checkout before review: the gate checks local HEAD, not an unfetched remote. Missing source/history fails closed. Any production approval in the reachable file history retains production tier; a deliberate re-scope needs a separately reviewed gate change, not just lowering the readiness field. Source pins and mapping changes alter the bundle digest and need fresh review/confirmation. Existing live evidence remains historical. For emergency direct apply, keep all normal plan/digest requirements and add: ```bash ops-mason plane apply --bundle bundles/.yaml \ --confirm --expect-digest \ --activation BREAK_GLASS --break-glass-reason '' ``` The JSON evidence and CLI output record activation, local executing account, time, reason, resolved tier/source, and the obligation to commit the same change to the manifest repository ArgoCD reconciles. The command does not open that change or grant emergency authority itself. An empty reason is refused.