# NetKingdom layer declaration route Date: 2026-09-04 Catalog: `netkingdom-layer-declaration` Doctrine owner: `gate-house` Path steward: `ops-warden` This page is a route from the accepted NetKingdom security companion to the reference declaration artifacts. It does not redefine the layer model. ## Worker checklist 1. Read `net-kingdom/SECURITY-COMPANION.md`, then use the accepted `net-kingdom/canon/standards/security-layer-model_v0.7.md` for the normative layer, Tooling-contact, and PEP obligations. `v0.8` is proposed, not accepted, and its acceptance flip is held on amendments A9–A13 (`GH-DEC-2026-019`) — but those amendments' substance **already governs** through the decision 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 reference and publish the resulting path in the repository's layer declaration. 4. Adapt `scripts/check_layer_conformance.py` and `tests/test_layer_conformance.py`, then run both checks in the declaring repo. 5. Send the declaration and any stance-map inventory pointer to `gate-house` for doctrine/register review. Route credential or operational-lane questions back through `warden route`; do not place doctrine in the routing catalog. Reference checks in this checkout: ```bash python3 scripts/check_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 to the conformance *run* (see the 2026-09-21 `GH-DEC-2026-020` section below; the "derived conformance record" this line used to name was a defect in §5 and nobody is required to emit one). 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. ## Reach and run-version change set — 2026-09-21 (`GH-DEC-2026-020`, A12 r2) **If you copied ops-warden's checker before this change, it enforces A12 by key name only, and prints no version.** Both are now defects. `GH-DEC-2026-020` refines A12 as A12 r2; verify it in `gate-house` `decisions/decisions.md` and `docs/amendments/v0.8-section-11-declaration-amendments.md` (§ "A12 r2"), not from this page. 1. **A version anywhere in the declaration counts.** The declaration is every key and value of your `INTENT.md` frontmatter and of your derived sidecar. No key or value carries a version of the standard **or of its companion**, including a version-bearing path: `standard: .../security-layer-model_v0.7.md` becomes `standard: .../security-layer-model` (`GH-DEC-2026-020` §1). A de-versioned path was a required change, not a voluntary one. 2. **`companion_version` counts** and comes out of the declaration (§2). 3. **Not reached:** comments, and a file's own `schema_version`. Keeping or removing them is equally fine; do not edit them just to tidy. 4. **Not a declaration, not checked:** stance maps (`pep-stance.yaml`), claims maps, evidence classifications. Their version is what makes them re-readable when clause text changes; keep it. Your checker **MUST NOT** apply A12 to them (§3). 5. **The version belongs to the run.** A re-runnable checker is sufficient — not "for now" — if **every** run prints the standard version or commit it checks against and the scope it ranged over, including the PASS line (§4). No repository must emit a durable conformance record; whoever retains a run's output owes that copy's version. The pattern is kings-guard's: a `VALIDATED_AGAINST` constant in the checker, printed on every run. 6. **Widen your checker from key name to content.** ops-warden's `scripts/check_layer_conformance.py` now carries `VALIDATED_AGAINST`, `SCOPE` and `find_version_pins()`, which walks every parsed key and value, skips `schema_version`, and flags any key naming a standard/companion version and any value carrying a versioned file name or path. It prints version and scope before loading anything, so even a MALFORMED run states them. Copy that, set `VALIDATED_AGAINST` to what *your* run checks against, and add tests that fail if a versioned `standard:` path or a `companion_version` comes back (`tests/test_layer_conformance.py` has the reference set). Change declaration, checker and tests in the same commit, and re-spell no layer value. ### Reference detector and `VALIDATED_AGAINST` — the estate reference (`GH-DEC-2026-021`) The estate's checkers each wrote their own version detector in the 020 round, and they diverge: some flag any key *ending* in `version`, some any key *containing* it, one flags `vN.N` anywhere in prose while the others ignore prose. The checkers also disagree on what `VALIDATED_AGAINST` names. `GH-DEC-2026-021` §3 rules that the detector below is the **estate reference** every checker's copy converges on — when the copy is next edited, and no later than the commit that re-points its `VALIDATED_AGAINST` after the v0.8 flip (`GH-WP-0004-T11`). Each repository implements its own copy. **One detector.** Copy this from ops-warden's checker as-is: ```python VERSION_KEY = re.compile(r"(standard|companion).*version|version.*(standard|companion)", re.I) VERSION_IN_VALUE = re.compile(r"[_\-.]v\d+(\.\d+)*(\.md)?\b|@v?\d+\.\d+", re.I) NOT_REACHED_KEYS = {"schema_version"} IDENTITY_KEYS = {"standard", "companion"} IDENTITY_VERSION = re.compile(r"\bv?\d+\.\d+", re.I) def find_version_pins(node, where="", identity=False): # walk every parsed key and value ... # see scripts/check_layer_conformance.py ``` - **Keys:** flag a key that names a *standard or companion* version (`standard_version`, `companion_version`, `standard_version_reviewed`) — not every key containing `version`. `schema_version` is the file's own schema and is skipped (A12 r2). **Do not flag a key such as `intent_version`**: it names neither the standard nor its companion. `informed-decision`'s declaring frontmatter carries `intent_version: 0.1.0` (the version of its own `INTENT.md`), and a detector that flags every key containing or ending in `version` fails it wrongly (`GH-DEC-2026-021`, Context). - **Values:** flag a version carried in a *file name or path* (`_v0.7`, `-v0.8.md`, `@0.7`) — the `standard: …_v0.7.md` case §1 rules on. - **Identity-bearing values:** any version token (`v?N.N`) in the value of a `standard:` or `companion:` key is a pin (`GH-DEC-2026-021` §3), so `standard: security-layer-model v0.7` fails. - **Deliberate over-reach:** the path pattern flags a versioned path of *any* document in a declaration, wider than A12's "this standard or its companion". `GH-DEC-2026-021` §3 accepts this; a repository that needs such a path raises it, and it is not waived by allowlist. - **Comments:** never read; the detector runs on parsed YAML, so they are gone. - **Prose citations in a value** (e.g. a rationale string saying "the v0.5 scope rule"): **not reached** (`GH-DEC-2026-021` §1, A12 r3). A revision cited in prose is provenance, not a pin. The reference detector does not flag a bare `vN.N` outside a `standard:`/`companion:` value, and no allowlist is needed. A12 r3 is out for assent; if it is rejected in favour of the literal reading, the reference is widened to any `vN.N` in any value. **Name the text in force.** While v0.8's acceptance flip is held (`GH-DEC-2026-019`), `VALIDATED_AGAINST` names the **accepted** text — `security-layer-model_v0.7.md`, with a net-kingdom commit — plus the decision records whose rulings the checker enforces beyond v0.7 (`GH-DEC-2026-017`, `GH-DEC-2026-020`, `GH-DEC-2026-021`), with a gate-house commit recommended (`GH-DEC-2026-021` §2). Naming the proposed v0.8 states a check against text that does not yet govern. Change it in the same commit that follows the flip. ops-warden's constant is the example: ```text net-kingdom/canon/standards/security-layer-model_v0.7.md (net-kingdom@66dc491) as amended by GH-DEC-2026-017, GH-DEC-2026-020 and GH-DEC-2026-021 (A9-A13, A12 r3; gate-house@39d9287) ``` **Citation.** Cite the ruling by the decision's body section: `GH-DEC-2026-017` §5, statute A12 (now A12 r2). This page's "§5" is canonical (`GH-DEC-2026-020`); the decision's `rationale:` part numbers are a summary and are not cited. ## Ownership boundary `gate-house` owns what the model requires. Each repository owns the truth of its own declaration. `ops-warden` owns only this discoverable path to those sources.