Apply GH-DEC-2026-020: remove companion_version from layer.yaml
A12 r2 reaches every key and value of the declaration, including the
companion's version. The standard: path in INTENT.md was already
unversioned and is unchanged. tests/test_layer_declaration.py fails if a
version key, a versioned standard path, or companion_version returns to
the INTENT.md frontmatter or layer.yaml; schema_version and comments are
not reached. One prose citation ("the v0.5 scope rule") in a rationale
value is allowlisted by exact text and reported to gate-house as open.
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
39e3380447
commit
71ae259877
2 changed files with 99 additions and 3 deletions
|
|
@ -28,9 +28,11 @@ derived_from: INTENT.md
|
||||||
|
|
||||||
# No `standard_version` key, here or in INTENT.md: GH-DEC-2026-017 §5 / A12 —
|
# No `standard_version` key, here or in INTENT.md: GH-DEC-2026-017 §5 / A12 —
|
||||||
# a layer declaration MUST NOT carry a standard version. The declared layer is
|
# a layer declaration MUST NOT carry a standard version. The declared layer is
|
||||||
# a standing property; version-scoped state belongs in the derived conformance
|
# a standing property. Do not add it back.
|
||||||
# record. Do not add it back.
|
#
|
||||||
companion_version: "0.2"
|
# No `companion_version` either: GH-DEC-2026-020 §2 / A12 r2 — the companion's
|
||||||
|
# version in a declaration is the same pin. tests/test_layer_declaration.py
|
||||||
|
# fails if it, or a versioned standard path, comes back.
|
||||||
repository: approval-engine
|
repository: approval-engine
|
||||||
layer: engine
|
layer: engine
|
||||||
role: pip # §3.3 engine typing; §4 catalog
|
role: pip # §3.3 engine typing; §4 catalog
|
||||||
|
|
|
||||||
94
tests/test_layer_declaration.py
Normal file
94
tests/test_layer_declaration.py
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
"""A12 r2 (GH-DEC-2026-017 §5, GH-DEC-2026-020): the layer declaration carries
|
||||||
|
no version of the standard or of its companion, in any key or value.
|
||||||
|
|
||||||
|
The declaration is every key of the INTENT.md frontmatter and every key of the
|
||||||
|
derived layer.yaml. Comments and `schema_version` are not reached. Stance,
|
||||||
|
claims and classification maps are not declarations and are not checked here.
|
||||||
|
|
||||||
|
Parsed as text, not YAML: pyyaml is not a dependency of this repository, and a
|
||||||
|
skipped test would enforce nothing.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import re
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
|
||||||
|
# A version-bearing key (any key ending in `version`, except the file's own
|
||||||
|
# schema version) or a version in a value, including one carried in a path or
|
||||||
|
# file name such as `security-layer-model_v0.7.md`.
|
||||||
|
VERSION_KEY = re.compile(r"^\s*-?\s*([A-Za-z0-9_]*version)\s*:", re.IGNORECASE)
|
||||||
|
VERSION_VALUE = re.compile(r"_v\d+(\.\d+)*|\bv\d+\.\d+")
|
||||||
|
|
||||||
|
# OPEN, reported to gate-house with this repository's A12 r2 findings: a prose
|
||||||
|
# citation of a past rule inside a rationale value ("the v0.5 scope rule") is
|
||||||
|
# not a pin, but A12 r2's "no key or value" reads literally as reaching it.
|
||||||
|
# Listed here, exactly, so it stays visible and nothing else slips past.
|
||||||
|
CITATION_ALLOWLIST = {
|
||||||
|
"Progress events. Outside §5 by the v0.5 scope rule. Recorded, not",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _declaration_lines(text: str) -> list[str]:
|
||||||
|
lines = []
|
||||||
|
for raw in text.splitlines():
|
||||||
|
line = raw.split(" #", 1)[0]
|
||||||
|
if line.lstrip().startswith("#") or not line.strip():
|
||||||
|
continue
|
||||||
|
lines.append(line)
|
||||||
|
return lines
|
||||||
|
|
||||||
|
|
||||||
|
def _intent_frontmatter() -> str:
|
||||||
|
text = (ROOT / "INTENT.md").read_text()
|
||||||
|
match = re.match(r"^---\n(.*?)\n---\n", text, re.DOTALL)
|
||||||
|
assert match, "INTENT.md has no frontmatter; the declaration lives there"
|
||||||
|
return match.group(1)
|
||||||
|
|
||||||
|
|
||||||
|
def _findings(name: str, text: str) -> list[str]:
|
||||||
|
found = []
|
||||||
|
for line in _declaration_lines(text):
|
||||||
|
key = VERSION_KEY.match(line)
|
||||||
|
if key and key.group(1).lower() != "schema_version":
|
||||||
|
found.append(f"{name}: version key: {line.strip()}")
|
||||||
|
elif (
|
||||||
|
not key
|
||||||
|
and VERSION_VALUE.search(line)
|
||||||
|
and line.strip() not in CITATION_ALLOWLIST
|
||||||
|
):
|
||||||
|
found.append(f"{name}: versioned value: {line.strip()}")
|
||||||
|
return found
|
||||||
|
|
||||||
|
|
||||||
|
def test_declaration_carries_no_version():
|
||||||
|
findings = _findings("INTENT.md frontmatter", _intent_frontmatter())
|
||||||
|
findings += _findings("layer.yaml", (ROOT / "layer.yaml").read_text())
|
||||||
|
assert not findings, "\n".join(findings)
|
||||||
|
|
||||||
|
|
||||||
|
def test_companion_version_absent():
|
||||||
|
assert "companion_version" not in "\n".join(
|
||||||
|
_declaration_lines((ROOT / "layer.yaml").read_text())
|
||||||
|
)
|
||||||
|
assert "companion_version" not in "\n".join(
|
||||||
|
_declaration_lines(_intent_frontmatter())
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_standard_path_unversioned():
|
||||||
|
match = re.search(r"^standard:\s*(\S+)", _intent_frontmatter(), re.MULTILINE)
|
||||||
|
assert match, "INTENT.md frontmatter names no standard"
|
||||||
|
assert match.group(1) == "net-kingdom/canon/standards/security-layer-model"
|
||||||
|
|
||||||
|
|
||||||
|
def test_detector_catches_the_forms_ruled_on():
|
||||||
|
# The check must see the pin under any name, not only `standard_version`.
|
||||||
|
assert _findings("x", 'companion_version: "0.2"\n')
|
||||||
|
assert _findings("x", 'standard_version: "0.7"\n')
|
||||||
|
assert _findings(
|
||||||
|
"x", "standard: net-kingdom/canon/standards/security-layer-model_v0.7.md\n"
|
||||||
|
)
|
||||||
|
assert not _findings("x", 'schema_version: "0.1"\n')
|
||||||
|
assert not _findings("x", "# Companion: SECURITY-COMPANION.md v0.2\n")
|
||||||
|
assert not _findings("x", ' statute: "§9.4"\n "5.1": []\n')
|
||||||
Loading…
Add table
Add a link
Reference in a new issue