Activate ZONE-WP-0001 and decide exception lifecycle

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a0291a-1e87-7151-9934-fcbfe3f65eb1
This commit is contained in:
tegwick 2026-08-22 13:01:14 +02:00
parent 6f6c893011
commit 11af8095ae
4 changed files with 174 additions and 17 deletions

View file

@ -128,16 +128,17 @@ Their answers are binding on this repo and are recorded in the workplan.
---
## Current state (2026-08-19)
## Current state (2026-08-22)
Seeded and reviewed. **No model, no schema, no runtime** — deliberately: an
engine that ships a wire format before it has partitioned the real estate
defines the model by accident.
`ZONE-WP-0001` is active. T01 confirmed ownership, T02 partitioned the estate,
and T04 selected reviewed declarations with enforcement-time expiry: **no
zone-engine runtime is warranted**. The exception lifecycle is recorded in
`docs/exception-lifecycle-2026-08-22.md`.
`ZONE-WP-0001` carries the work. T01 is answered by both owners; T02T07 are
open. Whether a runtime is warranted is an *output* of T04, and the "no runtime"
answer is a legitimate result that would retire this repo rather than embarrass
it (`GOAL.md` gate 5).
T03 is waiting on a declaration-boundary ruling from `repo-manager` and
`net-kingdom`. The current evidence has nine declared rapp workloads, but only
one of ops-warden's 27 lanes can be joined to one; unknown membership is kept
unknown rather than inferred. No API, storage, or wire schema has been shipped.
---

View file

@ -8,11 +8,11 @@
| Kind | ID | Status | Lane | Source |
| --- | --- | --- | --- | --- |
| workplan | ZONE-WP-0001 | proposed | — | workplans/ZONE-WP-0001-security-zone-model.md |
| task | ZONE-WP-0001-T01 | todo | — | workplans/ZONE-WP-0001-security-zone-model.md |
| workplan | ZONE-WP-0001 | active | — | workplans/ZONE-WP-0001-security-zone-model.md |
| task | ZONE-WP-0001-T01 | done | — | workplans/ZONE-WP-0001-security-zone-model.md |
| task | ZONE-WP-0001-T02 | done | — | workplans/ZONE-WP-0001-security-zone-model.md |
| task | ZONE-WP-0001-T03 | todo | — | workplans/ZONE-WP-0001-security-zone-model.md |
| task | ZONE-WP-0001-T04 | todo | — | workplans/ZONE-WP-0001-security-zone-model.md |
| task | ZONE-WP-0001-T03 | wait | — | workplans/ZONE-WP-0001-security-zone-model.md |
| task | ZONE-WP-0001-T04 | done | — | workplans/ZONE-WP-0001-security-zone-model.md |
| task | ZONE-WP-0001-T05 | todo | — | workplans/ZONE-WP-0001-security-zone-model.md |
| task | ZONE-WP-0001-T06 | todo | — | workplans/ZONE-WP-0001-security-zone-model.md |
| task | ZONE-WP-0001-T07 | todo | — | workplans/ZONE-WP-0001-security-zone-model.md |

View file

