ops-warden/workplans/WARDEN-WP-0034-layer-model-v07-conformance.md
tegwick 3aedd8f844
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 2s
docs: record the answers received and the questions routed
Six inbound messages attended, three of them carrying real asks.

flex-auth FLEX-DEC-2026-004 answers WARDEN-WP-0034-T05's decision-lifetime
question: a decision lifetime shorter than the certificate TTL is meaningful,
but only as authority to ISSUE, never to USE an already-issued certificate.
The question had mistaken a decision lifetime for a credential lifetime. They
declined to move the §9.7.2 revocation residue to their side; that refusal is
right and the stance map is unchanged. T05 still waits on ops-mason and
railiance-infra.

WARDEN-WP-0039-T03 routed to flex-auth: is there an admitted contract for a
delegated credential read where caller and resource owner differ? Three
outcomes named as equally acceptable, including that there should be no such
contract and the interim proxy transport is itself the defect -- which would
shorten WP-0033 rather than block it. Two easy fixes ruled out in writing:
broadening the caller binding, and relabelling resource.system as ops-warden
so the binding matches. The second would make the audit trail assert we own
credentials we deliberately do not, by editing a field instead of making an
argument.

WARDEN-WP-0037: npm path routed to railiance-platform, catalog unchanged
pending their answer. secrets-engine refused to resolve it from a
coordination message and was right; asserting our own pointer is
authoritative because it is ours would route around that. The ask names a
location only, and flags that a `bao kv get` answer would be the 2026-07-16
disclosure vector on a risk: high lane.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013EPuTc18FjU5WFqoSEKH3C

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 1276224@bnt-lap001
Assistant-Session: 426ec497-e1c4-4dd3-b417-dfce1ca1dbc3
2026-09-09 16:40:46 +02:00

246 lines
12 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
owner: ops-warden
topic_slug: netkingdom
planning_priority: P1
depends_on_workplans:
- WARDEN-WP-0030
created: "2026-08-29"
updated: "2026-09-05"
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.
## 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`