Apply GH-DEC-2026-017: INTENT.md governs, the sidecar is derived, no version
Verified against gate-house's own committed files before editing, not the inbox message: GH-DEC-2026-017 in decisions/decisions.md at gate-house@def0af2, amendments A9-A13 in docs/amendments/v0.8-section-11-declaration-amendments.md, and sections 3, 4 and 11 of net-kingdom's security-layer-model_v0.8.md. The ruling and docs/layer-declaration-precedence.md's secondary account agreed. INTENT.md's frontmatter is the declaration; layer.yaml is a derived artifact, now marked derived: true / derived_from: INTENT.md, and it does not govern. standard_version is removed from BOTH forms. The ruling's general form is that a layer declaration must not carry a standard version, and INTENT.md is the declaration, so removing it from the sidecar alone would have left the field in the only file that actually declares. INTENT.md's version-pinned `standard:` path is de-versioned for the same reason: a pinned path reads as a validity condition. The version ops-warden assented at stays with the assent, ADR-0010. NO LAYER VALUE IS CHANGED. INTENT.md still says Staff and layer.yaml still says staff. Section 3's vocabulary is closed, four tokens, and case-insensitive: the two forms were never in disagreement about a layer, and the ruling asked nobody to re-spell anything. The comment marking the divergence is rewritten from "unruled, do not touch" to "ruled, folding case is the checker's job". check_layer_conformance.py would have rejected the conforming declaration this ruling produces -- it listed standard_version as a required key. It now reads INTENT.md as the governing form, ASCII-folds before comparing, validates both values against the closed four-token vocabulary (Taxonomy included; omitting it is the defect A9 records against the estate's other validator), requires the derived marking, rejects a returning standard_version in either file, and reports a post-fold disagreement between the forms as a finding rather than resolving it away by precedence. The test asserts the fold, not equality. An equality assertion here would be this repository quietly performing the re-spelling the ruling declined to order; the fold still fails on a real layer divergence. pep-stance.yaml is untouched. A stance map is not a layer declaration, and the sidecar schema beyond the derived marking and the version is explicitly not ruled. layer.yaml is the form seven repositories copied, so the adopter change set is written out in wiki/playbooks/netkingdom-layer-declaration.md -- including the trap that an adopter which also copied the checker turns a conforming declaration into MALFORMED exit 2 by removing the field alone. No other repository is edited here. Still open: where the removed version lives. A12 says the derived conformance record "already MUST" carry it; ops-warden has a re-runnable checker that emits nothing durable. Asked of gate-house in message 4220413a, unanswered, and left open rather than answered by choosing. Nothing above depends on it. Carries WARDEN-WP-0034-T06 to done. 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
This commit is contained in:
parent
04b3a28aaa
commit
a70f559d40
8 changed files with 376 additions and 73 deletions
15
INTENT.md
15
INTENT.md
|
|
@ -1,11 +1,20 @@
|
||||||
---
|
---
|
||||||
|
# THE layer declaration (§11, GH-DEC-2026-017 §1). `layer.yaml` is derived from
|
||||||
|
# this frontmatter and must agree with it; it does not govern. Comparison of the
|
||||||
|
# §3 vocabulary is ASCII case-insensitive, so `Staff` here and `staff` there are
|
||||||
|
# the same value and neither is re-spelled (GH-DEC-2026-017 §2).
|
||||||
layer: Staff
|
layer: Staff
|
||||||
role: null # Engines only: PDP | PIP | Evidence | Lifecycle
|
role: null # Engines only: PDP | PIP | Evidence | Lifecycle
|
||||||
pep_shaped: true # §6.4 — issuing a certificate is a protected side effect
|
pep_shaped: true # §6.4 — issuing a certificate is a protected side effect
|
||||||
standard: net-kingdom/canon/standards/security-layer-model_v0.7.md
|
# No `standard_version` here or in the sidecar: GH-DEC-2026-017 §5 / A12 —
|
||||||
standard_version: "0.7"
|
# the declared layer is a standing property that does not change when the
|
||||||
|
# standard is revised, so a version in the declaration reads as a validity
|
||||||
|
# condition it is not. Version-scoped state belongs in the derived conformance
|
||||||
|
# record. The version ops-warden assented at is recorded with the assent
|
||||||
|
# (ADR-0010), which is where a version-at-a-boundary belongs.
|
||||||
|
standard: net-kingdom/canon/standards/security-layer-model
|
||||||
companion: net-kingdom/SECURITY-COMPANION.md
|
companion: net-kingdom/SECURITY-COMPANION.md
|
||||||
declaration: layer.yaml
|
declaration: layer.yaml # derived form; this frontmatter governs
|
||||||
pep_stance: pep-stance.yaml
|
pep_stance: pep-stance.yaml
|
||||||
assent: docs/adr/ADR-0010
|
assent: docs/adr/ADR-0010
|
||||||
---
|
---
|
||||||
|
|
|
||||||
4
SCOPE.md
4
SCOPE.md
|
|
@ -93,7 +93,7 @@ cited in the standard as the estate's reference forms:
|
||||||
|
|
||||||
| Artifact | Declares | Status |
|
| Artifact | Declares | Status |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `layer.yaml` | 5 Tooling contacts mapped to §5.1/§5.2/§5.3 shapes + non-Tooling clients so the check is total | shipped; named reference form (§11) |
|
| `layer.yaml` | 5 Tooling contacts mapped to §5.1/§5.2/§5.3 shapes + non-Tooling clients so the check is total; **derived** from `INTENT.md`, which governs (`GH-DEC-2026-017`) | shipped; named reference form (§11) |
|
||||||
| `pep-stance.yaml` | unreachable-engine stance map, total per zone | shipped; registered in statute §13.1 (§6.4 obl. 3) |
|
| `pep-stance.yaml` | unreachable-engine stance map, total per zone | shipped; registered in statute §13.1 (§6.4 obl. 3) |
|
||||||
| `scripts/check_layer_conformance.py` | every direct Tooling client maps to a declared shape | shipped; CI-enforced |
|
| `scripts/check_layer_conformance.py` | every direct Tooling client maps to a declared shape | shipped; CI-enforced |
|
||||||
| `tests/test_layer_conformance.py` | the §5.2 no-authority property, and published stance map **equals** shipped default | shipped, 11 tests |
|
| `tests/test_layer_conformance.py` | the §5.2 no-authority property, and published stance map **equals** shipped default | shipped, 11 tests |
|
||||||
|
|
@ -511,7 +511,7 @@ keywords: [access, credential, secret, npm, token, api-key, openbao, key-cape, l
|
||||||
| `wiki/WorkloadSecurityPosture.md` | Secret-store posture, workload maturity, and blocker triage |
|
| `wiki/WorkloadSecurityPosture.md` | Secret-store posture, workload maturity, and blocker triage |
|
||||||
| `registry/routing/catalog.yaml` | Machine-readable routing pointer catalog |
|
| `registry/routing/catalog.yaml` | Machine-readable routing pointer catalog |
|
||||||
| `net-kingdom/SECURITY-COMPANION.md` | **The estate's operative security rules — start here** |
|
| `net-kingdom/SECURITY-COMPANION.md` | **The estate's operative security rules — start here** |
|
||||||
| `layer.yaml` | Layer declaration: every Tooling contact and its §5 shape |
|
| `layer.yaml` | Derived layer declaration: every Tooling contact and its §5 shape (`INTENT.md` frontmatter governs) |
|
||||||
| `pep-stance.yaml` | Unreachable-engine stance map (§6.4); equals shipped behaviour by test |
|
| `pep-stance.yaml` | Unreachable-engine stance map (§6.4); equals shipped behaviour by test |
|
||||||
| `tenancy.yaml` | Declared tenancy posture (`I1 A1 E0 P n/a R n/a V0`) and why each axis sits where it does |
|
| `tenancy.yaml` | Declared tenancy posture (`I1 A1 E0 P n/a R n/a V0`) and why each axis sits where it does |
|
||||||
| `wiki/NetKingdomSecurityMap.md` | Platform security component map |
|
| `wiki/NetKingdomSecurityMap.md` | Platform security component map |
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,12 @@
|
||||||
# Which of ops-warden's two layer declarations governs — unruled, and not ours to rule
|
# Which of ops-warden's two layer declarations governs — ruled, and applied
|
||||||
|
|
||||||
**Status: open, waiting on gate-house. ops-warden will not change either file
|
**Status: RULED and APPLIED, 2026-09-21.** `GH-DEC-2026-017` (`gate-house@def0af2`)
|
||||||
until the ruling lands.** Route: `WARDEN-WP-0034-T06`.
|
settles it: `INTENT.md` governs, the sidecar is derived, and the §3 vocabulary is
|
||||||
|
case-insensitive — so the two values were never in disagreement about a layer.
|
||||||
|
Route: `WARDEN-WP-0034-T06`, done. **Sections 1–3 below are the position as it
|
||||||
|
stood while the question was open, kept because the ruling is only legible
|
||||||
|
against the question it answers.** What changed, and what is still open, is
|
||||||
|
[further down](#the-ruling-landed--2026-09-21--and-it-is-applied).
|
||||||
|
|
||||||
## The fact
|
## The fact
|
||||||
|
|
||||||
|
|
@ -63,10 +68,10 @@ settled either.
|
||||||
other file to match in one commit, together with a regression test asserting
|
other file to match in one commit, together with a regression test asserting
|
||||||
the two agree — so the next divergence is caught rather than surveyed.
|
the two agree — so the next divergence is caught rather than surveyed.
|
||||||
|
|
||||||
## The ruling landed — 2026-09-21, and it is NOT YET APPLIED
|
## The ruling landed — 2026-09-21 — and it is APPLIED
|
||||||
|
|
||||||
`GH-DEC-2026-017` (gate-house `def0af2`, message `3715e247`, amendments A9–A13)
|
`GH-DEC-2026-017` (gate-house `def0af2`, message `3715e247`, amendments A9–A13)
|
||||||
arrived hours after this page was written. It answers both questions and asks
|
arrived hours after this page was written. It answers both questions and asked
|
||||||
ops-warden for two changes, because `layer.yaml` is the estate's reference form
|
ops-warden for two changes, because `layer.yaml` is the estate's reference form
|
||||||
and seven repositories copied it.
|
and seven repositories copied it.
|
||||||
|
|
||||||
|
|
@ -74,42 +79,80 @@ and seven repositories copied it.
|
||||||
`layer:` key is the declaration and the file is a **derived** artifact —
|
`layer:` key is the declaration and the file is a **derived** artifact —
|
||||||
marked derived, naming `INTENT.md` as its source, required to agree with it.
|
marked derived, naming `INTENT.md` as its source, required to agree with it.
|
||||||
- **Casing: ruled away, not ruled on.** §3's vocabulary is case-insensitive for
|
- **Casing: ruled away, not ruled on.** §3's vocabulary is case-insensitive for
|
||||||
comparison; a conformance run **must fold case**, and **nobody re-spells
|
comparison, a conformance run **must fold case**, and **nobody re-spells
|
||||||
anything**. `Staff` and `staff` agree. The plan in point 4 above — align the
|
anything**. `Staff` and `staff` agree. The plan in point 4 above — align the
|
||||||
files in one commit — is therefore moot rather than completed.
|
files in one commit — is therefore **moot rather than completed**, and that
|
||||||
|
distinction is the point: the divergence was never a disagreement about a
|
||||||
|
layer, so there was never anything to align.
|
||||||
- **A disagreement between the two forms is still a finding** and must be
|
- **A disagreement between the two forms is still a finding** and must be
|
||||||
reported rather than resolved away, or precedence makes eight of the nine
|
reported rather than resolved away, or precedence makes eight of the nine
|
||||||
invisible instead of settling them.
|
invisible instead of settling them.
|
||||||
- **Ask 1:** remove `standard_version: "0.7"` from `layer.yaml`. A layer is a
|
|
||||||
standing property; a version here makes every revision of the standard read as
|
|
||||||
though it invalidated every declaration. Version-scoped state belongs in the
|
|
||||||
derived conformance record.
|
|
||||||
- **Ask 2:** mark the sidecar derived and name `INTENT.md` as its source.
|
|
||||||
`INTENT.md` already carries `layer: Staff`, so nothing needs adding there.
|
|
||||||
|
|
||||||
**Neither ask has been applied, and that is deliberate.** Both would edit this
|
### What was applied, 2026-09-21
|
||||||
repository's security-layer declaration on the strength of an instruction that
|
|
||||||
arrived in an inbox message, and both propagate: this file is the form seven
|
|
||||||
repositories copied, so removing a field here is a change to the estate's
|
|
||||||
reference shape rather than to one repository's metadata. A session that applies
|
|
||||||
it should be mandated to, should verify `GH-DEC-2026-017` at
|
|
||||||
`gate-house@def0af2` and the A9–A13 amendments in the repository rather than
|
|
||||||
from the message text, and should land it as one commit carrying:
|
|
||||||
|
|
||||||
1. `standard_version` removed from `layer.yaml` (and from
|
Verified first against gate-house's own committed files — `GH-DEC-2026-017` in
|
||||||
`scripts/check_layer_conformance.py`'s required-key list and report line).
|
`decisions/decisions.md` at `gate-house@def0af2`, amendments A9–A13 in
|
||||||
2. `derived: true` and `derived_from: INTENT.md` added.
|
`docs/amendments/v0.8-section-11-declaration-amendments.md`, and §3/§4/§11 of
|
||||||
3. A regression test asserting the sidecar's `layer` equals `INTENT.md`'s
|
`net-kingdom/canon/standards/security-layer-model_v0.8.md` — not from the inbox
|
||||||
frontmatter `layer` **case-folded**, and that `standard_version` has not
|
message and not from this page, which is a secondary record. The decision and
|
||||||
returned.
|
this page's account of it agreed.
|
||||||
4. `pep-stance.yaml` left alone. Its `standard_version: "0.7"` with
|
|
||||||
|
1. `standard_version` removed from **both** forms. The ruling's general form is
|
||||||
|
*a layer declaration MUST NOT carry a standard version*, and the governing
|
||||||
|
declaration is `INTENT.md`, so removing it from the sidecar alone would have
|
||||||
|
left the field in the one file that actually declares. `INTENT.md`'s
|
||||||
|
`standard:` pointer is de-versioned with it, for the same reason the field
|
||||||
|
goes: a version-pinned path reads as a validity condition. The version
|
||||||
|
ops-warden assented at stays with the assent (`ADR-0010`), which is where a
|
||||||
|
version-at-a-boundary belongs.
|
||||||
|
2. `derived: true` and `derived_from: INTENT.md` added to `layer.yaml`, and the
|
||||||
|
file's header now says plainly that it does not govern.
|
||||||
|
3. **No layer value changed.** `INTENT.md` still says `Staff`, `layer.yaml`
|
||||||
|
still says `staff`, and the comment marking the divergence is rewritten from
|
||||||
|
*unruled, do not touch* to *ruled, folding case is the checker's job*.
|
||||||
|
4. `scripts/check_layer_conformance.py` now reads `INTENT.md` as the governing
|
||||||
|
form, ASCII-folds before comparing, validates both values against §3's closed
|
||||||
|
four-token vocabulary (`Taxonomy` included — omitting it is the defect A9
|
||||||
|
records), requires the derived marking, and **rejects a returning
|
||||||
|
`standard_version` in either file**. It previously listed `standard_version`
|
||||||
|
as a required key, so it would have rejected the conforming declaration this
|
||||||
|
ruling produces.
|
||||||
|
5. `tests/test_layer_conformance.py` asserts the fold rather than equality. An
|
||||||
|
equality assertion would have been this repository performing the re-spelling
|
||||||
|
the ruling explicitly declined to order; the fold still fails on a real layer
|
||||||
|
divergence, which is what point 4 of this page originally wanted.
|
||||||
|
6. `pep-stance.yaml` left alone. Its `standard_version: "0.7"` with
|
||||||
`standard_version_reviewed: "0.8"` is a stance map, not a layer declaration,
|
`standard_version_reviewed: "0.8"` is a stance map, not a layer declaration,
|
||||||
and gate-house has said separately it would rather other consumers copied
|
and gate-house has said separately it would rather other consumers copied
|
||||||
that shape than that ops-warden changed it.
|
that shape than that ops-warden changed it. `GH-DEC-2026-017` also states it
|
||||||
|
does not rule the sidecar's schema beyond the derived marking and the version.
|
||||||
|
|
||||||
Until then this page and `layer.yaml`'s comment stand: do not "fix" the
|
### What the seven adopters must copy
|
||||||
divergence ad hoc. Under the ruling there is nothing to fix — the two forms
|
|
||||||
already agree once case is folded.
|
The change set is written for them in
|
||||||
|
`wiki/playbooks/netkingdom-layer-declaration.md`. ops-warden does not edit their
|
||||||
|
files. The trap worth repeating: any adopter that also copied the checker has a
|
||||||
|
required-key list containing `standard_version`, so removing the field alone
|
||||||
|
turns a conforming declaration into a `MALFORMED` exit 2.
|
||||||
|
|
||||||
|
### Still open — where the removed version goes
|
||||||
|
|
||||||
|
`GH-DEC-2026-017` §5 and A12 both say version-scoped state *"belongs in the
|
||||||
|
derived conformance record, which under this section's derived-artifact rule
|
||||||
|
already MUST name what it derives from and carry the version or commit it was
|
||||||
|
derived at."* Both sentences say **already**, and ops-warden does not have one:
|
||||||
|
what it has is `scripts/check_layer_conformance.py`, a re-runnable check that
|
||||||
|
emits nothing durable. So it is unresolved whether §11 expects an **emitted
|
||||||
|
record** — a committed artifact carrying the version it was derived at — or
|
||||||
|
whether a re-runnable checker discharges the obligation, with the version
|
||||||
|
supplied by whoever runs it.
|
||||||
|
|
||||||
|
Asked of gate-house in message `4220413a` (2026-09-21). **No answer had arrived
|
||||||
|
when this change was applied, and the question is deliberately left open rather
|
||||||
|
than answered by choosing.** Nothing in the applied change depends on it: the
|
||||||
|
version is gone from the declaration either way, and the only thing the answer
|
||||||
|
decides is whether ops-warden must additionally emit a record to have somewhere
|
||||||
|
to put it.
|
||||||
|
|
||||||
## Why this page exists rather than an inbox thread
|
## Why this page exists rather than an inbox thread
|
||||||
|
|
||||||
|
|
|
||||||
42
layer.yaml
42
layer.yaml
|
|
@ -1,6 +1,12 @@
|
||||||
# ops-warden — NetKingdom security layer declaration
|
# ops-warden — DERIVED form of the NetKingdom security layer declaration
|
||||||
#
|
#
|
||||||
# Framework: net-kingdom/canon/standards/security-layer-model_v0.7.md
|
# THIS FILE DOES NOT GOVERN. The declaration is the `layer:` key in INTENT.md's
|
||||||
|
# frontmatter; this file is a derived artifact under §11's derived-artifact rule
|
||||||
|
# and must agree with it (GH-DEC-2026-017 §1, amendment A11). A disagreement
|
||||||
|
# between the two forms is a finding in its own right and is reported, never
|
||||||
|
# resolved away by precedence.
|
||||||
|
#
|
||||||
|
# Framework: net-kingdom/canon/standards/security-layer-model
|
||||||
# Assent: docs/adr/ADR-0010 (ops-warden's own voice, per §11 "who must declare")
|
# Assent: docs/adr/ADR-0010 (ops-warden's own voice, per §11 "who must declare")
|
||||||
# Validate: python3 scripts/check_layer_conformance.py
|
# Validate: python3 scripts/check_layer_conformance.py
|
||||||
#
|
#
|
||||||
|
|
@ -12,16 +18,32 @@
|
||||||
# Conformance rule inherited from tenancy.yaml: accuracy, not altitude. A
|
# Conformance rule inherited from tenancy.yaml: accuracy, not altitude. A
|
||||||
# declared gap is TRACKED NON-CONFORMANCE (§11), never a claim of conformance.
|
# declared gap is TRACKED NON-CONFORMANCE (§11), never a claim of conformance.
|
||||||
|
|
||||||
schema_version: "0.1"
|
schema_version: "0.2"
|
||||||
framework: netkingdom-security-layer-model
|
framework: netkingdom-security-layer-model
|
||||||
standard_version: "0.7"
|
|
||||||
|
# §11 derived-artifact marking (GH-DEC-2026-017 §1 / A11).
|
||||||
|
derived: true
|
||||||
|
derived_from: INTENT.md
|
||||||
|
|
||||||
|
# NO `standard_version` KEY, AND DO NOT ADD ONE BACK.
|
||||||
|
# GH-DEC-2026-017 §5 / amendment A12: a layer declaration MUST NOT carry a
|
||||||
|
# standard version. The declared layer is a standing property of the repository
|
||||||
|
# and does not change when the standard is revised; a version here makes every
|
||||||
|
# revision read as though it invalidated every declaration. Version-scoped state
|
||||||
|
# belongs in the derived conformance record, which already must carry the
|
||||||
|
# version or commit it was derived at. Keeping the field "for information" was
|
||||||
|
# declined explicitly: a field that is present will be branched on. Absence is
|
||||||
|
# enforced by tests/test_layer_conformance.py.
|
||||||
|
|
||||||
repository: ops-warden
|
repository: ops-warden
|
||||||
# UNRULED, 2026-09-21: INTENT.md frontmatter declares `Staff` and this file
|
|
||||||
# declares `staff`. §11 permits both forms and does not say which governs when
|
# RULED, 2026-09-21 (GH-DEC-2026-017 §2): INTENT.md declares `Staff` and this
|
||||||
# both exist and disagree; gate-house holds that ruling and the case-sensitivity
|
# file declares `staff`, and THAT IS NOT A DISAGREEMENT. §3's vocabulary is
|
||||||
# one. NEITHER VALUE IS BEING CHANGED until it rules — see
|
# closed — {Taxonomy, Tooling, Engine, Staff} — and comparison is ASCII
|
||||||
# docs/layer-declaration-precedence.md and WARDEN-WP-0034-T06. Do not "fix" this
|
# case-insensitive: a conformance run MUST fold case before comparing, and a
|
||||||
# line to match INTENT.md, or the reverse: the divergence is the evidence.
|
# lowercase declaration is conforming, not tolerated. No repository was asked to
|
||||||
|
# re-spell anything. Do not "fix" this line to match INTENT.md, or the reverse;
|
||||||
|
# folding case is the checker's job, and it does it.
|
||||||
layer: staff
|
layer: staff
|
||||||
declared_by: docs/adr/ADR-0010
|
declared_by: docs/adr/ADR-0010
|
||||||
declared_at: "2026-08-29"
|
declared_at: "2026-08-29"
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,22 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""Check ops-warden against the NetKingdom security layer model (§5, §11).
|
"""Check ops-warden against the NetKingdom security layer model (§5, §11).
|
||||||
|
|
||||||
Read-only. Makes §11's second mechanical check real:
|
Read-only. Two declaration forms are read, and the precedence between them is
|
||||||
|
`GH-DEC-2026-017` §1 (amendment A11): **INTENT.md's frontmatter governs** and
|
||||||
|
`layer.yaml` is a derived artifact that must be marked derived, must name
|
||||||
|
INTENT.md as its source, and must agree with it. The sidecar is read anyway,
|
||||||
|
because a disagreement between the two is itself a finding and is reported
|
||||||
|
rather than resolved away by precedence.
|
||||||
|
|
||||||
|
Comparison against §3's closed four-token vocabulary ASCII-folds case before
|
||||||
|
comparing (`GH-DEC-2026-017` §2, amendment A9): two spellings of a token do not
|
||||||
|
describe two boundaries, and a check that reports findings about capital letters
|
||||||
|
buries the one real disagreement it exists to find.
|
||||||
|
|
||||||
|
Neither form carries a `standard_version`, and their absence is enforced here
|
||||||
|
and by tests (`GH-DEC-2026-017` §5, amendment A12).
|
||||||
|
|
||||||
|
Makes §11's second mechanical check real:
|
||||||
|
|
||||||
every direct Tooling client in a Staff repository maps to a declared
|
every direct Tooling client in a Staff repository maps to a declared
|
||||||
§5.1, §5.2, or §5.3 entry
|
§5.1, §5.2, or §5.3 entry
|
||||||
|
|
@ -27,10 +42,59 @@ import yaml
|
||||||
|
|
||||||
ROOT = Path(__file__).resolve().parents[1]
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
SRC = ROOT / "src" / "warden"
|
SRC = ROOT / "src" / "warden"
|
||||||
|
INTENT = ROOT / "INTENT.md"
|
||||||
DECL = ROOT / "layer.yaml"
|
DECL = ROOT / "layer.yaml"
|
||||||
|
|
||||||
VALID_SHAPES = {"5.1", "5.2", "5.3"}
|
VALID_SHAPES = {"5.1", "5.2", "5.3"}
|
||||||
|
|
||||||
|
# §3's vocabulary, closed, four tokens (GH-DEC-2026-017 §3, amendment A9). The
|
||||||
|
# canonical spellings are §4's catalog-column forms; comparison is ASCII
|
||||||
|
# case-insensitive, so the fold is what is stored and `Taxonomy` is in the set —
|
||||||
|
# omitting it is the defect A9 records against the estate's other validator.
|
||||||
|
LAYER_VOCABULARY = {"taxonomy", "tooling", "engine", "staff"}
|
||||||
|
|
||||||
|
|
||||||
|
def _fold(value: str) -> str:
|
||||||
|
"""ASCII case-fold, per §3 as amended: two spellings of a token are one token."""
|
||||||
|
return str(value).strip().encode("ascii", "ignore").decode().lower()
|
||||||
|
|
||||||
|
|
||||||
|
def load_governing_layer() -> str:
|
||||||
|
"""The declaration is INTENT.md's frontmatter `layer:` key (§11, GH-DEC-2026-017 §1).
|
||||||
|
|
||||||
|
layer.yaml is derived and does not govern. Read without a YAML frontmatter
|
||||||
|
dependency: the file is read by humans first and a parser second.
|
||||||
|
"""
|
||||||
|
if not INTENT.exists():
|
||||||
|
print(f"MISSING: {INTENT} — §11's governing declaration form")
|
||||||
|
raise SystemExit(2)
|
||||||
|
lines = INTENT.read_text().splitlines()
|
||||||
|
if not lines or lines[0].strip() != "---":
|
||||||
|
print("MALFORMED: INTENT.md has no frontmatter to carry the declaration (§11)")
|
||||||
|
raise SystemExit(2)
|
||||||
|
end = next((i for i, ln in enumerate(lines[1:], 1) if ln.strip() == "---"), None)
|
||||||
|
if end is None:
|
||||||
|
print("MALFORMED: INTENT.md frontmatter is not terminated")
|
||||||
|
raise SystemExit(2)
|
||||||
|
front = yaml.safe_load("\n".join(lines[1:end])) or {}
|
||||||
|
if "layer" not in front:
|
||||||
|
print("MALFORMED: INTENT.md frontmatter has no 'layer' key — §11's declaration")
|
||||||
|
raise SystemExit(2)
|
||||||
|
if "standard_version" in front:
|
||||||
|
print(
|
||||||
|
"MALFORMED: INTENT.md frontmatter carries 'standard_version' — a layer "
|
||||||
|
"declaration MUST NOT carry a standard version (§11 as amended by A12)"
|
||||||
|
)
|
||||||
|
raise SystemExit(2)
|
||||||
|
layer = front["layer"]
|
||||||
|
if _fold(layer) not in LAYER_VOCABULARY:
|
||||||
|
print(
|
||||||
|
f"MALFORMED: INTENT.md declares layer {layer!r}, outside §3's closed "
|
||||||
|
f"vocabulary {sorted(LAYER_VOCABULARY)} (case-insensitive)"
|
||||||
|
)
|
||||||
|
raise SystemExit(2)
|
||||||
|
return layer
|
||||||
|
|
||||||
# A direct Tooling contact is an *invocation*, not a mention. Matching the word
|
# A direct Tooling contact is an *invocation*, not a mention. Matching the word
|
||||||
# "bao" caught help text, a docstring, and the dev-tier doubles library that
|
# "bao" caught help text, a docstring, and the dev-tier doubles library that
|
||||||
# simulates bao rather than calling it — three false positives on first run.
|
# simulates bao rather than calling it — three false positives on first run.
|
||||||
|
|
@ -60,10 +124,33 @@ def load_declaration() -> dict:
|
||||||
print(f"MISSING: {DECL} — ops-warden must declare in its own voice (§11)")
|
print(f"MISSING: {DECL} — ops-warden must declare in its own voice (§11)")
|
||||||
raise SystemExit(2)
|
raise SystemExit(2)
|
||||||
decl = yaml.safe_load(DECL.read_text())
|
decl = yaml.safe_load(DECL.read_text())
|
||||||
for key in ("layer", "repository", "standard_version", "tooling_contacts"):
|
for key in ("layer", "repository", "derived", "derived_from", "tooling_contacts"):
|
||||||
if key not in decl:
|
if key not in decl:
|
||||||
print(f"MALFORMED: layer.yaml has no {key!r}")
|
print(f"MALFORMED: layer.yaml has no {key!r}")
|
||||||
raise SystemExit(2)
|
raise SystemExit(2)
|
||||||
|
# §11's derived-artifact rule: marked as derived, naming what it derives from.
|
||||||
|
if decl["derived"] is not True:
|
||||||
|
print("MALFORMED: layer.yaml must be marked 'derived: true' (§11, GH-DEC-2026-017 §1)")
|
||||||
|
raise SystemExit(2)
|
||||||
|
if decl["derived_from"] != "INTENT.md":
|
||||||
|
print(
|
||||||
|
f"MALFORMED: layer.yaml derives from {decl['derived_from']!r}; §11 names "
|
||||||
|
"INTENT.md as the governing declaration"
|
||||||
|
)
|
||||||
|
raise SystemExit(2)
|
||||||
|
# A12: the version has no home in a declaration, governing or derived.
|
||||||
|
if "standard_version" in decl:
|
||||||
|
print(
|
||||||
|
"MALFORMED: layer.yaml carries 'standard_version' — a layer declaration "
|
||||||
|
"MUST NOT carry a standard version (§11 as amended by A12)"
|
||||||
|
)
|
||||||
|
raise SystemExit(2)
|
||||||
|
if _fold(decl["layer"]) not in LAYER_VOCABULARY:
|
||||||
|
print(
|
||||||
|
f"MALFORMED: layer.yaml declares layer {decl['layer']!r}, outside §3's "
|
||||||
|
f"closed vocabulary {sorted(LAYER_VOCABULARY)} (case-insensitive)"
|
||||||
|
)
|
||||||
|
raise SystemExit(2)
|
||||||
for c in decl["tooling_contacts"]:
|
for c in decl["tooling_contacts"]:
|
||||||
if c.get("shape") not in VALID_SHAPES:
|
if c.get("shape") not in VALID_SHAPES:
|
||||||
print(f"MALFORMED: {c.get('id')} has shape {c.get('shape')!r}, not one of {sorted(VALID_SHAPES)}")
|
print(f"MALFORMED: {c.get('id')} has shape {c.get('shape')!r}, not one of {sorted(VALID_SHAPES)}")
|
||||||
|
|
@ -110,6 +197,7 @@ def main() -> int:
|
||||||
ap.add_argument("--report", action="store_true", help="also print the declaration and gap review dates")
|
ap.add_argument("--report", action="store_true", help="also print the declaration and gap review dates")
|
||||||
args = ap.parse_args()
|
args = ap.parse_args()
|
||||||
|
|
||||||
|
governing = load_governing_layer()
|
||||||
decl = load_declaration()
|
decl = load_declaration()
|
||||||
declared = {c["module"].split("/")[-1] for c in decl["tooling_contacts"]}
|
declared = {c["module"].split("/")[-1] for c in decl["tooling_contacts"]}
|
||||||
excluded = _excluded(decl)
|
excluded = _excluded(decl)
|
||||||
|
|
@ -127,7 +215,8 @@ def main() -> int:
|
||||||
stale_decls = declared - set(found) - voluntary
|
stale_decls = declared - set(found) - voluntary
|
||||||
|
|
||||||
if args.report:
|
if args.report:
|
||||||
print(f"{decl['repository']} — layer: {decl['layer']} (model v{decl['standard_version']})")
|
print(f"{decl['repository']} — layer: {governing} (declared in INTENT.md; §11 governing form)")
|
||||||
|
print(f" layer.yaml: derived from {decl['derived_from']}, layer: {decl['layer']}")
|
||||||
print(f"declared by {decl['declared_by']}\n")
|
print(f"declared by {decl['declared_by']}\n")
|
||||||
for c in decl["tooling_contacts"]:
|
for c in decl["tooling_contacts"]:
|
||||||
line = f" §{c['shape']} {c['id']:<28} {c['module']}"
|
line = f" §{c['shape']} {c['id']:<28} {c['module']}"
|
||||||
|
|
@ -141,6 +230,21 @@ def main() -> int:
|
||||||
print(f"\n{len(gaps)} declared gap(s) — tracked non-conformance, not conformance (§11).")
|
print(f"\n{len(gaps)} declared gap(s) — tracked non-conformance, not conformance (§11).")
|
||||||
|
|
||||||
ok = True
|
ok = True
|
||||||
|
|
||||||
|
# §11 as amended (A11): the derived form MUST agree with the governing one,
|
||||||
|
# and a disagreement is a finding in its own right — reported, not resolved
|
||||||
|
# away by precedence. Comparison folds case (A9): `Staff` and `staff` agree.
|
||||||
|
if _fold(decl["layer"]) != _fold(governing):
|
||||||
|
ok = False
|
||||||
|
print(
|
||||||
|
"\nDECLARATION DISAGREEMENT — a finding under §11, not a precedence question:\n"
|
||||||
|
f" INTENT.md (governs): layer: {governing}\n"
|
||||||
|
f" layer.yaml (derived): layer: {decl['layer']}\n"
|
||||||
|
"Precedence says which value is ops-warden's answer. It does not say the\n"
|
||||||
|
"disagreement did not happen. Case is already folded, so this is a real\n"
|
||||||
|
"disagreement about a layer, not about orthography."
|
||||||
|
)
|
||||||
|
|
||||||
if undeclared:
|
if undeclared:
|
||||||
ok = False
|
ok = False
|
||||||
print("\nUNDECLARED TOOLING CONTACT — a finding under §11, not a tracked gap:")
|
print("\nUNDECLARED TOOLING CONTACT — a finding under §11, not a tracked gap:")
|
||||||
|
|
|
||||||
|
|
@ -25,15 +25,62 @@ def _decl() -> dict:
|
||||||
return yaml.safe_load((ROOT / "layer.yaml").read_text())
|
return yaml.safe_load((ROOT / "layer.yaml").read_text())
|
||||||
|
|
||||||
|
|
||||||
|
def _intent_frontmatter() -> dict:
|
||||||
|
lines = (ROOT / "INTENT.md").read_text().splitlines()
|
||||||
|
assert lines[0].strip() == "---", "INTENT.md must carry frontmatter — it is the declaration"
|
||||||
|
end = next(i for i, ln in enumerate(lines[1:], 1) if ln.strip() == "---")
|
||||||
|
return yaml.safe_load("\n".join(lines[1:end]))
|
||||||
|
|
||||||
|
|
||||||
|
def _fold(value: str) -> str:
|
||||||
|
return str(value).strip().encode("ascii", "ignore").decode().lower()
|
||||||
|
|
||||||
|
|
||||||
class TestDeclaration:
|
class TestDeclaration:
|
||||||
def test_declares_staff_layer_in_its_own_voice(self):
|
def test_declares_staff_layer_in_its_own_voice(self):
|
||||||
d = _decl()
|
d = _decl()
|
||||||
assert d["repository"] == "ops-warden"
|
assert d["repository"] == "ops-warden"
|
||||||
assert d["layer"] == "staff"
|
assert _fold(d["layer"]) == "staff"
|
||||||
assert d["standard_version"] == "0.7"
|
|
||||||
# §11: "only the repository's own file, in its own voice, conforms."
|
# §11: "only the repository's own file, in its own voice, conforms."
|
||||||
assert d["declared_by"] == "docs/adr/ADR-0010"
|
assert d["declared_by"] == "docs/adr/ADR-0010"
|
||||||
|
|
||||||
|
def test_intent_md_carries_the_governing_declaration(self):
|
||||||
|
"""GH-DEC-2026-017 §1 / A11: INTENT.md's frontmatter is the declaration."""
|
||||||
|
assert _fold(_intent_frontmatter()["layer"]) == "staff"
|
||||||
|
|
||||||
|
def test_sidecar_is_marked_derived_and_names_its_source(self):
|
||||||
|
"""§11's derived-artifact rule, applied to the layer sidecar."""
|
||||||
|
d = _decl()
|
||||||
|
assert d["derived"] is True
|
||||||
|
assert d["derived_from"] == "INTENT.md"
|
||||||
|
|
||||||
|
def test_the_two_forms_agree_once_case_is_folded(self):
|
||||||
|
"""A11: the derived form must agree; A9: comparison folds case.
|
||||||
|
|
||||||
|
`Staff` in INTENT.md and `staff` in layer.yaml are the SAME value. This
|
||||||
|
test is deliberately a fold rather than an equality: the ruling asked
|
||||||
|
nobody to re-spell anything, and an equality assertion here would be this
|
||||||
|
repository quietly doing the re-spelling the ruling declined to order.
|
||||||
|
The next *real* divergence — a different layer — still fails.
|
||||||
|
"""
|
||||||
|
assert _fold(_decl()["layer"]) == _fold(_intent_frontmatter()["layer"])
|
||||||
|
|
||||||
|
def test_layer_is_in_section_3_closed_vocabulary(self):
|
||||||
|
"""A9: {Taxonomy, Tooling, Engine, Staff}, closed, case-insensitive."""
|
||||||
|
vocabulary = {"taxonomy", "tooling", "engine", "staff"}
|
||||||
|
assert _fold(_intent_frontmatter()["layer"]) in vocabulary
|
||||||
|
assert _fold(_decl()["layer"]) in vocabulary
|
||||||
|
|
||||||
|
def test_no_declaration_carries_a_standard_version(self):
|
||||||
|
"""GH-DEC-2026-017 §5 / A12 — and the regression guard on its return.
|
||||||
|
|
||||||
|
The field was removed from the estate's reference form, not just from
|
||||||
|
this file. A field that is present will be branched on, so absence is
|
||||||
|
asserted rather than trusted.
|
||||||
|
"""
|
||||||
|
assert "standard_version" not in _decl()
|
||||||
|
assert "standard_version" not in _intent_frontmatter()
|
||||||
|
|
||||||
def test_every_tooling_contact_maps_to_a_declared_shape(self):
|
def test_every_tooling_contact_maps_to_a_declared_shape(self):
|
||||||
"""§11 mechanical check — the guard against a new undeclared client."""
|
"""§11 mechanical check — the guard against a new undeclared client."""
|
||||||
result = subprocess.run(
|
result = subprocess.run(
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,16 @@ reference declaration artifacts. It does not redefine the layer model.
|
||||||
|
|
||||||
1. Read `net-kingdom/SECURITY-COMPANION.md`, then use the accepted
|
1. Read `net-kingdom/SECURITY-COMPANION.md`, then use the accepted
|
||||||
`net-kingdom/canon/standards/security-layer-model_v0.7.md` for the normative
|
`net-kingdom/canon/standards/security-layer-model_v0.7.md` for the normative
|
||||||
layer, Tooling-contact, and PEP obligations.
|
layer, Tooling-contact, and PEP obligations. `v0.8` is proposed, not accepted,
|
||||||
2. Use ops-warden's `layer.yaml` as the machine-readable declaration reference.
|
and its acceptance flip is held on amendments A9–A13 (`GH-DEC-2026-019`) —
|
||||||
Adapt its repository, layer, contacts, and ownership facts; do not copy
|
but those amendments' substance **already governs** through the decision
|
||||||
ops-warden-specific claims as your own.
|
record that authorises each of them, so declare to the shape below now.
|
||||||
|
2. **Declare in your own `INTENT.md` frontmatter.** That is the declaration
|
||||||
|
(`GH-DEC-2026-017` §1). Use ops-warden's `layer.yaml` as the machine-readable
|
||||||
|
reference *form*, which is a **derived** artifact that must be marked derived,
|
||||||
|
must name `INTENT.md` as its source, and must agree with it. Adapt its
|
||||||
|
repository, layer, contacts, and ownership facts; do not copy ops-warden-specific
|
||||||
|
claims as your own.
|
||||||
3. If the repository is PEP-shaped, use `pep-stance.yaml` as the stance-map
|
3. If the repository is PEP-shaped, use `pep-stance.yaml` as the stance-map
|
||||||
reference and publish the resulting path in the repository's layer declaration.
|
reference and publish the resulting path in the repository's layer declaration.
|
||||||
4. Adapt `scripts/check_layer_conformance.py` and
|
4. Adapt `scripts/check_layer_conformance.py` and
|
||||||
|
|
@ -31,6 +37,51 @@ python3 scripts/check_layer_conformance.py
|
||||||
pytest tests/test_layer_conformance.py
|
pytest tests/test_layer_conformance.py
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Reference-form change set — 2026-09-21 (`GH-DEC-2026-017`)
|
||||||
|
|
||||||
|
**If you copied ops-warden's `layer.yaml` before 2026-09-21, it is now the wrong
|
||||||
|
shape in three ways.** The change is to the reference form, which is why
|
||||||
|
`gate-house` asked ops-warden to make it here rather than asking each adopter to
|
||||||
|
work it out. Apply all three in your own repository; ops-warden does not edit
|
||||||
|
anyone else's files.
|
||||||
|
|
||||||
|
1. **Remove `standard_version:` from the sidecar *and* from your `INTENT.md`
|
||||||
|
frontmatter.** A layer declaration MUST NOT carry a standard version
|
||||||
|
(`GH-DEC-2026-017` §5, amendment A12): the declared layer is a standing
|
||||||
|
property that does not change when the standard is revised, and a version in
|
||||||
|
the declaration makes every revision read as though it invalidated every
|
||||||
|
declaration. Keeping it "for information" was declined explicitly — a field
|
||||||
|
that is present will be branched on. Version-scoped state belongs in the
|
||||||
|
derived conformance record. If your checker lists `standard_version` as a
|
||||||
|
required key, or prints it in a report line, it will now **reject a conforming
|
||||||
|
declaration** — fix the checker in the same commit.
|
||||||
|
2. **Add `derived: true` and `derived_from: INTENT.md`.** The sidecar is a derived
|
||||||
|
artifact under §11's derived-artifact rule and does not govern
|
||||||
|
(`GH-DEC-2026-017` §1, amendment A11). If your `INTENT.md` has no frontmatter
|
||||||
|
`layer:` key, add one — that, not the sidecar and not a prose line, is your
|
||||||
|
declaration.
|
||||||
|
3. **Fold ASCII case before comparing a layer value, and re-spell nothing.** §3's
|
||||||
|
vocabulary is closed and has **four** tokens — `Taxonomy`, `Tooling`,
|
||||||
|
`Engine`, `Staff` — and comparison is case-insensitive (`GH-DEC-2026-017` §2
|
||||||
|
and §3, amendment A9). `Staff` and `staff` are the same value; a lowercase
|
||||||
|
declaration is conforming, not tolerated. Two traps: a validator that admits
|
||||||
|
only three tokens and rejects `Taxonomy` carries a defect — the layer this
|
||||||
|
standard itself occupies is in the vocabulary; and an equality assertion
|
||||||
|
between your two forms silently performs the re-spelling the ruling declined
|
||||||
|
to order. Assert the **fold**, so a real layer divergence still fails.
|
||||||
|
|
||||||
|
A disagreement between the two forms, after folding, is a **finding in its own
|
||||||
|
right** and must be reported rather than resolved away by precedence. Precedence
|
||||||
|
says which value is your answer; it does not say the disagreement did not happen.
|
||||||
|
|
||||||
|
`pep-stance.yaml` is **not** a layer declaration and is out of scope here: its
|
||||||
|
`standard_version` / `standard_version_reviewed` pair is a stance map's record of
|
||||||
|
what was reviewed, and stays.
|
||||||
|
|
||||||
|
ops-warden's applied instance of this change set is commit-local: `INTENT.md`,
|
||||||
|
`layer.yaml`, `scripts/check_layer_conformance.py`, `tests/test_layer_conformance.py`.
|
||||||
|
Read those four together rather than the sidecar alone.
|
||||||
|
|
||||||
## Ownership boundary
|
## Ownership boundary
|
||||||
|
|
||||||
`gate-house` owns what the model requires. Each repository owns the truth of its
|
`gate-house` owns what the model requires. Each repository owns the truth of its
|
||||||
|
|
|
||||||
|
|
@ -235,7 +235,7 @@ T05 stays `wait` on the remaining two: `ops-mason` (no stance map published) and
|
||||||
|
|
||||||
```task
|
```task
|
||||||
id: WARDEN-WP-0034-T06
|
id: WARDEN-WP-0034-T06
|
||||||
status: wait
|
status: done
|
||||||
priority: low
|
priority: low
|
||||||
state_hub_task_id: "b3b573df-2d2d-5a2c-9662-a13e435be57b"
|
state_hub_task_id: "b3b573df-2d2d-5a2c-9662-a13e435be57b"
|
||||||
```
|
```
|
||||||
|
|
@ -247,24 +247,51 @@ while both follow the standard. Nine of nine repositories carrying both forms do
|
||||||
the same thing (flex-auth `tools/survey_layer_declarations.go`, receipt
|
the same thing (flex-auth `tools/survey_layer_declarations.go`, receipt
|
||||||
`docs/evidence/2026-09-21-layer-declaration-survey.json`).
|
`docs/evidence/2026-09-21-layer-declaration-survey.json`).
|
||||||
|
|
||||||
**Waiting on gate-house for two rulings**: which form governs, and whether the §3
|
**RULED 2026-09-21, APPLIED 2026-09-21.** `GH-DEC-2026-017`
|
||||||
vocabulary is case-sensitive. The custodian's estate-wide sweep adds a third that
|
(`gate-house@def0af2`, amendments A9-A13) answers both questions, and the answer
|
||||||
bears on it — §3's table capitalises and types engines `Engines` while §4's
|
to the second dissolves the first's consequence:
|
||||||
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
|
- **`INTENT.md` governs**; `layer.yaml` is a derived artifact that must be marked
|
||||||
gate-house owns, and doing it in the one place §11 says another repository may
|
derived, must name `INTENT.md` as its source, and must agree with it.
|
||||||
not speak for us. It would also erase the evidence the ruling is being made
|
- **The §3 vocabulary is case-insensitive**, closed, and has four tokens
|
||||||
against: the finding is visible because nine repositories exhibit it, and a
|
(`Taxonomy`, `Tooling`, `Engine`, `Staff`). A conformance run MUST ASCII-fold
|
||||||
repository that quietly normalises itself makes the estate read as more
|
case before comparing, and **no repository was asked to re-spell anything**.
|
||||||
conformant than it is. Position recorded in
|
`Staff` and `staff` are one value.
|
||||||
`docs/layer-declaration-precedence.md`; both files carry a comment saying not to
|
- **A declaration MUST NOT carry a standard version** — and that field is the
|
||||||
"fix" the divergence.
|
*reference form's*, not this repository's habit, so ops-warden was asked to
|
||||||
|
remove it here rather than each of seven adopters deciding.
|
||||||
|
|
||||||
**Done when:** gate-house rules, the non-governing file is changed to match in
|
Verified before editing against gate-house's own committed files rather than the
|
||||||
one commit, and a regression test asserts the two declarations agree so the next
|
inbox message: the decision at `gate-house@def0af2`, amendments A9-A13 in
|
||||||
divergence is caught rather than surveyed.
|
`docs/amendments/v0.8-section-11-declaration-amendments.md`, and §3/§4/§11 of
|
||||||
|
`net-kingdom/canon/standards/security-layer-model_v0.8.md`.
|
||||||
|
|
||||||
|
**What was applied.** `standard_version` removed from `layer.yaml` **and** from
|
||||||
|
`INTENT.md` frontmatter (the ruling's subject is the declaration, and `INTENT.md`
|
||||||
|
is the declaration), with the version-pinned `standard:` path de-versioned for the
|
||||||
|
same reason; `derived: true` / `derived_from: INTENT.md` added; **no layer value
|
||||||
|
changed**; `scripts/check_layer_conformance.py` rewritten to read `INTENT.md` as
|
||||||
|
governing, fold case, validate the closed four-token vocabulary, require the
|
||||||
|
derived marking, and reject a returning `standard_version` — it previously
|
||||||
|
*required* that field and so would have rejected the conforming declaration this
|
||||||
|
ruling produces; `tests/test_layer_conformance.py` asserts the **fold** rather
|
||||||
|
than equality, because an equality assertion would perform the re-spelling the
|
||||||
|
ruling declined to order. `pep-stance.yaml` untouched: a stance map is not a layer
|
||||||
|
declaration, and the schema beyond the derived marking and the version is
|
||||||
|
explicitly not ruled.
|
||||||
|
|
||||||
|
**Evidence.** `python3 scripts/check_layer_conformance.py --report` exits 0 and
|
||||||
|
prints the governing form and the derived one separately; `pytest
|
||||||
|
tests/test_layer_conformance.py` green; full suite and `ruff` green. Reasoning
|
||||||
|
and the adopter change set: `docs/layer-declaration-precedence.md` and
|
||||||
|
`wiki/playbooks/netkingdom-layer-declaration.md`.
|
||||||
|
|
||||||
|
**Left open, and not decided here.** Where the removed version now lives. A12
|
||||||
|
says version-scoped state belongs in the derived conformance record, which
|
||||||
|
"already MUST" carry the version it was derived at; ops-warden has a re-runnable
|
||||||
|
checker that emits nothing durable, not an emitted record. Whether §11 expects an
|
||||||
|
emitted artifact or a re-runnable check discharges it is asked of gate-house in
|
||||||
|
message `4220413a` and unanswered. Nothing applied above depends on the answer.
|
||||||
|
|
||||||
**Ruled the same day, and still `wait` — deliberately.** `GH-DEC-2026-017`
|
**Ruled the same day, and still `wait` — deliberately.** `GH-DEC-2026-017`
|
||||||
(message `3715e247`) landed hours later: `INTENT.md` governs, the sidecar is a
|
(message `3715e247`) landed hours later: `INTENT.md` governs, the sidecar is a
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue