Apply GH-DEC-2026-017: INTENT.md governs, layer.yaml is derived, no version

Verified against gate-house's committed ruling (decisions/decisions.md,
GH-DEC-2026-017) and amendments A9-A13, then ops-warden's reference change set
(a70f559, wiki/playbooks/netkingdom-layer-declaration.md). They agree.

layer.yaml: standard_version removed; derived: true and derived_from:
INTENT.md added; declared_by kept. INTENT.md frontmatter never carried
standard_version, but its standard: value was a version-pinned path; it is
de-versioned as the reference instance did. No layer value is re-spelled:
INTENT.md still says Engine and layer.yaml still says engine.

The checker changes in the same commit because it listed standard_version as
a required key: removing the field alone would have made a conforming
declaration exit 2 MALFORMED. It now reads INTENT.md as the governing form,
requires the derived marking, rejects a returning standard_version in either
form, checks both layer values against the closed four-token vocabulary
(Taxonomy included) after an ASCII fold, and reports a post-fold disagreement
between the forms as a finding rather than resolving it by precedence.

Tests assert the fold, not per-file spelling, and cover fold agreement, a
real disagreement, the closed vocabulary and a returning version. Full suite
430 passed.

role:, pep-stance.yaml and schema_version are untouched (not ruled). Still
open: where the removed version lives in a derived conformance record; asked
of gate-house by ops-warden (4220413a), followed rather than chosen here.

Closes the SECRETS-WP-0008 note that waited on the reference form.

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:
tegwick 2026-09-21 07:37:53 +02:00
parent 2b4cff04c5
commit 8a48cb05df
5 changed files with 226 additions and 22 deletions

View file

@ -1,9 +1,16 @@
--- ---
# 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 `Engine` here and `engine` there
# are the same value and neither is re-spelled (GH-DEC-2026-017 §2).
layer: Engine layer: Engine
role: Lifecycle role: Lifecycle
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): the
# declared layer is a standing property that does not change when the standard
# is revised. Version-scoped state belongs in the derived conformance record.
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
declared_at: "2026-08-29" declared_at: "2026-08-29"
--- ---

View file

@ -1,8 +1,15 @@
# secrets-engine — NetKingdom security layer declaration # secrets-engine — NetKingdom security layer declaration
# #
# Framework: net-kingdom/canon/standards/security-layer-model_v0.7.md # Framework: net-kingdom/canon/standards/security-layer-model
# Companion: net-kingdom/SECURITY-COMPANION.md # Companion: net-kingdom/SECURITY-COMPANION.md
# Voice: INTENT.md (this repository's own declaration, §11) # Voice: INTENT.md (this repository's own declaration, §11)
#
# DERIVED ARTIFACT (§11, GH-DEC-2026-017 §1 / A11). INTENT.md's frontmatter
# `layer:` key is the declaration and governs; this file derives from it and
# must agree with it. `engine` here and `Engine` there are one token: §3's
# vocabulary is closed and compared ASCII case-insensitively (GH-DEC-2026-017
# §2 / A9), so nothing is re-spelled. No standard version is carried here
# (GH-DEC-2026-017 §5 / A12).
# Validate: python3 scripts/check_layer_conformance.py # Validate: python3 scripts/check_layer_conformance.py
# #
# §11 requires a machine-readable form because prose cannot distinguish a # §11 requires a machine-readable form because prose cannot distinguish a
@ -16,7 +23,8 @@
schema_version: "0.1" schema_version: "0.1"
framework: netkingdom-security-layer-model framework: netkingdom-security-layer-model
standard_version: "0.7" derived: true
derived_from: INTENT.md
repository: secrets-engine repository: secrets-engine
layer: engine layer: engine
role: lifecycle role: lifecycle

View file

@ -4,10 +4,21 @@
Read-only. This is the Engine/Lifecycle adaptation of the ops-warden reference Read-only. This is the Engine/Lifecycle adaptation of the ops-warden reference
checker. §5 Staff shapes do not apply to the owned OpenBao contact. checker. §5 Staff shapes do not apply to the owned OpenBao contact.
Two declaration forms are read. Per GH-DEC-2026-017 §1 (amendment A11)
INTENT.md's frontmatter `layer:` key governs; layer.yaml is a derived artifact
that must be marked derived, must name INTENT.md, and must agree with it. The
sidecar is still read, because a disagreement between the two is a finding in
its own right, reported rather than resolved away by precedence.
Layer values are compared against §3's closed four-token vocabulary after an
ASCII case-fold (GH-DEC-2026-017 §2-§3, amendment A9). Nothing is re-spelled:
`Engine` and `engine` are one token. Neither form carries a standard version
(GH-DEC-2026-017 §5, amendment A12), and its return is rejected.
Mechanical checks: Mechanical checks:
- a machine-readable declaration exists and says Engine / Lifecycle - INTENT.md frontmatter carries the governing `layer:` (Engine) and role
- INTENT.md frontmatter matches that declaration - layer.yaml is marked derived from INTENT.md and agrees with it after folding
- no authorization decision surface is exposed - no authorization decision surface is exposed
- the PEP stance map is published at the path named in the declaration - the PEP stance map is published at the path named in the declaration
- every OpenBao subprocess adapter lives in a module listed as owned tooling - every OpenBao subprocess adapter lives in a module listed as owned tooling
@ -35,6 +46,34 @@ DECISION_SURFACE = re.compile(
r"""\b(evaluate_policy|check_permission|render_decision|pdp_decide)\b""" r"""\b(evaluate_policy|check_permission|render_decision|pdp_decide)\b"""
) )
# §3's vocabulary: closed, four tokens, compared case-insensitively
# (GH-DEC-2026-017 §3, amendment A9). Taxonomy is in it.
LAYER_VOCABULARY = {"taxonomy", "tooling", "engine", "staff"}
EXPECTED_LAYER = "engine"
def _fold(value: object) -> 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 _no_standard_version(where: str, data: dict) -> None:
if "standard_version" in data:
print(
f"MALFORMED: {where} carries 'standard_version' — a layer declaration "
"MUST NOT carry a standard version (§11 as amended by A12)"
)
raise SystemExit(2)
def _in_vocabulary(where: str, layer: object) -> None:
if _fold(layer) not in LAYER_VOCABULARY:
print(
f"MALFORMED: {where} declares layer {layer!r}, outside §3's closed "
f"vocabulary {sorted(LAYER_VOCABULARY)} (case-insensitive)"
)
raise SystemExit(2)
def load_declaration() -> dict: def load_declaration() -> dict:
if not DECL.exists(): if not DECL.exists():
@ -45,7 +84,8 @@ def load_declaration() -> dict:
"layer", "layer",
"role", "role",
"repository", "repository",
"standard_version", "derived",
"derived_from",
"owned_tooling", "owned_tooling",
"decision_surfaces_exposed", "decision_surfaces_exposed",
"pep_shaped", "pep_shaped",
@ -54,9 +94,18 @@ def load_declaration() -> dict:
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)
if decl["layer"] != "engine": # §11 derived-artifact rule (GH-DEC-2026-017 §1): marked, naming its source.
print(f"MALFORMED: declared layer is {decl['layer']!r}, expected 'engine'") if decl["derived"] is not True:
print("MALFORMED: layer.yaml must be marked 'derived: true' (§11, GH-DEC-2026-017 §1)")
raise SystemExit(2) 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)
_no_standard_version("layer.yaml", decl)
_in_vocabulary("layer.yaml", decl["layer"])
if decl["role"] != "lifecycle": if decl["role"] != "lifecycle":
print(f"MALFORMED: declared role is {decl['role']!r}, expected 'lifecycle'") print(f"MALFORMED: declared role is {decl['role']!r}, expected 'lifecycle'")
raise SystemExit(2) raise SystemExit(2)
@ -75,7 +124,13 @@ def intent_frontmatter() -> dict:
if end < 0: if end < 0:
print("MALFORMED: INTENT.md frontmatter is unclosed") print("MALFORMED: INTENT.md frontmatter is unclosed")
raise SystemExit(2) raise SystemExit(2)
return yaml.safe_load(text[3:end]) or {} front = yaml.safe_load(text[3:end]) or {}
if "layer" not in front:
print("MALFORMED: INTENT.md frontmatter has no 'layer' key — §11's declaration")
raise SystemExit(2)
_no_standard_version("INTENT.md frontmatter", front)
_in_vocabulary("INTENT.md frontmatter", front["layer"])
return front
def owned_modules(decl: dict) -> set[str]: def owned_modules(decl: dict) -> set[str]:
@ -118,13 +173,24 @@ def main() -> int:
ap.add_argument("--report", action="store_true") ap.add_argument("--report", action="store_true")
args = ap.parse_args() args = ap.parse_args()
decl = load_declaration()
front = intent_frontmatter() front = intent_frontmatter()
decl = load_declaration()
ok = True ok = True
if str(front.get("layer", "")).lower() != "engine": governing = front["layer"]
if _fold(governing) != EXPECTED_LAYER:
ok = False ok = False
print("FINDING: INTENT.md frontmatter layer is not Engine") print(f"FINDING: INTENT.md frontmatter layer is {governing!r}, not Engine")
# §11 as amended (A11): a post-fold disagreement between the two forms is a
# finding in its own right, reported rather than resolved by precedence.
if _fold(decl["layer"]) != _fold(governing):
ok = False
print(
"FINDING: DECLARATION DISAGREEMENT (§11) — "
f"INTENT.md (governs) layer: {governing!r}; "
f"layer.yaml (derived) layer: {decl['layer']!r}. "
"Case is already folded; this is a disagreement about a layer."
)
if str(front.get("role", "")).lower() != "lifecycle": if str(front.get("role", "")).lower() != "lifecycle":
ok = False ok = False
print("FINDING: INTENT.md frontmatter role is not Lifecycle") print("FINDING: INTENT.md frontmatter role is not Lifecycle")
@ -161,9 +227,10 @@ def main() -> int:
if args.report: if args.report:
print( print(
f"{decl['repository']} — layer: {decl['layer']} " f"{decl['repository']} — layer: {governing} role: {front.get('role')} "
f"role: {decl['role']} (model v{decl['standard_version']})" "(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']}") print(f"declared by {decl['declared_by']}")
print(f"pep stance: {decl['pep_stance']}") print(f"pep stance: {decl['pep_stance']}")
print(f"owned OpenBao modules: {sorted(owned)}") print(f"owned OpenBao modules: {sorted(owned)}")

View file

@ -6,6 +6,7 @@ from the code is worse than none.
""" """
from __future__ import annotations from __future__ import annotations
import importlib.util
import subprocess import subprocess
import sys import sys
from pathlib import Path from pathlib import Path
@ -38,28 +39,108 @@ def _stance() -> dict:
return yaml.safe_load(STANCE.read_text(encoding="utf-8")) return yaml.safe_load(STANCE.read_text(encoding="utf-8"))
def _front() -> dict:
text = INTENT.read_text(encoding="utf-8")
assert text.startswith("---"), "companion §2 requires INTENT.md frontmatter"
end = text.find("\n---", 3)
return yaml.safe_load(text[3:end])
def _fold(value: object) -> str:
"""§3 as amended (A9): comparison is ASCII case-insensitive."""
return str(value).strip().encode("ascii", "ignore").decode().lower()
def _checker():
spec = importlib.util.spec_from_file_location("check_layer_conformance", SCRIPT)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
def test_declares_engine_lifecycle_in_its_own_voice(): def test_declares_engine_lifecycle_in_its_own_voice():
assert DECL.exists(), "no layer.yaml — §11 requires a machine-readable declaration" assert DECL.exists(), "no layer.yaml — §11 requires a machine-readable declaration"
data = _decl() data = _decl()
assert data["repository"] == "secrets-engine" assert data["repository"] == "secrets-engine"
assert data["layer"] == "engine" # Fold, never equality: the ruling declined to order a re-spelling.
assert _fold(data["layer"]) == "engine"
assert data["role"] == "lifecycle" assert data["role"] == "lifecycle"
assert data["declared_by"] == "INTENT.md" assert data["declared_by"] == "INTENT.md"
assert data["derived"] is True
assert data["derived_from"] == "INTENT.md"
assert data["decision_surfaces_exposed"] == "none" assert data["decision_surfaces_exposed"] == "none"
assert data["pep_shaped"] is True assert data["pep_shaped"] is True
def test_intent_frontmatter_matches_declaration(): def test_intent_frontmatter_matches_declaration():
text = INTENT.read_text(encoding="utf-8") front = _front()
assert text.startswith("---"), "companion §2 requires INTENT.md frontmatter" assert _fold(front["layer"]) == "engine"
end = text.find("\n---", 3) assert _fold(_decl()["layer"]) == _fold(front["layer"]), (
front = yaml.safe_load(text[3:end]) "INTENT.md governs and layer.yaml must agree after folding (GH-DEC-2026-017 §1-§2)"
assert front["layer"] == "Engine" )
assert front["role"] == "Lifecycle" assert front["role"] == "Lifecycle"
assert front["declaration"] == "layer.yaml" assert front["declaration"] == "layer.yaml"
assert front["pep_stance"] == "pep-stance.yaml" assert front["pep_stance"] == "pep-stance.yaml"
def test_no_standard_version_in_either_form():
"""GH-DEC-2026-017 §5 / A12: a layer declaration carries no standard version."""
assert "standard_version" not in _decl()
assert "standard_version" not in _front()
assert not str(_front().get("standard", "")).endswith(".md")
def _run_checker(tmp_path, monkeypatch, intent_layer: str, sidecar_layer: str) -> int:
checker = _checker()
front = _front()
front["layer"] = intent_layer
intent = tmp_path / "INTENT.md"
intent.write_text("---\n" + yaml.safe_dump(front) + "---\n\n# INTENT\n", encoding="utf-8")
decl = _decl()
decl["layer"] = sidecar_layer
sidecar = tmp_path / "layer.yaml"
sidecar.write_text(yaml.safe_dump(decl), encoding="utf-8")
monkeypatch.setattr(checker, "INTENT", intent)
monkeypatch.setattr(checker, "DECL", sidecar)
monkeypatch.setattr(sys, "argv", ["check_layer_conformance.py"])
try:
return checker.main()
except SystemExit as exc:
return int(exc.code)
def test_checker_folds_case_between_forms(tmp_path, monkeypatch):
assert _run_checker(tmp_path, monkeypatch, "ENGINE", "engine") == 0
assert _run_checker(tmp_path, monkeypatch, "Engine", "Engine") == 0
def test_checker_reports_a_real_disagreement(tmp_path, monkeypatch, capsys):
"""A post-fold disagreement is a finding, not resolved by precedence."""
assert _run_checker(tmp_path, monkeypatch, "Engine", "staff") == 1
assert "DECLARATION DISAGREEMENT" in capsys.readouterr().out
def test_checker_vocabulary_is_closed_at_four_tokens(tmp_path, monkeypatch, capsys):
checker = _checker()
assert checker.LAYER_VOCABULARY == {"taxonomy", "tooling", "engine", "staff"}
# Taxonomy is in the vocabulary: a finding (wrong layer for this repo), not MALFORMED.
assert _run_checker(tmp_path, monkeypatch, "Taxonomy", "taxonomy") == 1
assert _run_checker(tmp_path, monkeypatch, "surface", "surface") == 2
assert "outside §3's closed vocabulary" in capsys.readouterr().out
def test_checker_rejects_a_returning_standard_version(tmp_path, monkeypatch):
checker = _checker()
decl = _decl()
decl["standard_version"] = "0.8"
sidecar = tmp_path / "layer.yaml"
sidecar.write_text(yaml.safe_dump(decl), encoding="utf-8")
monkeypatch.setattr(checker, "DECL", sidecar)
with pytest.raises(SystemExit) as raised:
checker.load_declaration()
assert raised.value.code == 2
def test_checker_passes_on_the_real_tree(): def test_checker_passes_on_the_real_tree():
result = subprocess.run( result = subprocess.run(
[sys.executable, str(SCRIPT)], [sys.executable, str(SCRIPT)],

View file

@ -9,7 +9,7 @@ flavor: implementation
owner: grok owner: grok
topic_slug: custodian topic_slug: custodian
created: "2026-08-29" created: "2026-08-29"
updated: "2026-09-09" updated: "2026-09-21"
state_hub_workstream_id: "9c9e5164-b2f5-5ea2-a557-5368d65e9fe0" state_hub_workstream_id: "9c9e5164-b2f5-5ea2-a557-5368d65e9fe0"
--- ---
@ -416,6 +416,47 @@ No task is opened here by hand. This is a note against the workplan that already
owns `layer.yaml` / `pep-stance.yaml` / INTENT frontmatter staying in one voice; owns `layer.yaml` / `pep-stance.yaml` / INTENT frontmatter staying in one voice;
the work lands under that exit criterion when ops-warden's form is published. the work lands under that exit criterion when ops-warden's form is published.
### 2026-09-21 GH-DEC-2026-017 applied — reference form published, note closed
ops-warden published the reference form (commit `a70f559`,
`wiki/playbooks/netkingdom-layer-declaration.md` "Reference-form change set").
Re-read against the ruling in `gate-house/decisions/decisions.md` and
amendments A9A13 before editing; the ruling and the playbook agree.
Applied in one commit, field and checker together:
- `layer.yaml`: `standard_version: "0.7"` removed; `derived: true` and
`derived_from: INTENT.md` added (`declared_by: INTENT.md` kept, as the note
above required). Header comment marks the file derived and drops the version
from the framework citation.
- `INTENT.md` frontmatter: never carried `standard_version`, but its
`standard:` value was a version-pinned path (`..._v0.7.md`). De-versioned to
`net-kingdom/canon/standards/security-layer-model`, as the reference instance
did, because a pinned path in the governing form is a standard version by
another name. The field is kept; only the pin is gone.
- **No layer value re-spelled.** INTENT says `Engine`, layer.yaml says
`engine`; both unchanged.
- `scripts/check_layer_conformance.py`: `standard_version` was a required key,
so removing the field alone would have exited 2 MALFORMED. It now reads
INTENT.md as the governing form, requires the derived marking, rejects a
returning `standard_version` in either form, validates both layer values
against the closed four-token vocabulary (Taxonomy included) after an ASCII
fold, and reports a post-fold disagreement between the forms as a finding.
- `tests/test_layer_conformance.py`: per-file equality on the layer spelling
replaced by fold assertions; new tests for fold agreement, a real
disagreement (finding, exit 1), the closed vocabulary (`surface` exit 2,
`Taxonomy` admitted), and a returning `standard_version` (exit 2).
Full suite: 430 passed.
`role:` untouched (not ruled). `pep-stance.yaml` untouched (a stance map, not
a declaration). `schema_version` left at `0.1` — ops-warden bumped its own, but
the ruling does not call for it.
**Still open, not ours to answer:** where the removed version lives. A12 says
the derived conformance record already MUST carry it; our checker, like
ops-warden's, is re-runnable and emits nothing durable. ops-warden asked
gate-house (message `4220413a`); we follow that answer rather than choose.
## Exit criteria ## Exit criteria
- The published PEP stance is the shipped default and stance application is - The published PEP stance is the shipped default and stance application is