ops-warden/wiki/playbooks/netkingdom-layer-declaration.md
tegwick 0f9ada0b0d
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
Give the playbook one reference version detector and a VALIDATED_AGAINST rule.
Reference practice, not a ruling: copies diverged on key matching and on prose,
and on naming v0.7 versus the held v0.8. Prose citations under A12 are marked
pending with gate-house.

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
2026-09-21 11:32:09 +02:00

10 KiB
Raw Blame History

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 A9A13 (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:

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 — practice, not a ruling

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. Neither point is ruled by GH-DEC-2026-020. What follows is the reference form to copy so the copies stop diverging; it is steward's practice, and a gate-house ruling wins over it.

One detector. Copy this from ops-warden's checker as-is:

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"}

def find_version_pins(node, where=""):  # 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).
  • 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.
  • 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"): pending. Whether A12 reaches them is an open question to gate-house. The reference detector deliberately does not flag a bare vN.N preceded by a space, so it neither enforces nor waives an answer that has not been given. Do not widen or narrow this in your copy until gate-house rules.

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 amendments already govern (GH-DEC-2026-017, GH-DEC-2026-020), with a gate-house commit. 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:

net-kingdom/canon/standards/security-layer-model_v0.7.md (net-kingdom@66dc491)
as amended by GH-DEC-2026-017 and GH-DEC-2026-020 (A9-A13, A12 r2; gate-house@d8c82a8)

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.