Apply GH-DEC-2026-021: identity-value pins, prose citations not reached.
The playbook detector is the estate reference (021 §3). Add its one addition to the reference and the checker: any v?N.N in a standard: or companion: value is a pin. The prose-citation note moves from pending to not reached (021 §1, A12 r3), and intent_version is noted as a key that must not be flagged. VALIDATED_AGAINST keeps accepted v0.7 and adds GH-DEC-2026-021 at gate-house@39d9287. 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
0f9ada0b0d
commit
39791526a0
3 changed files with 61 additions and 21 deletions
|
|
@ -58,12 +58,13 @@ DECL = ROOT / "layer.yaml"
|
|||
|
||||
VALID_SHAPES = {"5.1", "5.2", "5.3"}
|
||||
|
||||
# What every run checks against, printed on every run (GH-DEC-2026-020 §4, A12 r2).
|
||||
# The accepted text is v0.7 at net-kingdom@66dc491; the amendments that already
|
||||
# govern through their decision records are named with it.
|
||||
# What every run checks against, printed on every run (GH-DEC-2026-020 §4,
|
||||
# GH-DEC-2026-021 §2). The accepted text is v0.7 at net-kingdom@66dc491; the
|
||||
# decision records whose rulings this checker enforces beyond v0.7 are named with it.
|
||||
VALIDATED_AGAINST = (
|
||||
"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)"
|
||||
"as amended by GH-DEC-2026-017, GH-DEC-2026-020 and GH-DEC-2026-021 "
|
||||
"(A9-A13, A12 r3; gate-house@39d9287)"
|
||||
)
|
||||
# What every run ranges over. pep-stance.yaml is deliberately outside it.
|
||||
SCOPE = "INTENT.md frontmatter, layer.yaml, src/warden/**/*.py"
|
||||
|
|
@ -72,12 +73,18 @@ SCOPE = "INTENT.md frontmatter, layer.yaml, src/warden/**/*.py"
|
|||
# declaration. Keys: anything naming a standard/companion version. Values: a
|
||||
# versioned file name or path (`_v0.7`, `-v0.8.md`) or a bare version string on a
|
||||
# version-named key. `schema_version` is the file's own schema, not reached.
|
||||
# GH-DEC-2026-021 §1/§3 (A12 r3): a version is reached only as a pin. Any version
|
||||
# token (`v?N.N`) in the value of an identity-bearing key (`standard:`,
|
||||
# `companion:`) is a pin; a revision cited in other prose is provenance and is not
|
||||
# reached. Keys such as `intent_version` name neither and are not flagged.
|
||||
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: str = "") -> list[str]:
|
||||
def find_version_pins(node, where: str = "", identity: bool = False) -> list[str]:
|
||||
"""Every place in a parsed declaration that carries a standard/companion version.
|
||||
|
||||
Walks every key and value (comments are gone after parsing, which is the
|
||||
|
|
@ -92,12 +99,14 @@ def find_version_pins(node, where: str = "") -> list[str]:
|
|||
if VERSION_KEY.search(str(k)):
|
||||
pins.append(f"{here} (key names a standard/companion version)")
|
||||
continue
|
||||
pins.extend(find_version_pins(v, here))
|
||||
pins.extend(find_version_pins(v, here, str(k).lower() in IDENTITY_KEYS))
|
||||
elif isinstance(node, list):
|
||||
for i, v in enumerate(node):
|
||||
pins.extend(find_version_pins(v, f"{where}[{i}]"))
|
||||
pins.extend(find_version_pins(v, f"{where}[{i}]", identity))
|
||||
elif isinstance(node, str) and VERSION_IN_VALUE.search(node):
|
||||
pins.append(f"{where} = {node!r} (value carries a version)")
|
||||
elif isinstance(node, str) and identity and IDENTITY_VERSION.search(node):
|
||||
pins.append(f"{where} = {node!r} (identity-bearing value carries a version)")
|
||||
return pins
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -115,6 +115,21 @@ class TestDeclaration:
|
|||
assert checker.find_version_pins({"layer": "Staff", "companion_version": "0.2"})
|
||||
assert checker.find_version_pins({"nested": {"standard_version": "0.7"}})
|
||||
|
||||
def test_version_token_in_identity_value_is_a_pin(self):
|
||||
"""GH-DEC-2026-021 §3: any `v?N.N` in a standard:/companion: value is a pin."""
|
||||
checker = _checker()
|
||||
pins = checker.find_version_pins({"standard": "security-layer-model v0.7"})
|
||||
assert pins and pins[0].startswith("standard")
|
||||
assert checker.find_version_pins({"companion": "SECURITY-COMPANION 0.2"})
|
||||
assert checker.find_version_pins({"nested": {"standard": ["security-layer-model v0.8"]}})
|
||||
|
||||
def test_prose_citation_and_intent_version_are_not_reached(self):
|
||||
"""GH-DEC-2026-021 §1 (A12 r3): prose provenance and `intent_version` pass."""
|
||||
checker = _checker()
|
||||
assert checker.find_version_pins(
|
||||
{"layer": "Staff", "note": "Outside §5 by the v0.5 scope rule", "intent_version": "0.1.0"}
|
||||
) == []
|
||||
|
||||
def test_schema_version_is_not_reached(self):
|
||||
assert _checker().find_version_pins({"schema_version": "0.2", "layer": "Staff"}) == []
|
||||
|
||||
|
|
|
|||
|
|
@ -122,15 +122,16 @@ from this page.
|
|||
(`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
|
||||
### 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. 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.
|
||||
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:
|
||||
|
||||
|
|
@ -138,35 +139,50 @@ over it.
|
|||
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=""): # walk every parsed key and value
|
||||
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).
|
||||
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"): **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.
|
||||
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 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
|
||||
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 and GH-DEC-2026-020 (A9-A13, A12 r2; gate-house@d8c82a8)
|
||||
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`
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue