Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a0e75a-fc5c-7913-9dba-9846210c766d
233 lines
9.7 KiB
Markdown
233 lines
9.7 KiB
Markdown
---
|
||
id: MASON-WP-0006
|
||
type: workplan
|
||
title: "Check the target's readiness tier before a direct Kubernetes apply"
|
||
domain: infotech
|
||
repo: ops-mason
|
||
status: blocked
|
||
flavor: implementation
|
||
owner: claude
|
||
topic_slug: ops-mason
|
||
created: "2026-09-21"
|
||
updated: "2026-09-28"
|
||
state_hub_workstream_id: "1b900161-51ff-544f-8412-ba7fcab64bb5"
|
||
---
|
||
|
||
# MASON-WP-0006 — Check the target's readiness tier before a direct Kubernetes apply
|
||
|
||
## Goal
|
||
|
||
Make phase 4 enforce the founder's Kubernetes change-gate decision
|
||
(`the-custodian/docs/kubernetes-change-gate-decision.md`, 2026-09-21, the
|
||
founder exercising `GOVERN @ estate`). Before any direct
|
||
`ADMINISTER @ realm:kubernetes/railiance01`, `ops-mason plane apply` must
|
||
establish the target's railiance-master ADR-0006 `readiness_state` and:
|
||
|
||
- allow a direct apply under `activation=APPROVED` (founder plan approval) when
|
||
the target is `declared`, `installed` or `verified`;
|
||
- refuse a direct apply to a production-tier target (`production-approved`, or
|
||
no readiness state at all), except:
|
||
- under `activation=BREAK_GLASS`, which is recorded and must be reconciled
|
||
back into the manifest repository afterwards; or
|
||
- for `rapp-policy-nexus` under the transition, which runs until 2026-12-21.
|
||
Each such change keeps `activation=APPROVED` and is recorded as
|
||
production-tier, so the transition does not look like conformance.
|
||
|
||
The production path itself (`CONSTRUCT @ manifest repository`, reconciled by
|
||
ArgoCD) belongs to railiance-platform. ops-mason only refuses; it does not
|
||
build that path.
|
||
|
||
## Boundaries
|
||
|
||
- **The executor's limits are not widened.** One expected namespace per plan,
|
||
`Pod` and `Secret` refused, no `data` or `stringData`. The decision relies on
|
||
them; widening any of them is a new founder decision.
|
||
- The readiness check is a quality gate, not an authorization decision. It does
|
||
not consult access-engine and must not be described as a PDP.
|
||
- No live change is part of this workplan. Tests use the injected runner.
|
||
|
||
## Design choice: how ops-mason obtains the readiness state
|
||
|
||
The authoritative states live in another repository,
|
||
`reef-railiance/bindings/rapps.yaml`. Three options were weighed:
|
||
|
||
1. **Read the sibling checkout at apply time.** Simple, but unpinned: the
|
||
evidence would name no revision, and the result depends on whatever the
|
||
workstation happens to have checked out.
|
||
2. **Vendor a copy of `rapps.yaml` into ops-mason.** Pinned, but it goes stale
|
||
silently. A rApp promoted to `production-approved` upstream would still read
|
||
as `verified` here and pass the gate: the failure mode is fail-open.
|
||
3. **Pin the reference in the bundle and verify it against the source at
|
||
preflight (chosen).** The bundle names the target and pins the readiness
|
||
source the same way it already pins manifests:
|
||
|
||
```yaml
|
||
readiness:
|
||
target: {kind: rapp, rapp_id: rapp-user-engine} # or {kind: platform}
|
||
source:
|
||
repo: reef-railiance
|
||
path: bindings/rapps.yaml
|
||
revision: <commit>
|
||
sha256: <digest of the file at that commit>
|
||
```
|
||
|
||
Preflight, through the existing runner:
|
||
- `git -C <reef-railiance> show <revision>:bindings/rapps.yaml` must hash to
|
||
`sha256`;
|
||
- `git -C <reef-railiance> diff --quiet <revision> HEAD -- bindings/rapps.yaml`
|
||
must show the file unchanged since the pin, so a later promotion cannot be
|
||
missed. If the file changed, the bundle is re-pinned through review;
|
||
- the `readiness_state` for the target is read from the pinned content.
|
||
|
||
**Fail closed.** A missing `readiness` block, `kind: platform`, a target not
|
||
listed in `rapps.yaml`, a source that cannot be found or verified, or an
|
||
unknown state value all resolve to the production tier. The decision says
|
||
platform objects without a readiness state default to production; an
|
||
unverifiable state is treated the same way.
|
||
|
||
The checkout location comes from a `--readiness-repo` CLI option, defaulting
|
||
to the sibling path `../reef-railiance`. It is a location, not a trust
|
||
anchor: the pinned revision and digest are.
|
||
|
||
The evidence record gains a `readiness` section: target, source repo, revision
|
||
and digest, resolved state, tier, `activation`, and a `transition` flag when the
|
||
policy-nexus rule was used.
|
||
|
||
## Open question for the founder: the whitehat plane
|
||
|
||
```task
|
||
id: MASON-WP-0006-T01
|
||
status: done
|
||
priority: high
|
||
state_hub_task_id: "7b6fe7b4-08f7-5ad0-899d-a4862b5ddb00"
|
||
```
|
||
|
||
`bundles/whitehat-foundational-plane.yaml` is the only bundle today, and its plan
|
||
is `built`. It targets the `whitehat` namespace, which is not a rApp and carries
|
||
no ADR-0006 `readiness_state`. Under the decision it therefore defaults to the
|
||
production tier, and once T03 lands, a further direct apply of it would be
|
||
refused.
|
||
|
||
This workplan was told the check must not change behaviour for today's
|
||
non-production plans. Whether the whitehat plane is one of them is not a
|
||
question ops-mason can answer for itself. The founder chooses one of:
|
||
|
||
- (a) it is a platform object and production-tier, as the default says; future
|
||
changes to it go through the manifest repository or `BREAK_GLASS`;
|
||
- (b) it gains a readiness state from its owner (whitehat-security), in which
|
||
case `readiness.target` names that record; or
|
||
- (c) an explicit, dated exception.
|
||
|
||
T03 must not merge before this is answered.
|
||
|
||
**Resolved 2026-09-21; implemented 2026-09-28.** The founder chose explicit
|
||
non-production placement for namespace whitehat. Decision and inbox receipt
|
||
are recorded in the September 28 review. This unblocks T03.
|
||
|
||
## Extend the bundle schema with the readiness block
|
||
|
||
```task
|
||
id: MASON-WP-0006-T02
|
||
status: done
|
||
priority: high
|
||
state_hub_task_id: "89d07bd5-5a92-5a06-9ecb-441799c14dd7"
|
||
```
|
||
|
||
Add the optional `readiness` block to `PlaneBundle.load` as described above. It
|
||
is included in the bundle digest, as the bundle file already is. Add a
|
||
`--activation {APPROVED,BREAK_GLASS}` option to `plane apply`, defaulting to
|
||
`APPROVED`, and a `--readiness-repo` option. `BREAK_GLASS` requires a
|
||
`--break-glass-reason` string. No existing refusal is relaxed.
|
||
|
||
**Done 2026-09-28.** Schema/CLI implemented; the mapping also requires an
|
||
explicit namespace matching the bundle. Whitehat now pins the source used to
|
||
check whether a binding supersedes its explicit placement.
|
||
|
||
## Enforce the tier in preflight and apply
|
||
|
||
```task
|
||
id: MASON-WP-0006-T03
|
||
status: done
|
||
priority: high
|
||
state_hub_task_id: "163a807b-29aa-5eb7-a9a8-ef1ac70c89d3"
|
||
```
|
||
|
||
Add a pure function, `resolve_tier(state, target, activation, today)`, returning
|
||
the tier and whether a direct apply is allowed, and call it from `apply` after
|
||
the plan-approval and digest checks and before any `kubectl` write. `preflight`
|
||
reports the resolved tier without refusing, so a production-tier plane can
|
||
still be validated.
|
||
|
||
Tests, all against the injected runner:
|
||
|
||
- a `verified` rApp target applies under `APPROVED` (non-production tier);
|
||
- a `production-approved` target is refused under `APPROVED`, with no `kubectl
|
||
apply` call made;
|
||
- the same target is allowed under `BREAK_GLASS`, and the evidence records it;
|
||
- `rapp-policy-nexus` is allowed under `APPROVED` on 2026-12-20, is recorded
|
||
with `transition: true` and tier production, and is refused on 2026-12-22;
|
||
- no `readiness` block, `kind: platform`, an unlisted rApp, a digest mismatch,
|
||
and a file changed since the pin each resolve to production and are refused;
|
||
- the existing forbidden-kind, `data`/`stringData` and namespace tests still pass
|
||
unchanged.
|
||
|
||
**Done 2026-09-28.** Source digest, ancestry, local freshness and complete
|
||
binding history are checked. Historical production approval remains production;
|
||
deprecation retains the last known tier. Unknowns fail closed. The policy-nexus
|
||
transition stops on December 21 itself. Preflight reports; apply refuses before
|
||
Kubernetes commands. Covered by injected-runner regression tests.
|
||
|
||
## Record BREAK_GLASS and its reconcile-back obligation
|
||
|
||
```task
|
||
id: MASON-WP-0006-T04
|
||
status: done
|
||
priority: medium
|
||
state_hub_task_id: "66349531-09ee-55b9-be47-537842c80f3b"
|
||
```
|
||
|
||
A `BREAK_GLASS` apply writes its reason, actor and time into the evidence
|
||
record and prints the follow-up that is owed: the same change, committed to the
|
||
manifest repository that ArgoCD reconciles. ops-mason does not open that change
|
||
itself.
|
||
|
||
**Done 2026-09-28.** Apply evidence and printed JSON include the emergency
|
||
reason, local account, UTC time and GitOps reconciliation obligation. Empty
|
||
reasons are refused without invoking the runner.
|
||
|
||
## Update the docs and the declaration
|
||
|
||
```task
|
||
id: MASON-WP-0006-T05
|
||
status: done
|
||
priority: medium
|
||
state_hub_task_id: "6d64e7f5-9cff-5bf9-9851-97d318d1df0a"
|
||
```
|
||
|
||
Update `docs/kubernetes-plane.md` with the tier table and the readiness block,
|
||
and change the `enforcement` line of the `kubernetes-plane-apply` entry in
|
||
`INTENT.md` from "not yet in code" to point at the check.
|
||
|
||
**Done 2026-09-28.** Documented tiers, pins, mapping, history, checkout
|
||
freshness limits and emergency procedure; removed the withdrawn
|
||
rail-kubernetes ownership/layer assertion from INTENT.md.
|
||
|
||
## Review on 2026-12-21
|
||
|
||
```task
|
||
id: MASON-WP-0006-T06
|
||
status: wait
|
||
priority: medium
|
||
state_hub_task_id: "49dd5f9a-307b-5baf-809e-bd3893c73341"
|
||
```
|
||
|
||
On 2026-12-21 the policy-nexus transition ends and the plan-approval exception
|
||
comes up for review. Confirm with railiance-platform that policy-nexus is
|
||
onboarded to ArgoCD. The date check in T03 ends the transition in code on that
|
||
date either way.
|
||
|
||
## Loose-end review — 2026-09-28
|
||
|
||
T01–T05 are done: the founder resolved the whitehat placement and the guarded readiness implementation, tests, emergency evidence and docs are complete. T06 remains wait until the 2026-12-21 platform/exception review; this workplan is blocked on that dated review.
|
||
|
||
Evidence and precise resumption conditions: [review](../docs/evidence/2026-09-28-loose-end-review.md). Existing tasks retain all remaining obligations; no new task or workplan was opened.
|