docs: reconcile delivered scope with intent

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a0291a-1e87-7151-9934-fcbfe3f65eb1
This commit is contained in:
tegwick 2026-08-23 10:42:12 +02:00
parent d6e74a55f6
commit 5ce5117506
2 changed files with 189 additions and 130 deletions

212
SCOPE.md
View file

@ -1,159 +1,111 @@
# SCOPE
> What this repository is about, when it is relevant, and when it is not.
> The argument for its existence is `INTENT.md`; the checkable gates and the
> What this repository can do, when it is relevant, and when it is not.
> The argument for its existence is `INTENT.md`; the completed gates and the
> retirement condition are `GOAL.md`.
---
## One-liner
Authority for security zones — the bands of enforcement rigidity that scope
*where* a control bites, and the lifecycle of time-boxed exceptions that relax
them during deep refactors without leaving a permanent hole.
`zone-engine` is the model-owner and reference-conformance repository for
NetKingdom security-zone identity, membership, admission, and time-boxed
exception semantics. It does **not** run an engine or make policy decisions.
---
## Current lifecycle
## Why this exists
The repository's only workplan, `ZONE-WP-0001`, is finished and has `DoD-Ok`.
All seven tasks are done. The standard is published in `net-kingdom`, two
workload owners have adopted it, a third repository has read the declarations,
ops-warden's global policy switch is retired, and the no-runtime decision is
recorded.
Enforcement controls in this estate have been repo-wide booleans. ops-warden's
flex-auth pre-sign gate (`policy.enabled` with `fail_closed: true`) was the
first to become flippable, and flipping it would have made flex-auth a hard
dependency of every `warden sign` — including the SSH certificates the
ops-bridge tunnels depend on, one of which carries the policy call itself.
Those facts satisfy `GOAL.md`'s success gates and retirement condition. This
repository is therefore **complete and an archive candidate**, not an active
service backlog. Keeping it writable is useful only while the estate wants a
reference implementation and the evidence history here; canon remains the
published source for consumers.
Across an estate under continuous deep refactor, uniform enforcement hardens
exactly the access needed to perform the refactor. The flip was deferred under
ops-warden's `ADR-0006`*enforcement is zone-scoped, never a global flag*
and this repo is what that ADR defers to.
## Capability actually present
---
This repository contains:
## In scope
- the source model and local draft of `security-zones_v0.1`, including the five
zone ids, workload authority boundary, admission semantics, and the initial
owner-qualified control profile;
- the decision record for time-boxed exceptions, including grant authority,
maximum duration, decision-time expiry, durable-authority bounds, and audit
requirements;
- estate-partition and adoption evidence showing the model against the real
inventory and its use by `ops-warden` and `flex-auth`;
- an offline reference resolver, `tools/resolve_zones.py`, which reads one or
more local `tenancy.yaml`-shaped YAML documents, including single-service and
`services:` forms;
- validation of direct workload identity bindings, required membership fields,
review dates, maturity/context floors, and continuity evidence;
- deterministic `satisfied`, `unsatisfied`, or `unknown` admission results,
with no membership inference; and
- a resolved zone, declaration-content digest, and reference projection of the
initial control profile, covered by eight unit tests.
- **Zone identity and admission standards.** What zones exist, and the standard
a **workload** must meet to be admitted to one. Security policy is about the
running workload and whoever answers for it — the repo providing the software
only *suggests*. A zone is a floor a workload qualifies against, not a label
applied to it, and it is the `tenancy-posture` Decision 8.2 tier-minimum
mechanism rather than a new one.
- **Time-boxed exception lifecycle.** A relaxation with an expiry enforced by
something rather than intended, plus the record of who widened what, when,
and until when. **This is the task that decides whether this repo needs a
runtime at all.**
- **The membership declaration**, carried in each repo's `tenancy.yaml` under
the reserved top-level `zones:` key, with `tenancy-posture_v0.1` §6 carried
over verbatim: *accuracy, not altitude*.
- **Drafting the canon standard**, offered to `net-kingdom` for publication in
the family of `tenancy-posture_v0.1` and the `*-engine` boundary contracts.
- **Naming stance vocabulary**`enforced` / `advisory` / `exempt` — as
something owners express, not as something this repo evaluates.
The resolver is a **reference and adoption-proof tool**, not a complete
production compiler. In particular, it accepts already-located declarations;
it does not discover the estate or resolve Repo Manager's cross-repository
`(rapp_id, workload_identity.name, deployable?)` references. Its control rows
are a snapshot of the accepted v0.1 profile, not an authority that can override
the versioned policy and PEP configuration owned by `flex-auth` and
`ops-warden`.
## Out of scope
## Authority boundary
- **Authorization decisions.** `flex-auth` is the PDP and stays the only one.
- **Stance for controls flex-auth decides.** Settled on review: for the
pre-sign gate, stance lives in a flex-auth **policy package**, not in
compiled membership. flex-auth's decision envelope stamps
`matched_policy_version` and `policy_package`, and registry content appears
nowhere in that provenance — stance in the registry would let two decisions
with the same policy version and the same request differ, with nothing in the
audit trail explaining why. **Membership is ours; stance is theirs.**
- **The fail-open / fail-closed axis.** Also settled on review: a PDP returns
an effect. Fail-open describes what a *policy enforcement point* does when
the PDP is unreachable — no decision is rendered, so no compiled data and no
policy rule can reach it. The failure-mode axis is modelled PEP-side, by the
repo that owns the control.
- **`organization_posture`.** Ruled out of the declaration by canon: a
fleet-wide, time-varying scalar describing the estate is not a property of a
declaring service, and a per-repo copy of a global goes stale in as many
places as there are repos. It is an **input** to stance selection, read by
the model, never absorbed into it.
- **Network segmentation.** "Zone" is overloaded; the routing sense is someone
else's word.
- **Substrate placement.** Reefs are `repo-manager`'s. That
`reef-railiance` is single-node and therefore *caps availability* for
everything bound to it is a canon composition defect (`NK-WP-0027`), not a
zone problem — and zone-engine is explicitly not blocked on it.
- **Identity, secrets, tenancy**`key-cape`, OpenBao / `secrets-engine`,
`tenant-engine`.
- **Implementing anyone's controls.** Owners keep them; this model says where
they bite.
- **Publishing canon.** `net-kingdom` owns canon; `policy-nexus` publishes.
---
## Settled by review (2026-08-19)
`ZONE-WP-0001` was reviewed by both affected owners before any modelling began.
Their answers are binding on this repo and are recorded in the workplan.
| Question | Answer | Ruled by |
| Concern | Authority | This repository's role |
| --- | --- | --- |
| A new standard, or a seventh axis of `tenancy-posture_v0.1`? | **Separate standard.** The six axes are ladders where higher is stronger and desirable; enforcement stance is not monotone — `ADR-0006` *is* the finding that the top rung is wrong for the SSH lane. And an accurately declared `exempt` as an axis would be conformant *and* exempt: a conformance rule handing out its own exemption. | net-kingdom, Decision 5.6 |
| Then where is membership declared? | **`tenancy.yaml`, reserved top-level `zones:` key.** One declaration surface, one review cadence, one validator; two standards, because they have different owners and different conformance semantics. | net-kingdom, Decision 5.6 |
| Does membership need a flex-auth schema change? | **No.** Resource `metadata` / `labels` / `attributes` are already flattened into the Rego input, so a compiler emitting a zone field is readable today. | flex-auth |
| Is "never synchronously in a decision path" the right invariant? | **No** — that is a latency guarantee, not an authority one. Replaced: identity and membership here, effect in a flex-auth policy package. | flex-auth |
| Are reefs ours to reconcile? | **No**, and the attempt surfaced a canon defect instead (`NK-WP-0027`). | net-kingdom |
| Workload identity and requested membership | Workload's responsible repo | Defines and reference-validates the contract |
| Zone ids and admission standard | zone-engine model, published by net-kingdom | Maintains the source model and conformance evidence |
| Canon publication | net-kingdom | Offers source material; does not publish canon |
| Control stance | Owner of the control | Records the vocabulary and an owner-qualified reference profile |
| Failure behavior | Owner of the policy enforcement point | Records semantics only |
| Authorization effect | Existing PDP or control owner | Makes no decision |
| Exception grant and expiry | Control owner's designated authority and enforcement point | Standardizes the lifecycle; stores or evaluates no grant |
### Two constraints inherited from that review
The invariant remains: **membership is ours; stance is theirs; the decision
point is neither.** `flex-auth` remains the only PDP for decisions it renders.
- **`trust_zone` already exists inside the PDP, and is dead.**
`ops-warden/scripts/build_flex_auth_registry.py` hardcodes
`"trust_zone": "platform"` on every ssh-cert resource; it reaches the Rego
input and **no policy rule reads it**. This repo's own warning about "zone"
being overloaded named network segmentation as the hazard; the live collision
is a dormant, plausibly-named field sitting exactly where membership would go.
The compiler must resolve it — reuse or rename, deliberately.
- **flex-auth has no reload path.** Registry and policy are loaded once at
process start from a digest-pinned image. An exception compiled as inert
registry data therefore expires only when a human redeploys — expiry by
*intention*, which is precisely what the exception lifecycle must not be. An
exception carrying `not_after`, evaluated against decision time in policy,
does expire on its own: granting costs a redeploy, lapsing is automatic.
## Deliberately absent
---
There is no:
## Relationship to what already exists
- API, daemon, database, controller, scheduler, watch loop, or reload path;
- synchronous zone lookup in an authorization or enforcement path;
- central exception store, grant workflow, clock, or expiry evaluator;
- live policy evaluation or implementation of another repository's control;
- fleet discovery, Repo Manager reference resolution, or registry publication;
- network segmentation, reef placement, tenancy, identity, or secrets service;
or
- authority to publish canon or select a consumer's stance and failure mode.
| Mechanism | Owner | Relationship |
| --- | --- | --- |
| `tenancy-posture_v0.1` | net-kingdom canon | Sibling standard and **carrier file**. Structural model: graduated levels, per-repo declaration with evidence and review dates, accuracy over altitude |
| Environment posture + workload maturity `M0``M3` | ops-warden (WP-0015) | Candidate membership inputs |
| `organization_posture: build` | ops-warden (WP-0029) | An **input** to stance selection. Explicitly not part of the declaration |
| Reefs / `bound_reefs` | repo-manager | Separate axis. Their interaction with availability is `NK-WP-0027`, not ours |
| Compiled registry snapshot | flex-auth | How membership reaches the PDP — no schema change needed, one name collision to resolve |
| Policy package | flex-auth | Where **stance** lives for controls flex-auth decides |
| `warden plan` verdicts + `reasons` | ops-warden (WP-0029) | Existing verdict machinery to extend, not parallel |
---
## Current state (2026-08-22)
`ZONE-WP-0001` is finished. T01T05 established the model: ownership is
confirmed, the estate is partitioned, stance and failure mode are modelled, the
exception lifecycle requires **no zone-engine runtime**, and the
declaration/compiler contract is drafted. The integrated owner draft is
`docs/security-zones_v0.1.md`.
Net-kingdom Decisions 5.6.1 and 5.6.2 settle the workload boundary. Operational
execution units declare authoritative workload identity directly in
`tenancy.yaml`; absence resolves to `unknown`, never inference. The standard is
published in net-kingdom canon, and T07 proves adoption in ops-warden and
flex-auth with zone-engine compiling both declarations. No API, storage, or
synchronous lookup has been shipped because the exception lifecycle showed
that none is needed.
---
Exception expiry is enforced at decision or enforcement time by each owning
control. Adding a central runtime without new evidence would cross the decided
authority boundary and introduce an unnecessary availability dependency.
## Relevant when
- A control is about to be enabled and "enforced *where*?" has no answer
- A deep refactor needs relaxed rigidity in a band of the estate, with an expiry
- A repo is filling in the `zones:` key of its `tenancy.yaml`
- Evolving the zone identities, admission rules, or exception-lifecycle
contract before offering a corresponding canon change to `net-kingdom`.
- Checking a direct `tenancy.yaml` declaration against the v0.1 reference
admission rules.
- Reproducing the adoption evidence or using the fixtures as a starting point
for an owner-side implementation.
- Auditing why the estate chose no zone-engine runtime.
## Not relevant when
- Asking whether a specific request is allowed → `flex-auth`
- Placing a workload on a substrate → `repo-manager` reefs
- Anything about network reachability
- Determining the authoritative published rule: read `net-kingdom` canon.
- Asking whether a specific request is allowed: use `flex-auth` or the owning
control.
- Resolving a managed deployable across repositories: use the Repo Manager
workload-reference contract and an owning consumer/compiler.
- Granting, applying, or expiring an exception: use the control owner's
versioned policy or PEP configuration.
- Placing a workload on a substrate: use Repo Manager reefs.
- Making a network-routing, identity, tenancy, or secrets decision.

View file

@ -0,0 +1,107 @@
# Scope assessment against `INTENT.md` — 2026-08-23
## Assessment
There is no open repository work. `ZONE-WP-0001` is the only workplan; it is
`finished`, all seven tasks are `done`, and its delivery assessment is
`DoD-Ok`. `GOAL.md` marks the project `complete`, and the checked-in work-record
index contains no ready or in-progress item.
The intended outcome was achieved, but the runtime hypothesis was falsified in
the useful direction anticipated by `INTENT.md` §7. The repository proved that
reviewed declarations plus enforcement-time expiry at the owning control are
sufficient. The thing delivered here is therefore a standard source, a partial
reference resolver, tests, and evidence—not a running zone engine.
## Intent-to-outcome map
| Intent claim or test | Assessment | Evidence / boundary |
| --- | --- | --- |
| A control can vary by workload zone rather than one repo-wide switch (§§12) | Met | The five-zone model and total owner-qualified profiles were adopted; ops-warden retired `policy.enabled` and global `policy.fail_closed`. |
| The workload is the policy subject and qualifies against a floor (§3) | Met | Direct `workload_identity` plus `zones:` declarations are validated; missing facts resolve `unknown` without inference. |
| Identity, admission, stance, failure mode, and expiring exceptions all have owners (§4) | Met by a distributed contract | zone-engine owns the identity/membership model; control owners own stance; PEP owners own failure behavior; exception expiry runs where the effect occurs. No central runtime is required. |
| flex-auth remains the only PDP for its decisions (§5) | Met | zone-engine performs no live lookup or authorization decision. flex-auth owns its versioned policy package. |
| Consumers can understand posture without reading this repo (§6) | Met for the adopted path | The standard is in net-kingdom canon, declarations are in owning repos, and decision/verdict evidence belongs to control owners. |
| Exception lifecycle needs no runtime (§7 falsifier) | Falsifier triggered | `docs/exception-lifecycle-2026-08-22.md` records decision-time expiry and explicitly rejects a central service. Under the Intent, this makes the repo an archive candidate. |
| Zones partition the real estate (§7 falsifier) | Met at model level | The estate study classifies applicable workloads and explicitly represents `unknown` and `not-applicable`; it does not manufacture zones for unresolved inventory. |
| Two owners declare and a third reads (§7 falsifier) | Met | ops-warden and flex-auth declare; zone-engine's reference resolver reads both. |
| No second decision point appears (§7 falsifier) | Met, with a reference-tool caveat | The local resolver projects an accepted profile for evidence, but cannot render an authorization effect and is not authoritative policy. |
| Canon-first direction and conditional runtime (§9) | Met | Canon was published and adoption proven; T04 selected the cheaper no-runtime result. |
## Gaps and residual boundaries
These are gaps between the broad language of `INTENT.md`, the full canonical
contract, and what this repository itself can execute. They are not open tasks
in the completed workplan.
### 1. Repository name and lifecycle no longer match the delivered shape
The name `zone-engine` suggests a running service. No engine was needed or
shipped. `INTENT.md` §7 says this exact outcome should lead to archival rather
than preserving a repository for its own sake. The remaining governance choice
is to archive it or deliberately retain it as a clearly named reference and
evidence repository. That choice belongs outside the completed implementation
workplan.
### 2. `INTENT.md` is now historical argument, not present-state description
Phrases such as “NetKingdom cannot say that today,” “the gate ... was
deliberately not switched on,” and “a relaxation with an expiry is state”
describe the initiating problem and hypothesis. Adoption has since made the
sentence sayable, retired the global switch, and shown that state can live in
versioned owner policy with expiry evaluated at the enforcement point.
`SCOPE.md`, not those present-tense passages, must be used for current
capability.
### 3. The checked-in resolver implements only part of the resolved-view contract
The reference resolver validates direct declaration files and emits an
admission result. It does not:
- resolve Repo Manager's managed-workload tuple or emit applicability and
`workload_ref` results;
- discover declarations or join a fleet catalog;
- include source revision in `membership_revision` (the digest covers the
workload identity and `zones:` content);
- report membership changes against a preceding snapshot;
- emit the full authority/provenance fields illustrated by the standard, such
as identity binding, policy owner, PEP owner, and policy reference; or
- represent active exception ids and expiry in its output.
Consequently it is sufficient for the recorded direct-declaration adoption
proof, but must not be presented as the complete compiler described by the
canonical standard.
### 4. The local standard is a source snapshot, not canon
`docs/security-zones_v0.1.md` remains marked `status: draft` even though the
standard has been published and subsequently updated in `net-kingdom`. The
published copy is authoritative. Maintaining two independently editable copies
creates drift risk; an archived repository avoids that risk, while a retained
reference repository needs an explicit canon-sync policy.
### 5. The reference control profile could be mistaken for local stance authority
`tools/resolve_zones.py` embeds the initial flex-auth and ops-warden control
rows and emits them without policy-package provenance. This was adequate to
prove the v0.1 adoption profile, but the owning policy packages and PEP
configuration remain authoritative. Any future profile change must happen at
those owners and in canon; changing this table alone must never change a live
effect.
### 6. Estate-wide completeness remains consumer migration work
The model can represent resolved workloads, `unknown`, and `not-applicable`,
but this repository does not make every catalog entry resolvable. Pre-rapp
deployables and missing owner references remain migration debt in the owning
catalogs and workloads. That does not require a zone-engine runtime and is not
unclosed work in this repository.
## Recommendation
Treat `zone-engine` as complete and make no new runtime workplan. Prefer
archival once its history/evidence value is accepted elsewhere. If it is kept,
retain it explicitly as a reference-conformance repository, make net-kingdom
canon the only consumer-facing authority, and open future work only for a
concrete canon revision or a demonstrated adopting-control need that cannot be
met at its existing enforcement point.