the-custodian/docs/kubernetes-change-gate-decision.md
codex 9ba6e65654
Some checks are pending
CI Smoke / host-smoke (push) Waiting to run
CI Smoke / container-smoke (push) Waiting to run
Settle the change gate's edge cases and withdraw an unintended rail-to-layer mapping.
Founder rulings: unmapped targets are production-tier until mapped;
an evidence lapse does not loosen the path; deprecated keeps its tier.
The contact is realm:kubernetes with no layer assigned (statute 20.3 stays
unset per ADR-0009 D4). ArgoCD on railiance01 is unverified; until the
production row has a working path, the transition rule covers every
production-tier target. Resolves the conflict gate-house noted between the
two founder records.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-21 14:38:58 +02:00

6.5 KiB

Kubernetes change gate: tiered by readiness state

Decided by: Bernd Worsch (founder), exercising GOVERN @ estate. Date: 2026-09-21. Recorded by: the-custodian.

Vocabulary: SecurityCanon Mode of Authority v0.2.0 (security-canon/infospace/vocabulary/mode-of-authority/), which is still a draft. Where that vocabulary changes, this record follows it.

This record answers gate-house's open question: which engine, if any, should own ops-mason's contact with the Kubernetes API.

The question, stated in the canon's terms

Applying manifests to a running cluster is ADMINISTER @ realm:kubernetes/railiance01. Changing the manifests is CONSTRUCT @ <manifest repository>. A GitOps controller separates the two: CONSTRUCT produces the definition, and the controller reconciles the cluster to it.

The question is what gates ADMINISTER @ realm:kubernetes, and whether that gate differs between experimental and production workloads.

Decision

  1. No engine owns the contact. The gate is a quality gate on a change, not an authorization decision. railiance-master ADR-0006 already keeps readiness and permission on separate axes: production-approved "is not an authorization decision". So no PDP belongs in this path. The contact is with realm:kubernetes/railiance01. This record assigns no layer to that realm and no layer to any rail. Mapping rails onto layers is statute §20.3, which ADR-0009 Decision 4 deliberately leaves unset. The first version of this record said the contact "stays a Tooling contact, owned by rail-kubernetes". That was an unintended §20.3 mapping, and it is withdrawn.

  2. The gate is tiered by ADR-0006 readiness_state, not by Environment. railiance01 is a single cluster, and every workload on it shares one Environment. The canon's Environment dimension therefore cannot separate experimental from production here. The readiness state can.

    Readiness state of the target Path for a change Activation
    declared, installed, verified Direct ADMINISTER @ realm:kubernetes by ops-mason APPROVED: founder approval of the construction plan
    production-approved CONSTRUCT @ manifest repository, reconciled by ArgoCD (railiance-platform) APPROVED for the change; the merge is the gate
    production-approved, emergency Direct ADMINISTER BREAK_GLASS, recorded, reconciled back into the repository afterwards

    Three rules settle the edges of the table (founder, 2026-09-21):

    • Unmapped targets are production-tier until mapped. The readiness contract defines states only for rails and bound rapps, and nothing yet maps a Kubernetes object or namespace to its binding. So a target without a mapping is production-tier. The friction this creates is deliberate: it is what motivates building the namespace-to-binding mapping (ops-mason MASON-WP-0006, with railiance-master).
    • An evidence lapse does not loosen the path. When a binding's evidence fails or expires, the contract returns it to its last proven state. The change path does not follow it down. Once a binding has reached production-approved, its changes stay on the git/ArgoCD path until the binding is explicitly re-scoped. A lapse weakens the readiness claim, and that is exactly when the gate must not loosen.
    • deprecated keeps the tier it had before deprecation. A deprecated production workload may still carry production traffic until it is removed.
  3. Why production goes through git: the EvidenceBoundary dimension. A direct apply is target-audited: the only evidence of the change is held by the realm being changed. A change through the manifest repository adds external-audited evidence, which survives the actor and the realm. For production that is the property that matters, and it is a statement about evidence, not about trust in ops-mason.

Transition for rapp-policy-nexus

rapp-policy-nexus is production-approved (reef-railiance bindings/rapps.yaml), but ArgoCD does not manage it. Its railiance-apps-root applications are external-secrets, issue-core, openbao-secretstore and target-revenue. So the production path does not yet exist for the one workload that needs it.

  • Until 2026-12-21: changes to policy-nexus keep activation=APPROVED by founder plan approval. Each change additionally records that its target is production-tier, so the transition is visible and does not look like conformance.
  • By 2026-12-21: policy-nexus is onboarded to ArgoCD. From then on, the production row of the table applies to it.

2026-12-21 is the same review date as the ops-mason plan-approval gate, so both come up together.

Scope of ops-mason's contact, as found

ops-mason's executor is narrower than a generic kubectl apply:

  • it confines each plan to one expected namespace;
  • it refuses the Pod and Secret kinds;
  • it rejects any manifest carrying data or stringData.

This decision relies on those limits. Widening them is a new decision.

Not verified here, and possibly not true

Whether ArgoCD runs on railiance01 at all is unverified, and railiance-platform's own records point the other way:

  • Its later records name the controller "coulombcore ArgoCD".
  • Its only health record, "healthy on railiance01", predates the 2026-07-02 correction, before which "railiance01" often meant coulombcore.
  • No evidence records railiance-apps-root syncing on 92.205.62.239.

If ArgoCD is not on railiance01, the production row has no working path there yet. Until one exists, production-tier changes on railiance01 fall under the transition rule in the next paragraph, and installing ArgoCD on railiance01 is a cluster-layer change needing its own go-ahead. railiance-platform RPF-WP-0043-T01 holds the read-only check.

Until the production row has a working path, the policy-nexus transition rule applies to every production-tier target on railiance01, not only to policy-nexus: activation=APPROVED, with each change recorded as production-tier.

Owners

  • gate-house: the open question is answered. No engine owns the contact, and the gate is quality, not authorization.
  • ops-mason: phase 4 checks the target's readiness state and refuses a direct apply to a production-tier target, except under BREAK_GLASS or the policy-nexus transition.
  • railiance-platform: the ArgoCD lane is the production path, and policy-nexus onboarding is due by 2026-12-21.
  • railiance-master: ADR-0006 gains a deploy-path consequence for production-approved.
  • rapp-policy-nexus: the transition and its date.