Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 63291@bnt-lap001 Assistant-Session: 8bd77868-ca68-4f49-bb1e-d539ecc0d703
8.1 KiB
| id | type | title | domain | repo | status | flavor | owner | topic_slug | created | updated | state_hub_workstream_id |
|---|---|---|---|---|---|---|---|---|---|---|---|
| MASON-WP-0006 | workplan | Check the target's readiness tier before a direct Kubernetes apply | infotech | ops-mason | proposed | implementation | claude | ops-mason | 2026-09-21 | 2026-09-21 | 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 isdeclared,installedorverified; - 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-nexusunder the transition, which runs until 2026-12-21. Each such change keepsactivation=APPROVEDand is recorded as production-tier, so the transition does not look like conformance.
- under
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,
PodandSecretrefused, nodataorstringData. 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:
-
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.
-
Vendor a copy of
rapps.yamlinto ops-mason. Pinned, but it goes stale silently. A rApp promoted toproduction-approvedupstream would still read asverifiedhere and pass the gate: the failure mode is fail-open. -
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:
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.yamlmust hash tosha256;git -C <reef-railiance> diff --quiet <revision> HEAD -- bindings/rapps.yamlmust 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_statefor the target is read from the pinned content.
Fail closed. A missing
readinessblock,kind: platform, a target not listed inrapps.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-repoCLI 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
id: MASON-WP-0006-T01
status: wait
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.targetnames that record; or - (c) an explicit, dated exception.
T03 must not merge before this is answered.
Extend the bundle schema with the readiness block
id: MASON-WP-0006-T02
status: todo
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.
Enforce the tier in preflight and apply
id: MASON-WP-0006-T03
status: todo
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
verifiedrApp target applies underAPPROVED(non-production tier); - a
production-approvedtarget is refused underAPPROVED, with nokubectl applycall made; - the same target is allowed under
BREAK_GLASS, and the evidence records it; rapp-policy-nexusis allowed underAPPROVEDon 2026-12-20, is recorded withtransition: trueand tier production, and is refused on 2026-12-22;- no
readinessblock,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/stringDataand namespace tests still pass unchanged.
Record BREAK_GLASS and its reconcile-back obligation
id: MASON-WP-0006-T04
status: todo
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.
Update the docs and the declaration
id: MASON-WP-0006-T05
status: todo
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.
Review on 2026-12-21
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.