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>
This commit is contained in:
parent
e3d0d13253
commit
9ba6e65654
2 changed files with 17 additions and 5 deletions
|
|
@ -14,7 +14,7 @@ The question is what gates `ADMINISTER @ realm:kubernetes`, and whether that gat
|
|||
|
||||
## 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 Kubernetes API stays a Tooling contact, owned by `rail-kubernetes`.
|
||||
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.
|
||||
|
||||
|
|
@ -24,7 +24,11 @@ The question is what gates `ADMINISTER @ realm:kubernetes`, and whether that gat
|
|||
| `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 |
|
||||
|
||||
Platform objects that carry no readiness state default to the production tier.
|
||||
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.
|
||||
|
||||
|
|
@ -47,9 +51,17 @@ ops-mason's executor is narrower than a generic `kubectl apply`:
|
|||
|
||||
This decision relies on those limits. Widening them is a new decision.
|
||||
|
||||
## Not verified here
|
||||
## Not verified here, and possibly not true
|
||||
|
||||
Whether ArgoCD is currently syncing on railiance01 could not be checked from the workstation, whose kube context is not the production cluster. The production row assumes ArgoCD works as its repository declares.
|
||||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ ops-mason's construction plans are drafted and self-reviewed by an agent, then a
|
|||
|
||||
- **Only these changes are covered.** The exception covers the phase-4 actions listed above, as ops-mason declared them in its INTENT.md frontmatter on 2026-09-21 (ops-mason@0ff263a). A new class of protected change is not covered until the founder accepts it.
|
||||
- **Structure only.** ops-mason's own declared capability is "structure only, never secret values". The exception depends on that holding.
|
||||
- **Review 2026-12-21.** That is the date ops-mason already set on the gaps. At review, the founder either renews the exception or asks for these writes to route through access-engine.
|
||||
- **Review 2026-12-21.** That is the date ops-mason already set on the gaps. At review, the founder either renews the exception or asks for these writes to route through access-engine. That choice does not extend to `kubectl apply`: `docs/kubernetes-change-gate-decision.md` ruled it a quality gate, not an authorization decision, so it never routes through access-engine. gate-house GH-DEC-2026-022 noted the conflict between the two records, and this sentence resolves it.
|
||||
- **Still declared.** The gaps stay declared, not removed, and are marked accepted rather than open. A conformance run must report them as accepted exceptions, not as conformance.
|
||||
|
||||
## Consequences for other records
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue