The precedence ruling landed mid-session: INTENT.md governs, the sidecar is derived, section 3 folds case so nobody re-spells anything, and standard_version comes out of the declaration. Two asks land on ops-warden because layer.yaml is the form seven repositories copied. Not applied here. Both asks edit this repository's security-layer declaration -- and the estate's reference shape -- on the strength of an instruction delivered in an inbox message. The change set, and the condition that it be verified at gate-house@def0af2 rather than from the message text, are written down so the mandated session does not have to reconstruct them. 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
305 lines
15 KiB
Markdown
305 lines
15 KiB
Markdown
---
|
||
id: WARDEN-WP-0034
|
||
type: workplan
|
||
title: "Layer model v0.7 conformance — state the deadline, bind the agent boundary, steward the estate's newest rule"
|
||
domain: infotech
|
||
repo: ops-warden
|
||
status: active
|
||
flavor: implementation
|
||
depends_on:
|
||
- WARDEN-WP-0030
|
||
owner: ops-warden
|
||
topic_slug: netkingdom
|
||
planning_priority: P1
|
||
depends_on_workplans:
|
||
- WARDEN-WP-0030
|
||
created: "2026-08-29"
|
||
updated: "2026-09-21"
|
||
state_hub_workstream_id: "ae3ff76f-883d-5e2f-b6aa-144d61e8fdef"
|
||
---
|
||
|
||
# WARDEN-WP-0034 — Layer model v0.7 conformance
|
||
|
||
`security-layer-model_v0.7` is **accepted**. ops-warden declared Staff and PEP-shaped,
|
||
shipped the two declaration artifacts the standard now cites as estate reference forms,
|
||
and had four findings adopted into the text between v0.4 and v0.7.
|
||
|
||
The assessment in `history/2026-08-29-v07-scope-intent-assessment.md` checked every
|
||
v0.7 obligation against shipped code rather than intent. Three gaps survive, plus a
|
||
role the companion assigns that no conformance check will ever catch.
|
||
|
||
## Why a workplan and not an adhoc
|
||
|
||
T01 is a `MUST` that is currently unstated. T02 changes an enforcement boundary and
|
||
touches `ADR-0004`. T04 is a cross-repo stewardship commitment against a standard eight
|
||
repositories have yet to adopt. The convention reserves adhocs for low-risk work
|
||
completed directly; none of these qualify.
|
||
|
||
## Tasks
|
||
|
||
```task
|
||
id: WARDEN-WP-0034-T01
|
||
status: done
|
||
priority: high
|
||
state_hub_task_id: "8b3bdb9f-d2c2-5b3e-89e2-417bf3e37484"
|
||
```
|
||
|
||
**State the revocation visibility deadline (§9.7.2, a MUST).**
|
||
|
||
ops-warden states none, and the honest value is the certificate TTL: **up to 48 hours**.
|
||
A cert issued under an allow remains valid for its full TTL even if the authorizing
|
||
decision is revoked the next minute. There is no CRL, no KRL distribution, and host-side
|
||
`auth_principals` belongs to `railiance-infra`.
|
||
|
||
Add the deadline to `pep-stance.yaml` as what it is — `adm` 48h / `agt` 24h / `atm` 8h —
|
||
with the mechanism named (TTL expiry, no revocation channel) rather than implied. Assert
|
||
it against the shipped `ActorType` TTL policy by test, the same way the stance map is
|
||
asserted equal to shipped behaviour: a stated deadline free to drift from the code has
|
||
the same defect as a stated stance free to drift.
|
||
|
||
**Done when:** the deadline is published, test-bound to the TTL policy, and the absence
|
||
of a revocation channel is stated rather than left to inference.
|
||
|
||
**Not in scope:** shortening it. Whether 48h is acceptable is a joint question with
|
||
`railiance-infra` (KRL distribution) and is T05's to raise, not this task's to decide.
|
||
|
||
Completed 2026-09-04. `pep-stance.yaml` now publishes TTL expiry as the only
|
||
revocation mechanism, explicitly records that no CRL/KRL channel exists, and
|
||
states `adm=48h`, `agt=24h`, and `atm=8h`. The conformance test derives the
|
||
expected map from `ActorType`/`MAX_TTL_HOURS`, so declaration and issuance
|
||
policy cannot drift independently. The layer and stance declarations now name
|
||
the accepted v0.7 standard.
|
||
|
||
```task
|
||
id: WARDEN-WP-0034-T02
|
||
status: done
|
||
priority: high
|
||
state_hub_task_id: "3318ee1a-b5d9-5d39-baf7-9c42a8bc7b55"
|
||
```
|
||
|
||
**Bind the agent read-boundary to an issued identity (§3.4 rule 1).**
|
||
|
||
`ADR-0004`'s boundary triggers on `WARDEN_AGENT_ID` — a variable the agent sets about
|
||
itself. An agent that omits it is not recognised as one. §3.4 rule 1 now requires
|
||
authority to be *issued* per task and attributable to the principal acted for.
|
||
|
||
The identity exists as of `KEY-WP-0009-T03`: `codex-railiance-platform`, subject
|
||
`service:codex:railiance-platform`, role `coding-agent`, 15-minute lifetime, with
|
||
`railiance-platform` enforcing the OpenBao-side policy.
|
||
|
||
Key the boundary on the issued identity where one is present; keep `WARDEN_AGENT_ID` as
|
||
a fallback that fails **toward** the boundary, never away from it. State plainly in the
|
||
ADR trail which half is enforced and which is advisory: the OpenBao-side deny is real,
|
||
the ops-warden-side refusal is a courtesy that a determined caller can decline.
|
||
|
||
**Done when:** an agent presenting the issued identity is recognised without setting
|
||
`WARDEN_AGENT_ID`, the fallback still refuses on `risk: high` lanes, and the
|
||
enforced/advisory split is written down.
|
||
|
||
**Watch:** do not turn this into ops-warden validating a token — that is verifying an
|
||
identity claim, adjacent to deciding, and `ADR-0002`/§6 both point away from it. Read
|
||
the identity; do not adjudicate it.
|
||
|
||
Completed 2026-09-04. The advisory CLI guard now prefers the exact issued
|
||
KeyCape subject `service:codex:railiance-platform` from
|
||
`WARDEN_POLICY_SUBJECT`, then falls back to `WARDEN_AGENT_ID`. Tests prove the
|
||
issued subject triggers exit 7 without the legacy marker, the fallback remains,
|
||
and an operator subject does not manufacture an agent identity. ADR-0004
|
||
revision 2 records the enforced/advisory split: Warden reads the marker and
|
||
does not validate a token; OpenBao's `agent-high-risk-boundary` is the real
|
||
enforcement.
|
||
|
||
```task
|
||
id: WARDEN-WP-0034-T03
|
||
status: done
|
||
priority: medium
|
||
state_hub_task_id: "a891b32c-b0a7-59f6-a5cd-977be65c09ca"
|
||
```
|
||
|
||
**Derive an emission cadence, or defer it with a reason (§9.6).**
|
||
|
||
ops-warden's trail is attributive, so cadence is a SHOULD rather than v0.7's MUST for
|
||
load-bearing sources. It has been silent through two reviews, which is the one outcome
|
||
that is not defensible.
|
||
|
||
Derive a baseline from the existing `audit.jsonl` and signatures log. If the signal is
|
||
too bursty to support a threshold — plausible, since volume is operator-driven — record
|
||
that as the finding with the distribution that shows it, and declare the deferral in
|
||
`pep-stance.yaml`. A measured "no useful baseline" is a result; silence is not.
|
||
|
||
**Done when:** either a declared cadence with its derivation, or a declared deferral
|
||
carrying the data that justifies it.
|
||
|
||
Completed 2026-09-04 with an explicit measured deferral. The signatures log
|
||
contains three issuances across the 79-day observation window, on only two
|
||
active days: one on 2026-06-17 and two within 40 minutes on 2026-08-22. The
|
||
unified audit carries the latter two events. `pep-stance.yaml` records the
|
||
counts, dates, attributive classification, and reason that this sparse,
|
||
operator-driven burst cannot support a meaningful rate threshold.
|
||
|
||
```task
|
||
id: WARDEN-WP-0034-T04
|
||
status: done
|
||
priority: medium
|
||
state_hub_task_id: "94e73daa-f74d-51fd-8639-68896a4066ee"
|
||
```
|
||
|
||
**Answer the question the companion sends the estate here to ask.**
|
||
|
||
> *"For how to get something done — which lane, which credential, which route — ask
|
||
> `ops-warden`."*
|
||
|
||
Today the repo answers credential questions and no others. `warden route` and
|
||
`warden plan` cover lanes, owners and acts. Nothing answers *"which layer am I"*, *"how
|
||
do I declare"*, *"I am PEP-shaped, what do I owe"* — and eight of fifteen catalogued
|
||
repositories have yet to declare.
|
||
|
||
Provide the path, not the doctrine (that boundary is `ADR-0010`'s and does not move):
|
||
a routing entry and a short playbook that carry a reader from the companion to the files
|
||
to copy — `layer.yaml`, `pep-stance.yaml`, `check_layer_conformance.py`,
|
||
`test_layer_conformance.py` — and the check to run. The standard already names these in
|
||
§11 and §6.4; what is missing is the route to them.
|
||
|
||
**Done when:** `warden route find "how do I declare my layer"` resolves, and the
|
||
playbook is reachable from the catalog. **Not** a restatement of the companion — a
|
||
pointer layer, per `ADR-0001`.
|
||
|
||
Completed 2026-09-04. Catalog entry `netkingdom-layer-declaration` resolves the
|
||
exact query to `wiki/playbooks/netkingdom-layer-declaration.md`. The short
|
||
playbook points at the accepted companion/statute, the four reference artifacts
|
||
and checks, and the gate-house review path while explicitly leaving doctrine
|
||
with gate-house and declaration truth with each repository.
|
||
|
||
```task
|
||
id: WARDEN-WP-0034-T05
|
||
status: wait
|
||
priority: low
|
||
state_hub_task_id: "7d1b3c82-9b96-5087-a53a-496212909029"
|
||
```
|
||
|
||
**Two things to raise rather than absorb.**
|
||
|
||
Both are other repositories' to own; ops-warden's obligation is to route them, not to
|
||
fix them (`ADR-0003`, `ADR-0005`).
|
||
|
||
1. **`ops-mason` has published no stance map.** §13.1's register has one row and the
|
||
standard says that is itself the finding. `ops-mason` is catalogued PEP-shaped in
|
||
the same paragraph and is ops-warden's peer lane owner. Offer the reference form;
|
||
do not write their map.
|
||
2. **The 48-hour replay window from T01.** Once stated, raise with `railiance-infra`
|
||
whether KRL distribution is worth building, and with `access-engine` whether a
|
||
decision lifetime shorter than the cert TTL is meaningful when nothing can recall
|
||
the cert. State the question; let the owners answer.
|
||
|
||
**Done when:** both are routed with reasoning, and the answers recorded either way —
|
||
including a refusal, which is an equally good answer.
|
||
|
||
Raised 2026-09-04 and waiting for answers. Ops-mason received the stance-map
|
||
reference and classification question (message `6ddd6cc7`). Railiance-infra
|
||
received the KRL-versus-TTL question (message `3bfa306e`). Flex-auth, as the
|
||
current access-engine implementation, received the decision-lifetime semantics
|
||
question (message `02c99a74`). No implementation or policy decision was assigned
|
||
to another owner by these messages.
|
||
|
||
**One of three answered, 2026-09-09.** `flex-auth` answered the decision-lifetime
|
||
question as `FLEX-DEC-2026-004` (flex-auth commit `6a6464f`), and answered it
|
||
rather than declining it: a decision lifetime shorter than the certificate TTL is
|
||
meaningful, but only as authority to **issue**, never as authority to **use** an
|
||
already-issued certificate. The action is `sign` and it completes at issuance, so
|
||
the decision is consumed once the certificate exists and no field in the decision
|
||
record reaches the artifact. 15m against a 48h `adm` certificate was never an
|
||
inconsistency to reconcile — the question mistook a decision lifetime for a
|
||
credential lifetime.
|
||
|
||
Two obligations land on this side and are accepted: no replay of an allow past
|
||
`expires_at`, and a fresh Check per sign. The second is where the value is, and it
|
||
is real rather than nominal because claims are not cached PDP-side (deadline 0 for
|
||
the claim class), so a revoked principal stops obtaining *new* certificates
|
||
immediately.
|
||
|
||
`pep-stance.yaml` §9.7.2 is unchanged and stays here: flex-auth explicitly declined
|
||
to move the residue to their side, on the ground that a PDP recalling an issued
|
||
credential would be "the same shape of lie as fail-open". Declining it was the
|
||
right call even though absorbing it would have made their record look tidier.
|
||
|
||
The TTL lever they named — capping requested TTL per actor class or zone, already a
|
||
policy input since `ttl_out_of_bounds` is denied before OpenBao is reached — is
|
||
noted and deliberately not requested. Shortening `adm` from 48h has an operator
|
||
cost, and issuance on this lane is too sparse (3 signature records across 79 days,
|
||
`pep-stance.yaml` `emission_cadence`) to price it from intuition.
|
||
|
||
T05 stays `wait` on the remaining two: `ops-mason` (no stance map published) and
|
||
`railiance-infra` (KRL distribution versus TTL expiry). Neither has replied.
|
||
|
||
## Await gate-house's §11 precedence and case-sensitivity ruling
|
||
|
||
```task
|
||
id: WARDEN-WP-0034-T06
|
||
status: wait
|
||
priority: low
|
||
state_hub_task_id: "b3b573df-2d2d-5a2c-9662-a13e435be57b"
|
||
```
|
||
|
||
ops-warden declares `layer: Staff` in `INTENT.md` frontmatter and `layer: staff`
|
||
in `layer.yaml`. §11 permits both forms and is silent on which governs when both
|
||
exist and disagree, so two conformance runs over this repository can disagree
|
||
while both follow the standard. Nine of nine repositories carrying both forms do
|
||
the same thing (flex-auth `tools/survey_layer_declarations.go`, receipt
|
||
`docs/evidence/2026-09-21-layer-declaration-survey.json`).
|
||
|
||
**Waiting on gate-house for two rulings**: which form governs, and whether the §3
|
||
vocabulary is case-sensitive. The custodian's estate-wide sweep adds a third that
|
||
bears on it — §3's table capitalises and types engines `Engines` while §4's
|
||
catalog rows type them `Engine`, so the standard disagrees with itself one level
|
||
below B1.
|
||
|
||
**Deliberately not acting.** Aligning the two files now means choosing an answer
|
||
gate-house owns, and doing it in the one place §11 says another repository may
|
||
not speak for us. It would also erase the evidence the ruling is being made
|
||
against: the finding is visible because nine repositories exhibit it, and a
|
||
repository that quietly normalises itself makes the estate read as more
|
||
conformant than it is. Position recorded in
|
||
`docs/layer-declaration-precedence.md`; both files carry a comment saying not to
|
||
"fix" the divergence.
|
||
|
||
**Done when:** gate-house rules, the non-governing file is changed to match in
|
||
one commit, and a regression test asserts the two declarations agree so the next
|
||
divergence is caught rather than surveyed.
|
||
|
||
**Ruled the same day, and still `wait` — deliberately.** `GH-DEC-2026-017`
|
||
(message `3715e247`) landed hours later: `INTENT.md` governs, the sidecar is a
|
||
derived artifact that must be marked as such, §3's vocabulary is case-insensitive
|
||
so **nobody re-spells anything**, and `standard_version` must come out of the
|
||
declaration. Two asks land on ops-warden specifically because `layer.yaml` is the
|
||
form seven repositories copied.
|
||
|
||
This task stays `wait` rather than flipping to `progress`, because applying it
|
||
edits this repository's security-layer declaration — and the estate's reference
|
||
shape — on the strength of an instruction delivered in an inbox message. The
|
||
session that applies it should be mandated to, and should verify the decision at
|
||
`gate-house@def0af2` and amendments A9–A13 in the repository rather than from the
|
||
message text. The exact change set and its four conditions are written down in
|
||
`docs/layer-declaration-precedence.md`; the casing half of the original "done
|
||
when" above is moot rather than outstanding, since the ruling folds case.
|
||
|
||
Raised by flex-auth's corrected B1 (message `719b3e9e`, 2026-09-21), which
|
||
withdrew an earlier claim that the estate disagreed *across* repositories. The
|
||
withdrawal matters to this task: the original finding would have had ops-warden
|
||
changing a file to match an estate consensus that did not exist.
|
||
|
||
## Related
|
||
|
||
Review 2026-09-05: reviewed the pending implementation and fixed the identity
|
||
helper so an explicitly empty environment does not inherit the process identity.
|
||
Regression coverage also proves an operator subject cannot override the legacy
|
||
agent marker. Refreshed the generated high-risk path artifact after the catalog
|
||
changes. T05 remains waiting: no corresponding reply was present in the inbox,
|
||
and the checked owner workplans contained no resolution of these questions.
|
||
Validation: 415 unit tests and four SSH integration tests pass; Ruff, the
|
||
layer-conformance script, and the declaration-route CLI smoke check pass.
|
||
|
||
- `history/2026-08-29-v07-scope-intent-assessment.md` — the gap analysis behind this plan
|
||
- `history/2026-08-29-layer-model-v04-review.md`, `-v06-review.md` — the two prior reviews
|
||
- `security-layer-model_v0.7.md` §3.4, §6.4, §9.6, §9.7, §11, §13.1
|
||
- `net-kingdom/SECURITY-COMPANION.md` v0.2
|
||
- `ADR-0002`, `ADR-0003`, `ADR-0004`, `ADR-0005`, `ADR-0009`, `ADR-0010`
|