@ -0,0 +1,121 @@
# Time-boxed security-zone exceptions — ZONE-WP-0001-T04
**Decision date:** 2026-08-22
**Decision:** the exception lifecycle does not require a zone-engine runtime.
An exception is a temporary relaxation of one control for workloads already
admitted to a named security zone. It does not change membership, lower an
admission floor, or create a temporary-sounding zone. Membership remains a
declared workload fact. The control owner remains the authority for the effect.
## 1. Grant authority
The workload's responsible party may request an exception. Only the authority
designated by the **control owner** may grant it, because that owner owns the
base stance and the enforcement point that must apply the relaxation. For a
failure-mode relaxation, the grant authority is the owner of the policy
enforcement point (PEP), never the PDP.
One person may currently perform both roles in this founder-operated estate,
but the record still names `requested_by` and `granted_by` separately. A
declarer cannot grant itself an exemption merely by changing its zone
membership.
Each control declares a `maximum_exception_duration`. If it declares no
maximum, it permits no exceptions. A grant beyond the declared maximum is
invalid rather than silently shortened.
## 2. Minimum record
This is a conceptual record for the canon draft, not an API or storage schema.
Every implementation must preserve these facts in machine-readable form:
| Fact | Rule |
| --- | --- |
| `exception_id` | Stable and unique; renewed grants get new ids |
| `security_zone` | The admitted zone whose normal rule is being relaxed |
| `control` | Stable owner-qualified control id |
| `workloads` | Authoritative workload ids; an empty or unresolved subject is invalid |
| `base` | The stance and, where relevant, PEP failure mode that auto-restores |
| `relaxation` | Explicit `advisory` or `exempt` stance and/or PEP-side failure mode |
| `justification` | The bounded work that requires the relaxation |
| `requested_by` / `granted_by` | Auditable responsible parties |
| `issued_at` / `not_before` / `not_after` | UTC instants; `not_after` is exclusive |
| `maximum_duration_policy` | Versioned rule against which duration was checked |
| `change_ref` | Reviewed source change that introduced the grant |
A grant may only relax a named control. Promotion to a stricter stance is an
ordinary policy change, not an exception. Wildcard workload scope is forbidden:
the work that needs relief must be named, and unknown membership never inherits
a permissive zone or exception.
## 3. Enforced expiry
At every decision or enforcement attempt, an exception applies only when all of
the following are true:
1. its record is valid and was granted by the control's designated authority;
2. the current authoritative workload and zone match its scope;
3. `not_before <= now < not_after`; and
4. its duration does not exceed the referenced maximum.
Missing, malformed, unresolved, or unevaluable facts make the exception
**inactive**. The enforcement point applies the base stance and failure mode.
Clock failure must never preserve the relaxation.
Expiry is an automatic return to the base rule. It does not block waiting for a
renewal, and it does not require a commit, image rebuild, rollout, scheduler, or
human reminder. Renewal is a new reviewed grant with a new id; the expired
record remains in history.
No authority created under an exception may outlive it. A certificate, token,
lease, session, or other durable result must have an expiry no later than the
exception's `not_after`, or the enforcement point must re-evaluate the exception
before each use. Otherwise the timestamp would expire while its effect remained
live.
## 4. Placement by control
| Control kind | Grant representation | Expiry evaluator | Required evidence |
| --- | --- | --- | --- |
| flex-auth decision | Versioned flex-auth policy package | Rego decision time (`time.now_ns()`) | Decision envelope includes policy package/version and active exception id/expiry |
| ops-warden CLI decision | Versioned ops-warden control data | CLI at each invocation | Verdict `reasons` includes active exception id/expiry |
| PEP failure mode | Versioned consumer configuration | PEP when the PDP/control is unreachable | PEP audit record includes exception id/expiry and fallback taken |
This placement preserves the authority boundary: zone-engine standardizes the
lifecycle, while each control owner represents and evaluates the effect where
that control already runs. In particular, fail-open cannot be implemented by
flex-auth because no PDP decision exists when flex-auth is unreachable.
The current flex-auth deployment loads registry and policy once at process
start. Granting therefore costs rebuild and rollout, but a timestamp evaluated
at decision time still lapses without either. An inert registry flag would not;
it is prohibited for exceptions.
## 5. Visibility
Someone who did not grant an exception must be able to discover it in two
places:
- the reviewed, versioned source record owned with the control, including
expired records in history; and
- the machine-readable decision or verdict whenever the exception changes an
outcome, including `exception_id` and `not_after`.
Control builds must also produce a machine-readable inventory of active and
future grants and reject overlaps that would make the selected relaxation
ambiguous. Near-expiry reporting is useful operationally but is not the expiry
mechanism.
## 6. Runtime decision
A central zone-engine service would not enforce expiry more reliably. It could
not alter flex-auth's digest-pinned, load-once artifacts at the deadline, and a
synchronous lookup would add a new availability dependency while crossing the
PDP authority boundary. The enforcement points already have the clocks and the
decision context needed to make a compiled `not_after` self-expiring.
Therefore T04 selects reviewed declarations plus enforcement-time timestamp
evaluation. `zone-engine` needs a canon contract and conformance fixtures, not a
runtime. This decision can be reopened only if a real adopting control cannot
evaluate time at the point where the relaxation takes effect.

View file

@ -4,12 +4,12 @@ type: workplan
title: "The security zone model — derive it from the estate, draft it as canon"
domain: infotech
repo: zone-engine
status: proposed
status: active
owner: zone-engine
topic_slug: netkingdom
planning_priority: P1
created: "2026-08-19"
updated: "2026-08-19"
updated: "2026-08-22"
state_hub_workstream_id: "a75c8c9c-c108-4831-8d72-4343cce49879"
---
@ -76,7 +76,7 @@ machinery; it does not grow a second vocabulary beside it.
```task
id: ZONE-WP-0001-T01
status: todo
status: done
priority: high
state_hub_task_id: "ea74316e-b711-4888-9b38-553ebc9ad856"
```
@ -91,6 +91,12 @@ the only PDP and consumes compiled membership.
If either disagrees, the model moves and this repo is archived rather than kept
for its own sake. Record the outcome either way.
**Done 2026-08-22.** Both required owners answered on the record below. Their
binding decisions have been carried into `GOAL.md` and `SCOPE.md`: zone-engine
owns identity, membership, and the exception lifecycle; net-kingdom publishes
the canon standard; flex-auth remains the only PDP; membership is compiled data
and stance is owned by the policy or enforcement point that renders the effect.
**flex-auth answered 2026-08-19 (amended by flex-auth).** Confirmed: zone-engine
owns zone identity, membership and exception lifecycle; flex-auth stays the only
PDP. But the invariant as written in `GOAL.md` guards the wrong property. *"Never
@ -263,7 +269,7 @@ those lanes are graded.
```task
id: ZONE-WP-0001-T03
status: todo
status: wait
priority: high
state_hub_task_id: "7f47b750-1ae4-467d-b3c4-064f4ec07dbd"
```
@ -277,6 +283,19 @@ Controls in scope at minimum: the flex-auth pre-sign gate (`policy.enabled`,
`fail_closed`), the agent read-boundary on `risk: high` lanes (ops-warden
`ADR-0004`), and the `warden plan` escalation verdicts.
**Waiting on owner rulings, 2026-08-22.** Re-running
`ops-warden/scripts/report_workload_join.py` finds **nine** declared rapp
workloads, but still only **one of 27 lanes** joins to a workload; 13 name an
undeclared candidate and 13 have no workload-shaped path. The exact residue was
sent to `repo-manager` (declaration ownership/surface) and `net-kingdom`
(whether operational control-plane consumers must acquire workload identities,
and whether unknown is a required result). This is the consultation required by
the 2026-08-20 finding below; stance modelling will not reopen the policy subject
merely to make the corpus fit. In the interim, `RISK-N-0004`'s consumer
requirements are accepted: the resolved view is workload-addressable,
authoritative, machine-readable, exposes guarantees as well as membership, and
returns unknown without inference.
**Operator direction 2026-08-19 — defaults derive from maturity, not from
nothing.** An ungraded lane must not inherit the safest-for-the-tool default; it
should inherit the default its *maturity context* implies. Early or experimental
@ -473,7 +492,7 @@ not, and a model that implies otherwise will be built and then not work.
```task
id: ZONE-WP-0001-T04
status: todo
status: done
priority: high
state_hub_task_id: "1c542ca5-2b82-4778-a3e4-c76e932423c9"
```
@ -491,6 +510,22 @@ happens at expiry — auto-revert, or block until renewed.
If T04 concludes the lifecycle can live as reviewed declarations in git, say so
plainly and drop the runtime. That is a valid and cheaper outcome.
**Done 2026-08-22.** The lifecycle and runtime decision are recorded in
`docs/exception-lifecycle-2026-08-22.md`. A grant is a reviewed,
machine-readable relaxation for named workloads, one zone, and one control;
only the control owner's designated authority may grant it, within that
control's declared maximum duration. The enforcement point applies it only for
`not_before <= now < not_after`, falls back to the base rule on any invalid or
unevaluable fact, stamps the active exception into its decision/verdict, and
caps any durable credential or session so no granted authority outlives the
exception. Expiry auto-restores the base rule; renewal is a new grant.
**No runtime is warranted.** flex-auth policy evaluates time in Rego; CLI and
PEP controls evaluate it on invocation. A central service could neither reload
flex-auth's digest-pinned artifacts nor improve deadline enforcement without
adding a synchronous availability and authority boundary. Git review plus
enforcement-time evaluation is the cheaper and stronger result.
**Hard constraint from flex-auth 2026-08-19 — the PDP has no reload path.**
`cmd/flex-auth/main.go:447` calls `registry.LoadFile` once at process start.
There is no watcher, no SIGHUP, no reload endpoint. Both the registry snapshot