Implement §5.3 machine-readably — layer.yaml, checker, conformance tests
The security layer model moved v0.1 -> v0.4 (accepted) after ops-warden's
assent. Both §5 asks from ADR-0010 were adopted: §5.2 now sanctions the conduit
shape on the supplied-authority property, and §5.3 is the declared engine gap
amendment, carrying the four fields verbatim and crediting ops-warden's
delegation machinery as prior art.
Which creates an obligation. §5.3 requires those fields MACHINE-READABLY, and
§11 makes "every direct Tooling client maps to a declared §5.1/§5.2/§5.3 entry"
a mechanical check. ops-warden's declaration was prose in INTENT.md — the repo
that proposed the shape was not implementing it.
layer.yaml is the map: 5 contacts (2 declared gaps, 1 read-only observation,
2 conduits) plus the non-Tooling clients recorded explicitly so the check is
total rather than silently selective.
scripts/check_layer_conformance.py enforces it and found three undeclared
modules on its first run — all false positives (help text, a docstring, and the
doubles library that SIMULATES bao rather than calling it), which is why the
scan now matches invocation shapes instead of the word: an httpx call built
against the configured OpenBao address, or an argv whose first element is the
bao binary.
tests/test_layer_conformance.py adds the §5.2 test the standard says SHOULD
exist: _caller_env() returns the caller's environment unchanged, and proxy.py
is asserted not to reference X-Vault-Token, approle login, or token create — a
conduit that presents its own token is not a conduit.
No assertion on review dates, deliberately: a date-triggered failure breaks the
build on a calendar day with no code change, the same reasoning WP-0033-T05
recorded for blocker staleness.
398 tests pass, ruff clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YWBMovyFoy9RRrfL7zKvPJ
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 4014535@bnt-lap001
Assistant-Session: d0036016-73e8-4da1-8e47-563e3ab39a3c
2026-08-29 02:45:29 +02:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
"""Check ops-warden against the NetKingdom security layer model (§5, §11).
|
|
|
|
|
|
Apply GH-DEC-2026-017: INTENT.md governs, the sidecar is derived, no version
Verified against gate-house's own committed files before editing, not the inbox
message: GH-DEC-2026-017 in decisions/decisions.md at gate-house@def0af2,
amendments A9-A13 in docs/amendments/v0.8-section-11-declaration-amendments.md,
and sections 3, 4 and 11 of net-kingdom's security-layer-model_v0.8.md. The
ruling and docs/layer-declaration-precedence.md's secondary account agreed.
INTENT.md's frontmatter is the declaration; layer.yaml is a derived artifact,
now marked derived: true / derived_from: INTENT.md, and it does not govern.
standard_version is removed from BOTH forms. The ruling's general form is that a
layer declaration must not carry a standard version, and INTENT.md is the
declaration, so removing it from the sidecar alone would have left the field in
the only file that actually declares. INTENT.md's version-pinned `standard:`
path is de-versioned for the same reason: a pinned path reads as a validity
condition. The version ops-warden assented at stays with the assent, ADR-0010.
NO LAYER VALUE IS CHANGED. INTENT.md still says Staff and layer.yaml still says
staff. Section 3's vocabulary is closed, four tokens, and case-insensitive: the
two forms were never in disagreement about a layer, and the ruling asked nobody
to re-spell anything. The comment marking the divergence is rewritten from
"unruled, do not touch" to "ruled, folding case is the checker's job".
check_layer_conformance.py would have rejected the conforming declaration this
ruling produces -- it listed standard_version as a required key. It now reads
INTENT.md as the governing form, ASCII-folds before comparing, validates both
values against the closed four-token vocabulary (Taxonomy included; omitting it
is the defect A9 records against the estate's other validator), requires the
derived marking, rejects a returning standard_version in either file, and
reports a post-fold disagreement between the forms as a finding rather than
resolving it away by precedence.
The test asserts the fold, not equality. An equality assertion here would be
this repository quietly performing the re-spelling the ruling declined to order;
the fold still fails on a real layer divergence.
pep-stance.yaml is untouched. A stance map is not a layer declaration, and the
sidecar schema beyond the derived marking and the version is explicitly not
ruled.
layer.yaml is the form seven repositories copied, so the adopter change set is
written out in wiki/playbooks/netkingdom-layer-declaration.md -- including the
trap that an adopter which also copied the checker turns a conforming
declaration into MALFORMED exit 2 by removing the field alone. No other
repository is edited here.
Still open: where the removed version lives. A12 says the derived conformance
record "already MUST" carry it; ops-warden has a re-runnable checker that emits
nothing durable. Asked of gate-house in message 4220413a, unanswered, and left
open rather than answered by choosing. Nothing above depends on it.
Carries WARDEN-WP-0034-T06 to done.
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 02:38:55 +02:00
|
|
|
Read-only. Two declaration forms are read, and the precedence between them is
|
|
|
|
|
`GH-DEC-2026-017` §1 (amendment A11): **INTENT.md's frontmatter governs** and
|
|
|
|
|
`layer.yaml` is a derived artifact that must be marked derived, must name
|
|
|
|
|
INTENT.md as its source, and must agree with it. The sidecar is read anyway,
|
|
|
|
|
because a disagreement between the two is itself a finding and is reported
|
|
|
|
|
rather than resolved away by precedence.
|
|
|
|
|
|
|
|
|
|
Comparison against §3's closed four-token vocabulary ASCII-folds case before
|
|
|
|
|
comparing (`GH-DEC-2026-017` §2, amendment A9): two spellings of a token do not
|
|
|
|
|
describe two boundaries, and a check that reports findings about capital letters
|
|
|
|
|
buries the one real disagreement it exists to find.
|
|
|
|
|
|
2026-09-21 09:38:17 +02:00
|
|
|
Neither form carries a version of the standard or of its companion, in any key
|
|
|
|
|
or value (`GH-DEC-2026-017` §5, amendment A12 as refined by A12 r2 /
|
|
|
|
|
`GH-DEC-2026-020` §1-§2). The rule reaches content, not a key name: a
|
|
|
|
|
`standard_version` key, a `companion_version` key, and a version-bearing path
|
|
|
|
|
such as `standard: .../security-layer-model_v0.7.md` are the same pin. Comments
|
|
|
|
|
and a file's own `schema_version` are not reached. Stance, claims and
|
|
|
|
|
evidence-classification maps (`pep-stance.yaml`) are NOT declarations and this
|
|
|
|
|
check does not read them (`GH-DEC-2026-020` §3).
|
|
|
|
|
|
|
|
|
|
The version belongs to the run (`GH-DEC-2026-020` §4): every run prints
|
|
|
|
|
VALIDATED_AGAINST and SCOPE below, including the PASS line, following
|
|
|
|
|
kings-guard's pattern. A retained copy of this output is a derived artifact
|
|
|
|
|
whose version is owed by whoever retains it.
|
Apply GH-DEC-2026-017: INTENT.md governs, the sidecar is derived, no version
Verified against gate-house's own committed files before editing, not the inbox
message: GH-DEC-2026-017 in decisions/decisions.md at gate-house@def0af2,
amendments A9-A13 in docs/amendments/v0.8-section-11-declaration-amendments.md,
and sections 3, 4 and 11 of net-kingdom's security-layer-model_v0.8.md. The
ruling and docs/layer-declaration-precedence.md's secondary account agreed.
INTENT.md's frontmatter is the declaration; layer.yaml is a derived artifact,
now marked derived: true / derived_from: INTENT.md, and it does not govern.
standard_version is removed from BOTH forms. The ruling's general form is that a
layer declaration must not carry a standard version, and INTENT.md is the
declaration, so removing it from the sidecar alone would have left the field in
the only file that actually declares. INTENT.md's version-pinned `standard:`
path is de-versioned for the same reason: a pinned path reads as a validity
condition. The version ops-warden assented at stays with the assent, ADR-0010.
NO LAYER VALUE IS CHANGED. INTENT.md still says Staff and layer.yaml still says
staff. Section 3's vocabulary is closed, four tokens, and case-insensitive: the
two forms were never in disagreement about a layer, and the ruling asked nobody
to re-spell anything. The comment marking the divergence is rewritten from
"unruled, do not touch" to "ruled, folding case is the checker's job".
check_layer_conformance.py would have rejected the conforming declaration this
ruling produces -- it listed standard_version as a required key. It now reads
INTENT.md as the governing form, ASCII-folds before comparing, validates both
values against the closed four-token vocabulary (Taxonomy included; omitting it
is the defect A9 records against the estate's other validator), requires the
derived marking, rejects a returning standard_version in either file, and
reports a post-fold disagreement between the forms as a finding rather than
resolving it away by precedence.
The test asserts the fold, not equality. An equality assertion here would be
this repository quietly performing the re-spelling the ruling declined to order;
the fold still fails on a real layer divergence.
pep-stance.yaml is untouched. A stance map is not a layer declaration, and the
sidecar schema beyond the derived marking and the version is explicitly not
ruled.
layer.yaml is the form seven repositories copied, so the adopter change set is
written out in wiki/playbooks/netkingdom-layer-declaration.md -- including the
trap that an adopter which also copied the checker turns a conforming
declaration into MALFORMED exit 2 by removing the field alone. No other
repository is edited here.
Still open: where the removed version lives. A12 says the derived conformance
record "already MUST" carry it; ops-warden has a re-runnable checker that emits
nothing durable. Asked of gate-house in message 4220413a, unanswered, and left
open rather than answered by choosing. Nothing above depends on it.
Carries WARDEN-WP-0034-T06 to done.
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 02:38:55 +02:00
|
|
|
|
|
|
|
|
Makes §11's second mechanical check real:
|
Implement §5.3 machine-readably — layer.yaml, checker, conformance tests
The security layer model moved v0.1 -> v0.4 (accepted) after ops-warden's
assent. Both §5 asks from ADR-0010 were adopted: §5.2 now sanctions the conduit
shape on the supplied-authority property, and §5.3 is the declared engine gap
amendment, carrying the four fields verbatim and crediting ops-warden's
delegation machinery as prior art.
Which creates an obligation. §5.3 requires those fields MACHINE-READABLY, and
§11 makes "every direct Tooling client maps to a declared §5.1/§5.2/§5.3 entry"
a mechanical check. ops-warden's declaration was prose in INTENT.md — the repo
that proposed the shape was not implementing it.
layer.yaml is the map: 5 contacts (2 declared gaps, 1 read-only observation,
2 conduits) plus the non-Tooling clients recorded explicitly so the check is
total rather than silently selective.
scripts/check_layer_conformance.py enforces it and found three undeclared
modules on its first run — all false positives (help text, a docstring, and the
doubles library that SIMULATES bao rather than calling it), which is why the
scan now matches invocation shapes instead of the word: an httpx call built
against the configured OpenBao address, or an argv whose first element is the
bao binary.
tests/test_layer_conformance.py adds the §5.2 test the standard says SHOULD
exist: _caller_env() returns the caller's environment unchanged, and proxy.py
is asserted not to reference X-Vault-Token, approle login, or token create — a
conduit that presents its own token is not a conduit.
No assertion on review dates, deliberately: a date-triggered failure breaks the
build on a calendar day with no code change, the same reasoning WP-0033-T05
recorded for blocker staleness.
398 tests pass, ruff clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YWBMovyFoy9RRrfL7zKvPJ
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 4014535@bnt-lap001
Assistant-Session: d0036016-73e8-4da1-8e47-563e3ab39a3c
2026-08-29 02:45:29 +02:00
|
|
|
|
|
|
|
|
every direct Tooling client in a Staff repository maps to a declared
|
|
|
|
|
§5.1, §5.2, or §5.3 entry
|
|
|
|
|
|
|
|
|
|
The failure this catches is a *new* direct OpenBao contact appearing in
|
|
|
|
|
src/warden/ without an entry in layer.yaml — an undeclared violation (§11),
|
|
|
|
|
which is a finding rather than a tracked gap. It deliberately does NOT check
|
|
|
|
|
the review dates: a date-triggered failure breaks the build on a calendar day
|
|
|
|
|
with no code change (the reasoning recorded in WARDEN-WP-0033-T05), so
|
|
|
|
|
staleness is reported and left to `--report`, never to CI.
|
|
|
|
|
|
|
|
|
|
Exit 0 clean, 1 undeclared contact found, 2 declaration malformed.
|
|
|
|
|
"""
|
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
import argparse
|
|
|
|
|
import re
|
|
|
|
|
import sys
|
|
|
|
|
from datetime import date
|
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
|
|
|
|
import yaml
|
|
|
|
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
|
|
|
SRC = ROOT / "src" / "warden"
|
Apply GH-DEC-2026-017: INTENT.md governs, the sidecar is derived, no version
Verified against gate-house's own committed files before editing, not the inbox
message: GH-DEC-2026-017 in decisions/decisions.md at gate-house@def0af2,
amendments A9-A13 in docs/amendments/v0.8-section-11-declaration-amendments.md,
and sections 3, 4 and 11 of net-kingdom's security-layer-model_v0.8.md. The
ruling and docs/layer-declaration-precedence.md's secondary account agreed.
INTENT.md's frontmatter is the declaration; layer.yaml is a derived artifact,
now marked derived: true / derived_from: INTENT.md, and it does not govern.
standard_version is removed from BOTH forms. The ruling's general form is that a
layer declaration must not carry a standard version, and INTENT.md is the
declaration, so removing it from the sidecar alone would have left the field in
the only file that actually declares. INTENT.md's version-pinned `standard:`
path is de-versioned for the same reason: a pinned path reads as a validity
condition. The version ops-warden assented at stays with the assent, ADR-0010.
NO LAYER VALUE IS CHANGED. INTENT.md still says Staff and layer.yaml still says
staff. Section 3's vocabulary is closed, four tokens, and case-insensitive: the
two forms were never in disagreement about a layer, and the ruling asked nobody
to re-spell anything. The comment marking the divergence is rewritten from
"unruled, do not touch" to "ruled, folding case is the checker's job".
check_layer_conformance.py would have rejected the conforming declaration this
ruling produces -- it listed standard_version as a required key. It now reads
INTENT.md as the governing form, ASCII-folds before comparing, validates both
values against the closed four-token vocabulary (Taxonomy included; omitting it
is the defect A9 records against the estate's other validator), requires the
derived marking, rejects a returning standard_version in either file, and
reports a post-fold disagreement between the forms as a finding rather than
resolving it away by precedence.
The test asserts the fold, not equality. An equality assertion here would be
this repository quietly performing the re-spelling the ruling declined to order;
the fold still fails on a real layer divergence.
pep-stance.yaml is untouched. A stance map is not a layer declaration, and the
sidecar schema beyond the derived marking and the version is explicitly not
ruled.
layer.yaml is the form seven repositories copied, so the adopter change set is
written out in wiki/playbooks/netkingdom-layer-declaration.md -- including the
trap that an adopter which also copied the checker turns a conforming
declaration into MALFORMED exit 2 by removing the field alone. No other
repository is edited here.
Still open: where the removed version lives. A12 says the derived conformance
record "already MUST" carry it; ops-warden has a re-runnable checker that emits
nothing durable. Asked of gate-house in message 4220413a, unanswered, and left
open rather than answered by choosing. Nothing above depends on it.
Carries WARDEN-WP-0034-T06 to done.
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 02:38:55 +02:00
|
|
|
INTENT = ROOT / "INTENT.md"
|
Implement §5.3 machine-readably — layer.yaml, checker, conformance tests
The security layer model moved v0.1 -> v0.4 (accepted) after ops-warden's
assent. Both §5 asks from ADR-0010 were adopted: §5.2 now sanctions the conduit
shape on the supplied-authority property, and §5.3 is the declared engine gap
amendment, carrying the four fields verbatim and crediting ops-warden's
delegation machinery as prior art.
Which creates an obligation. §5.3 requires those fields MACHINE-READABLY, and
§11 makes "every direct Tooling client maps to a declared §5.1/§5.2/§5.3 entry"
a mechanical check. ops-warden's declaration was prose in INTENT.md — the repo
that proposed the shape was not implementing it.
layer.yaml is the map: 5 contacts (2 declared gaps, 1 read-only observation,
2 conduits) plus the non-Tooling clients recorded explicitly so the check is
total rather than silently selective.
scripts/check_layer_conformance.py enforces it and found three undeclared
modules on its first run — all false positives (help text, a docstring, and the
doubles library that SIMULATES bao rather than calling it), which is why the
scan now matches invocation shapes instead of the word: an httpx call built
against the configured OpenBao address, or an argv whose first element is the
bao binary.
tests/test_layer_conformance.py adds the §5.2 test the standard says SHOULD
exist: _caller_env() returns the caller's environment unchanged, and proxy.py
is asserted not to reference X-Vault-Token, approle login, or token create — a
conduit that presents its own token is not a conduit.
No assertion on review dates, deliberately: a date-triggered failure breaks the
build on a calendar day with no code change, the same reasoning WP-0033-T05
recorded for blocker staleness.
398 tests pass, ruff clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YWBMovyFoy9RRrfL7zKvPJ
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 4014535@bnt-lap001
Assistant-Session: d0036016-73e8-4da1-8e47-563e3ab39a3c
2026-08-29 02:45:29 +02:00
|
|
|
DECL = ROOT / "layer.yaml"
|
|
|
|
|
|
|
|
|
|
VALID_SHAPES = {"5.1", "5.2", "5.3"}
|
|
|
|
|
|
2026-09-21 13:05:24 +02:00
|
|
|
# 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.
|
2026-09-21 09:38:17 +02:00
|
|
|
VALIDATED_AGAINST = (
|
|
|
|
|
"net-kingdom/canon/standards/security-layer-model_v0.7.md (net-kingdom@66dc491) "
|
2026-09-21 13:05:24 +02:00
|
|
|
"as amended by GH-DEC-2026-017, GH-DEC-2026-020 and GH-DEC-2026-021 "
|
|
|
|
|
"(A9-A13, A12 r3; gate-house@39d9287)"
|
2026-09-21 09:38:17 +02:00
|
|
|
)
|
|
|
|
|
# What every run ranges over. pep-stance.yaml is deliberately outside it.
|
|
|
|
|
SCOPE = "INTENT.md frontmatter, layer.yaml, src/warden/**/*.py"
|
|
|
|
|
|
|
|
|
|
# A12 r2: a version of the standard or companion in any key or value of the
|
|
|
|
|
# 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.
|
2026-09-21 13:05:24 +02:00
|
|
|
# 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.
|
2026-09-21 09:38:17 +02:00
|
|
|
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"}
|
2026-09-21 13:05:24 +02:00
|
|
|
IDENTITY_KEYS = {"standard", "companion"}
|
|
|
|
|
IDENTITY_VERSION = re.compile(r"\bv?\d+\.\d+", re.I)
|
2026-09-21 09:38:17 +02:00
|
|
|
|
|
|
|
|
|
2026-09-21 13:05:24 +02:00
|
|
|
def find_version_pins(node, where: str = "", identity: bool = False) -> list[str]:
|
2026-09-21 09:38:17 +02:00
|
|
|
"""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
|
|
|
|
|
A12 r2 exclusion). Returns human-readable locations; empty means clean.
|
|
|
|
|
"""
|
|
|
|
|
pins: list[str] = []
|
|
|
|
|
if isinstance(node, dict):
|
|
|
|
|
for k, v in node.items():
|
|
|
|
|
here = f"{where}.{k}" if where else str(k)
|
|
|
|
|
if str(k) in NOT_REACHED_KEYS:
|
|
|
|
|
continue
|
|
|
|
|
if VERSION_KEY.search(str(k)):
|
|
|
|
|
pins.append(f"{here} (key names a standard/companion version)")
|
|
|
|
|
continue
|
2026-09-21 13:05:24 +02:00
|
|
|
pins.extend(find_version_pins(v, here, str(k).lower() in IDENTITY_KEYS))
|
2026-09-21 09:38:17 +02:00
|
|
|
elif isinstance(node, list):
|
|
|
|
|
for i, v in enumerate(node):
|
2026-09-21 13:05:24 +02:00
|
|
|
pins.extend(find_version_pins(v, f"{where}[{i}]", identity))
|
2026-09-21 09:38:17 +02:00
|
|
|
elif isinstance(node, str) and VERSION_IN_VALUE.search(node):
|
|
|
|
|
pins.append(f"{where} = {node!r} (value carries a version)")
|
2026-09-21 13:05:24 +02:00
|
|
|
elif isinstance(node, str) and identity and IDENTITY_VERSION.search(node):
|
|
|
|
|
pins.append(f"{where} = {node!r} (identity-bearing value carries a version)")
|
2026-09-21 09:38:17 +02:00
|
|
|
return pins
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _reject_version_pins(label: str, node) -> None:
|
|
|
|
|
pins = find_version_pins(node)
|
|
|
|
|
if pins:
|
|
|
|
|
print(
|
|
|
|
|
f"MALFORMED: {label} carries a standard/companion version — a layer "
|
|
|
|
|
"declaration MUST NOT, in any key or value (§11 as amended by A12 r2, "
|
|
|
|
|
"GH-DEC-2026-020 §1-§2):"
|
|
|
|
|
)
|
|
|
|
|
for p in pins:
|
|
|
|
|
print(f" {p}")
|
|
|
|
|
raise SystemExit(2)
|
|
|
|
|
|
Apply GH-DEC-2026-017: INTENT.md governs, the sidecar is derived, no version
Verified against gate-house's own committed files before editing, not the inbox
message: GH-DEC-2026-017 in decisions/decisions.md at gate-house@def0af2,
amendments A9-A13 in docs/amendments/v0.8-section-11-declaration-amendments.md,
and sections 3, 4 and 11 of net-kingdom's security-layer-model_v0.8.md. The
ruling and docs/layer-declaration-precedence.md's secondary account agreed.
INTENT.md's frontmatter is the declaration; layer.yaml is a derived artifact,
now marked derived: true / derived_from: INTENT.md, and it does not govern.
standard_version is removed from BOTH forms. The ruling's general form is that a
layer declaration must not carry a standard version, and INTENT.md is the
declaration, so removing it from the sidecar alone would have left the field in
the only file that actually declares. INTENT.md's version-pinned `standard:`
path is de-versioned for the same reason: a pinned path reads as a validity
condition. The version ops-warden assented at stays with the assent, ADR-0010.
NO LAYER VALUE IS CHANGED. INTENT.md still says Staff and layer.yaml still says
staff. Section 3's vocabulary is closed, four tokens, and case-insensitive: the
two forms were never in disagreement about a layer, and the ruling asked nobody
to re-spell anything. The comment marking the divergence is rewritten from
"unruled, do not touch" to "ruled, folding case is the checker's job".
check_layer_conformance.py would have rejected the conforming declaration this
ruling produces -- it listed standard_version as a required key. It now reads
INTENT.md as the governing form, ASCII-folds before comparing, validates both
values against the closed four-token vocabulary (Taxonomy included; omitting it
is the defect A9 records against the estate's other validator), requires the
derived marking, rejects a returning standard_version in either file, and
reports a post-fold disagreement between the forms as a finding rather than
resolving it away by precedence.
The test asserts the fold, not equality. An equality assertion here would be
this repository quietly performing the re-spelling the ruling declined to order;
the fold still fails on a real layer divergence.
pep-stance.yaml is untouched. A stance map is not a layer declaration, and the
sidecar schema beyond the derived marking and the version is explicitly not
ruled.
layer.yaml is the form seven repositories copied, so the adopter change set is
written out in wiki/playbooks/netkingdom-layer-declaration.md -- including the
trap that an adopter which also copied the checker turns a conforming
declaration into MALFORMED exit 2 by removing the field alone. No other
repository is edited here.
Still open: where the removed version lives. A12 says the derived conformance
record "already MUST" carry it; ops-warden has a re-runnable checker that emits
nothing durable. Asked of gate-house in message 4220413a, unanswered, and left
open rather than answered by choosing. Nothing above depends on it.
Carries WARDEN-WP-0034-T06 to done.
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 02:38:55 +02:00
|
|
|
# §3's vocabulary, closed, four tokens (GH-DEC-2026-017 §3, amendment A9). The
|
|
|
|
|
# canonical spellings are §4's catalog-column forms; comparison is ASCII
|
|
|
|
|
# case-insensitive, so the fold is what is stored and `Taxonomy` is in the set —
|
|
|
|
|
# omitting it is the defect A9 records against the estate's other validator.
|
|
|
|
|
LAYER_VOCABULARY = {"taxonomy", "tooling", "engine", "staff"}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _fold(value: str) -> 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 load_governing_layer() -> str:
|
|
|
|
|
"""The declaration is INTENT.md's frontmatter `layer:` key (§11, GH-DEC-2026-017 §1).
|
|
|
|
|
|
|
|
|
|
layer.yaml is derived and does not govern. Read without a YAML frontmatter
|
|
|
|
|
dependency: the file is read by humans first and a parser second.
|
|
|
|
|
"""
|
|
|
|
|
if not INTENT.exists():
|
|
|
|
|
print(f"MISSING: {INTENT} — §11's governing declaration form")
|
|
|
|
|
raise SystemExit(2)
|
|
|
|
|
lines = INTENT.read_text().splitlines()
|
|
|
|
|
if not lines or lines[0].strip() != "---":
|
|
|
|
|
print("MALFORMED: INTENT.md has no frontmatter to carry the declaration (§11)")
|
|
|
|
|
raise SystemExit(2)
|
|
|
|
|
end = next((i for i, ln in enumerate(lines[1:], 1) if ln.strip() == "---"), None)
|
|
|
|
|
if end is None:
|
|
|
|
|
print("MALFORMED: INTENT.md frontmatter is not terminated")
|
|
|
|
|
raise SystemExit(2)
|
|
|
|
|
front = yaml.safe_load("\n".join(lines[1:end])) or {}
|
|
|
|
|
if "layer" not in front:
|
|
|
|
|
print("MALFORMED: INTENT.md frontmatter has no 'layer' key — §11's declaration")
|
|
|
|
|
raise SystemExit(2)
|
2026-09-21 09:38:17 +02:00
|
|
|
_reject_version_pins("INTENT.md frontmatter", front)
|
Apply GH-DEC-2026-017: INTENT.md governs, the sidecar is derived, no version
Verified against gate-house's own committed files before editing, not the inbox
message: GH-DEC-2026-017 in decisions/decisions.md at gate-house@def0af2,
amendments A9-A13 in docs/amendments/v0.8-section-11-declaration-amendments.md,
and sections 3, 4 and 11 of net-kingdom's security-layer-model_v0.8.md. The
ruling and docs/layer-declaration-precedence.md's secondary account agreed.
INTENT.md's frontmatter is the declaration; layer.yaml is a derived artifact,
now marked derived: true / derived_from: INTENT.md, and it does not govern.
standard_version is removed from BOTH forms. The ruling's general form is that a
layer declaration must not carry a standard version, and INTENT.md is the
declaration, so removing it from the sidecar alone would have left the field in
the only file that actually declares. INTENT.md's version-pinned `standard:`
path is de-versioned for the same reason: a pinned path reads as a validity
condition. The version ops-warden assented at stays with the assent, ADR-0010.
NO LAYER VALUE IS CHANGED. INTENT.md still says Staff and layer.yaml still says
staff. Section 3's vocabulary is closed, four tokens, and case-insensitive: the
two forms were never in disagreement about a layer, and the ruling asked nobody
to re-spell anything. The comment marking the divergence is rewritten from
"unruled, do not touch" to "ruled, folding case is the checker's job".
check_layer_conformance.py would have rejected the conforming declaration this
ruling produces -- it listed standard_version as a required key. It now reads
INTENT.md as the governing form, ASCII-folds before comparing, validates both
values against the closed four-token vocabulary (Taxonomy included; omitting it
is the defect A9 records against the estate's other validator), requires the
derived marking, rejects a returning standard_version in either file, and
reports a post-fold disagreement between the forms as a finding rather than
resolving it away by precedence.
The test asserts the fold, not equality. An equality assertion here would be
this repository quietly performing the re-spelling the ruling declined to order;
the fold still fails on a real layer divergence.
pep-stance.yaml is untouched. A stance map is not a layer declaration, and the
sidecar schema beyond the derived marking and the version is explicitly not
ruled.
layer.yaml is the form seven repositories copied, so the adopter change set is
written out in wiki/playbooks/netkingdom-layer-declaration.md -- including the
trap that an adopter which also copied the checker turns a conforming
declaration into MALFORMED exit 2 by removing the field alone. No other
repository is edited here.
Still open: where the removed version lives. A12 says the derived conformance
record "already MUST" carry it; ops-warden has a re-runnable checker that emits
nothing durable. Asked of gate-house in message 4220413a, unanswered, and left
open rather than answered by choosing. Nothing above depends on it.
Carries WARDEN-WP-0034-T06 to done.
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 02:38:55 +02:00
|
|
|
layer = front["layer"]
|
|
|
|
|
if _fold(layer) not in LAYER_VOCABULARY:
|
|
|
|
|
print(
|
|
|
|
|
f"MALFORMED: INTENT.md declares layer {layer!r}, outside §3's closed "
|
|
|
|
|
f"vocabulary {sorted(LAYER_VOCABULARY)} (case-insensitive)"
|
|
|
|
|
)
|
|
|
|
|
raise SystemExit(2)
|
|
|
|
|
return layer
|
|
|
|
|
|
Implement §5.3 machine-readably — layer.yaml, checker, conformance tests
The security layer model moved v0.1 -> v0.4 (accepted) after ops-warden's
assent. Both §5 asks from ADR-0010 were adopted: §5.2 now sanctions the conduit
shape on the supplied-authority property, and §5.3 is the declared engine gap
amendment, carrying the four fields verbatim and crediting ops-warden's
delegation machinery as prior art.
Which creates an obligation. §5.3 requires those fields MACHINE-READABLY, and
§11 makes "every direct Tooling client maps to a declared §5.1/§5.2/§5.3 entry"
a mechanical check. ops-warden's declaration was prose in INTENT.md — the repo
that proposed the shape was not implementing it.
layer.yaml is the map: 5 contacts (2 declared gaps, 1 read-only observation,
2 conduits) plus the non-Tooling clients recorded explicitly so the check is
total rather than silently selective.
scripts/check_layer_conformance.py enforces it and found three undeclared
modules on its first run — all false positives (help text, a docstring, and the
doubles library that SIMULATES bao rather than calling it), which is why the
scan now matches invocation shapes instead of the word: an httpx call built
against the configured OpenBao address, or an argv whose first element is the
bao binary.
tests/test_layer_conformance.py adds the §5.2 test the standard says SHOULD
exist: _caller_env() returns the caller's environment unchanged, and proxy.py
is asserted not to reference X-Vault-Token, approle login, or token create — a
conduit that presents its own token is not a conduit.
No assertion on review dates, deliberately: a date-triggered failure breaks the
build on a calendar day with no code change, the same reasoning WP-0033-T05
recorded for blocker staleness.
398 tests pass, ruff clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YWBMovyFoy9RRrfL7zKvPJ
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 4014535@bnt-lap001
Assistant-Session: d0036016-73e8-4da1-8e47-563e3ab39a3c
2026-08-29 02:45:29 +02:00
|
|
|
# A direct Tooling contact is an *invocation*, not a mention. Matching the word
|
|
|
|
|
# "bao" caught help text, a docstring, and the dev-tier doubles library that
|
|
|
|
|
# simulates bao rather than calling it — three false positives on first run.
|
|
|
|
|
# So match the two shapes that actually execute:
|
|
|
|
|
# 1. an HTTP request built against the OpenBao address
|
|
|
|
|
# 2. an argv list whose first element is the bao binary
|
|
|
|
|
TOOLING_PATTERNS = (
|
|
|
|
|
# httpx call whose URL is built from the configured OpenBao/Vault address
|
|
|
|
|
re.compile(r"""\bhttpx\.\w+\(|url\s*=\s*f?["'].*\{self\._cfg\.addr\}"""),
|
|
|
|
|
# argv construction: [bao_bin, ...] / ["bao", ...] / [bao_binary, ...]
|
|
|
|
|
re.compile(r"""\[\s*(?:["']bao["']|bao_bin\b|bao_binary\b)\s*,"""),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# httpx alone is not a Tooling contact — policy.py calls an Engine and worker.py
|
|
|
|
|
# calls the State Hub. A module matching only the httpx pattern counts as a
|
|
|
|
|
# contact only if it also references the OpenBao address configuration.
|
|
|
|
|
ADDR_HINT = re.compile(r"""_cfg\.addr|VAULT_ADDR|BAO_ADDR""")
|
|
|
|
|
|
|
|
|
|
# Modules that talk to an Engine or to something outside the §4 catalog. Listed
|
|
|
|
|
# in layer.yaml under non_tooling_clients and excluded from the scan with it.
|
|
|
|
|
def _excluded(decl: dict) -> set[str]:
|
|
|
|
|
return {e["module"].split("/")[-1] for e in decl.get("non_tooling_clients", [])}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def load_declaration() -> dict:
|
|
|
|
|
if not DECL.exists():
|
|
|
|
|
print(f"MISSING: {DECL} — ops-warden must declare in its own voice (§11)")
|
|
|
|
|
raise SystemExit(2)
|
|
|
|
|
decl = yaml.safe_load(DECL.read_text())
|
Apply GH-DEC-2026-017: INTENT.md governs, the sidecar is derived, no version
Verified against gate-house's own committed files before editing, not the inbox
message: GH-DEC-2026-017 in decisions/decisions.md at gate-house@def0af2,
amendments A9-A13 in docs/amendments/v0.8-section-11-declaration-amendments.md,
and sections 3, 4 and 11 of net-kingdom's security-layer-model_v0.8.md. The
ruling and docs/layer-declaration-precedence.md's secondary account agreed.
INTENT.md's frontmatter is the declaration; layer.yaml is a derived artifact,
now marked derived: true / derived_from: INTENT.md, and it does not govern.
standard_version is removed from BOTH forms. The ruling's general form is that a
layer declaration must not carry a standard version, and INTENT.md is the
declaration, so removing it from the sidecar alone would have left the field in
the only file that actually declares. INTENT.md's version-pinned `standard:`
path is de-versioned for the same reason: a pinned path reads as a validity
condition. The version ops-warden assented at stays with the assent, ADR-0010.
NO LAYER VALUE IS CHANGED. INTENT.md still says Staff and layer.yaml still says
staff. Section 3's vocabulary is closed, four tokens, and case-insensitive: the
two forms were never in disagreement about a layer, and the ruling asked nobody
to re-spell anything. The comment marking the divergence is rewritten from
"unruled, do not touch" to "ruled, folding case is the checker's job".
check_layer_conformance.py would have rejected the conforming declaration this
ruling produces -- it listed standard_version as a required key. It now reads
INTENT.md as the governing form, ASCII-folds before comparing, validates both
values against the closed four-token vocabulary (Taxonomy included; omitting it
is the defect A9 records against the estate's other validator), requires the
derived marking, rejects a returning standard_version in either file, and
reports a post-fold disagreement between the forms as a finding rather than
resolving it away by precedence.
The test asserts the fold, not equality. An equality assertion here would be
this repository quietly performing the re-spelling the ruling declined to order;
the fold still fails on a real layer divergence.
pep-stance.yaml is untouched. A stance map is not a layer declaration, and the
sidecar schema beyond the derived marking and the version is explicitly not
ruled.
layer.yaml is the form seven repositories copied, so the adopter change set is
written out in wiki/playbooks/netkingdom-layer-declaration.md -- including the
trap that an adopter which also copied the checker turns a conforming
declaration into MALFORMED exit 2 by removing the field alone. No other
repository is edited here.
Still open: where the removed version lives. A12 says the derived conformance
record "already MUST" carry it; ops-warden has a re-runnable checker that emits
nothing durable. Asked of gate-house in message 4220413a, unanswered, and left
open rather than answered by choosing. Nothing above depends on it.
Carries WARDEN-WP-0034-T06 to done.
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 02:38:55 +02:00
|
|
|
for key in ("layer", "repository", "derived", "derived_from", "tooling_contacts"):
|
Implement §5.3 machine-readably — layer.yaml, checker, conformance tests
The security layer model moved v0.1 -> v0.4 (accepted) after ops-warden's
assent. Both §5 asks from ADR-0010 were adopted: §5.2 now sanctions the conduit
shape on the supplied-authority property, and §5.3 is the declared engine gap
amendment, carrying the four fields verbatim and crediting ops-warden's
delegation machinery as prior art.
Which creates an obligation. §5.3 requires those fields MACHINE-READABLY, and
§11 makes "every direct Tooling client maps to a declared §5.1/§5.2/§5.3 entry"
a mechanical check. ops-warden's declaration was prose in INTENT.md — the repo
that proposed the shape was not implementing it.
layer.yaml is the map: 5 contacts (2 declared gaps, 1 read-only observation,
2 conduits) plus the non-Tooling clients recorded explicitly so the check is
total rather than silently selective.
scripts/check_layer_conformance.py enforces it and found three undeclared
modules on its first run — all false positives (help text, a docstring, and the
doubles library that SIMULATES bao rather than calling it), which is why the
scan now matches invocation shapes instead of the word: an httpx call built
against the configured OpenBao address, or an argv whose first element is the
bao binary.
tests/test_layer_conformance.py adds the §5.2 test the standard says SHOULD
exist: _caller_env() returns the caller's environment unchanged, and proxy.py
is asserted not to reference X-Vault-Token, approle login, or token create — a
conduit that presents its own token is not a conduit.
No assertion on review dates, deliberately: a date-triggered failure breaks the
build on a calendar day with no code change, the same reasoning WP-0033-T05
recorded for blocker staleness.
398 tests pass, ruff clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YWBMovyFoy9RRrfL7zKvPJ
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 4014535@bnt-lap001
Assistant-Session: d0036016-73e8-4da1-8e47-563e3ab39a3c
2026-08-29 02:45:29 +02:00
|
|
|
if key not in decl:
|
|
|
|
|
print(f"MALFORMED: layer.yaml has no {key!r}")
|
|
|
|
|
raise SystemExit(2)
|
Apply GH-DEC-2026-017: INTENT.md governs, the sidecar is derived, no version
Verified against gate-house's own committed files before editing, not the inbox
message: GH-DEC-2026-017 in decisions/decisions.md at gate-house@def0af2,
amendments A9-A13 in docs/amendments/v0.8-section-11-declaration-amendments.md,
and sections 3, 4 and 11 of net-kingdom's security-layer-model_v0.8.md. The
ruling and docs/layer-declaration-precedence.md's secondary account agreed.
INTENT.md's frontmatter is the declaration; layer.yaml is a derived artifact,
now marked derived: true / derived_from: INTENT.md, and it does not govern.
standard_version is removed from BOTH forms. The ruling's general form is that a
layer declaration must not carry a standard version, and INTENT.md is the
declaration, so removing it from the sidecar alone would have left the field in
the only file that actually declares. INTENT.md's version-pinned `standard:`
path is de-versioned for the same reason: a pinned path reads as a validity
condition. The version ops-warden assented at stays with the assent, ADR-0010.
NO LAYER VALUE IS CHANGED. INTENT.md still says Staff and layer.yaml still says
staff. Section 3's vocabulary is closed, four tokens, and case-insensitive: the
two forms were never in disagreement about a layer, and the ruling asked nobody
to re-spell anything. The comment marking the divergence is rewritten from
"unruled, do not touch" to "ruled, folding case is the checker's job".
check_layer_conformance.py would have rejected the conforming declaration this
ruling produces -- it listed standard_version as a required key. It now reads
INTENT.md as the governing form, ASCII-folds before comparing, validates both
values against the closed four-token vocabulary (Taxonomy included; omitting it
is the defect A9 records against the estate's other validator), requires the
derived marking, rejects a returning standard_version in either file, and
reports a post-fold disagreement between the forms as a finding rather than
resolving it away by precedence.
The test asserts the fold, not equality. An equality assertion here would be
this repository quietly performing the re-spelling the ruling declined to order;
the fold still fails on a real layer divergence.
pep-stance.yaml is untouched. A stance map is not a layer declaration, and the
sidecar schema beyond the derived marking and the version is explicitly not
ruled.
layer.yaml is the form seven repositories copied, so the adopter change set is
written out in wiki/playbooks/netkingdom-layer-declaration.md -- including the
trap that an adopter which also copied the checker turns a conforming
declaration into MALFORMED exit 2 by removing the field alone. No other
repository is edited here.
Still open: where the removed version lives. A12 says the derived conformance
record "already MUST" carry it; ops-warden has a re-runnable checker that emits
nothing durable. Asked of gate-house in message 4220413a, unanswered, and left
open rather than answered by choosing. Nothing above depends on it.
Carries WARDEN-WP-0034-T06 to done.
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 02:38:55 +02:00
|
|
|
# §11's derived-artifact rule: marked as derived, naming what it derives from.
|
|
|
|
|
if decl["derived"] is not True:
|
|
|
|
|
print("MALFORMED: layer.yaml must be marked 'derived: true' (§11, GH-DEC-2026-017 §1)")
|
|
|
|
|
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)
|
|
|
|
|
# A12: the version has no home in a declaration, governing or derived.
|
2026-09-21 09:38:17 +02:00
|
|
|
_reject_version_pins("layer.yaml", decl)
|
Apply GH-DEC-2026-017: INTENT.md governs, the sidecar is derived, no version
Verified against gate-house's own committed files before editing, not the inbox
message: GH-DEC-2026-017 in decisions/decisions.md at gate-house@def0af2,
amendments A9-A13 in docs/amendments/v0.8-section-11-declaration-amendments.md,
and sections 3, 4 and 11 of net-kingdom's security-layer-model_v0.8.md. The
ruling and docs/layer-declaration-precedence.md's secondary account agreed.
INTENT.md's frontmatter is the declaration; layer.yaml is a derived artifact,
now marked derived: true / derived_from: INTENT.md, and it does not govern.
standard_version is removed from BOTH forms. The ruling's general form is that a
layer declaration must not carry a standard version, and INTENT.md is the
declaration, so removing it from the sidecar alone would have left the field in
the only file that actually declares. INTENT.md's version-pinned `standard:`
path is de-versioned for the same reason: a pinned path reads as a validity
condition. The version ops-warden assented at stays with the assent, ADR-0010.
NO LAYER VALUE IS CHANGED. INTENT.md still says Staff and layer.yaml still says
staff. Section 3's vocabulary is closed, four tokens, and case-insensitive: the
two forms were never in disagreement about a layer, and the ruling asked nobody
to re-spell anything. The comment marking the divergence is rewritten from
"unruled, do not touch" to "ruled, folding case is the checker's job".
check_layer_conformance.py would have rejected the conforming declaration this
ruling produces -- it listed standard_version as a required key. It now reads
INTENT.md as the governing form, ASCII-folds before comparing, validates both
values against the closed four-token vocabulary (Taxonomy included; omitting it
is the defect A9 records against the estate's other validator), requires the
derived marking, rejects a returning standard_version in either file, and
reports a post-fold disagreement between the forms as a finding rather than
resolving it away by precedence.
The test asserts the fold, not equality. An equality assertion here would be
this repository quietly performing the re-spelling the ruling declined to order;
the fold still fails on a real layer divergence.
pep-stance.yaml is untouched. A stance map is not a layer declaration, and the
sidecar schema beyond the derived marking and the version is explicitly not
ruled.
layer.yaml is the form seven repositories copied, so the adopter change set is
written out in wiki/playbooks/netkingdom-layer-declaration.md -- including the
trap that an adopter which also copied the checker turns a conforming
declaration into MALFORMED exit 2 by removing the field alone. No other
repository is edited here.
Still open: where the removed version lives. A12 says the derived conformance
record "already MUST" carry it; ops-warden has a re-runnable checker that emits
nothing durable. Asked of gate-house in message 4220413a, unanswered, and left
open rather than answered by choosing. Nothing above depends on it.
Carries WARDEN-WP-0034-T06 to done.
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 02:38:55 +02:00
|
|
|
if _fold(decl["layer"]) not in LAYER_VOCABULARY:
|
|
|
|
|
print(
|
|
|
|
|
f"MALFORMED: layer.yaml declares layer {decl['layer']!r}, outside §3's "
|
|
|
|
|
f"closed vocabulary {sorted(LAYER_VOCABULARY)} (case-insensitive)"
|
|
|
|
|
)
|
|
|
|
|
raise SystemExit(2)
|
Implement §5.3 machine-readably — layer.yaml, checker, conformance tests
The security layer model moved v0.1 -> v0.4 (accepted) after ops-warden's
assent. Both §5 asks from ADR-0010 were adopted: §5.2 now sanctions the conduit
shape on the supplied-authority property, and §5.3 is the declared engine gap
amendment, carrying the four fields verbatim and crediting ops-warden's
delegation machinery as prior art.
Which creates an obligation. §5.3 requires those fields MACHINE-READABLY, and
§11 makes "every direct Tooling client maps to a declared §5.1/§5.2/§5.3 entry"
a mechanical check. ops-warden's declaration was prose in INTENT.md — the repo
that proposed the shape was not implementing it.
layer.yaml is the map: 5 contacts (2 declared gaps, 1 read-only observation,
2 conduits) plus the non-Tooling clients recorded explicitly so the check is
total rather than silently selective.
scripts/check_layer_conformance.py enforces it and found three undeclared
modules on its first run — all false positives (help text, a docstring, and the
doubles library that SIMULATES bao rather than calling it), which is why the
scan now matches invocation shapes instead of the word: an httpx call built
against the configured OpenBao address, or an argv whose first element is the
bao binary.
tests/test_layer_conformance.py adds the §5.2 test the standard says SHOULD
exist: _caller_env() returns the caller's environment unchanged, and proxy.py
is asserted not to reference X-Vault-Token, approle login, or token create — a
conduit that presents its own token is not a conduit.
No assertion on review dates, deliberately: a date-triggered failure breaks the
build on a calendar day with no code change, the same reasoning WP-0033-T05
recorded for blocker staleness.
398 tests pass, ruff clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YWBMovyFoy9RRrfL7zKvPJ
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 4014535@bnt-lap001
Assistant-Session: d0036016-73e8-4da1-8e47-563e3ab39a3c
2026-08-29 02:45:29 +02:00
|
|
|
for c in decl["tooling_contacts"]:
|
|
|
|
|
if c.get("shape") not in VALID_SHAPES:
|
|
|
|
|
print(f"MALFORMED: {c.get('id')} has shape {c.get('shape')!r}, not one of {sorted(VALID_SHAPES)}")
|
|
|
|
|
raise SystemExit(2)
|
|
|
|
|
# §5.3 carries four fields, machine-readably. That is the whole point of
|
|
|
|
|
# the shape; a gap missing them is prose wearing a schema.
|
|
|
|
|
if c["shape"] == "5.3":
|
|
|
|
|
for field in ("capability", "intended_owner", "blocked_on", "review"):
|
|
|
|
|
if not c.get(field):
|
|
|
|
|
print(f"MALFORMED: §5.3 entry {c['id']!r} is missing {field!r}")
|
|
|
|
|
raise SystemExit(2)
|
|
|
|
|
# §5.2's test is the supplied-authority property.
|
|
|
|
|
if c["shape"] == "5.2" and c.get("supplied_authority") != "none":
|
|
|
|
|
print(f"MALFORMED: §5.2 conduit {c['id']!r} must declare supplied_authority: none")
|
|
|
|
|
raise SystemExit(2)
|
|
|
|
|
return decl
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def scan_modules() -> dict[str, list[int]]:
|
|
|
|
|
"""Return {module_name: [line numbers]} for direct Tooling contacts."""
|
|
|
|
|
found: dict[str, list[int]] = {}
|
|
|
|
|
for path in sorted(SRC.rglob("*.py")):
|
|
|
|
|
if path.name.startswith("test_"):
|
|
|
|
|
continue
|
|
|
|
|
text = path.read_text()
|
|
|
|
|
hits: list[int] = []
|
|
|
|
|
for n, line in enumerate(text.splitlines(), 1):
|
|
|
|
|
stripped = line.strip()
|
|
|
|
|
if stripped.startswith("#") or stripped.startswith('"'):
|
|
|
|
|
continue
|
|
|
|
|
if any(p.search(line) for p in TOOLING_PATTERNS):
|
|
|
|
|
hits.append(n)
|
|
|
|
|
if hits:
|
|
|
|
|
# An httpx-only match needs the OpenBao address to be a Tooling
|
|
|
|
|
# contact; otherwise it is an Engine or non-catalogued call.
|
|
|
|
|
argv_shape = any(TOOLING_PATTERNS[1].search(ln) for ln in text.splitlines())
|
|
|
|
|
if argv_shape or ADDR_HINT.search(text):
|
|
|
|
|
found[path.name] = hits
|
|
|
|
|
return found
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def main() -> int:
|
|
|
|
|
ap = argparse.ArgumentParser()
|
|
|
|
|
ap.add_argument("--report", action="store_true", help="also print the declaration and gap review dates")
|
|
|
|
|
args = ap.parse_args()
|
|
|
|
|
|
2026-09-21 09:38:17 +02:00
|
|
|
# Printed before anything can fail, so even a MALFORMED run states what it
|
|
|
|
|
# checked against and over what (GH-DEC-2026-020 §4).
|
|
|
|
|
print(f"validated against: {VALIDATED_AGAINST}")
|
|
|
|
|
print(f"scope: {SCOPE}")
|
Apply GH-DEC-2026-017: INTENT.md governs, the sidecar is derived, no version
Verified against gate-house's own committed files before editing, not the inbox
message: GH-DEC-2026-017 in decisions/decisions.md at gate-house@def0af2,
amendments A9-A13 in docs/amendments/v0.8-section-11-declaration-amendments.md,
and sections 3, 4 and 11 of net-kingdom's security-layer-model_v0.8.md. The
ruling and docs/layer-declaration-precedence.md's secondary account agreed.
INTENT.md's frontmatter is the declaration; layer.yaml is a derived artifact,
now marked derived: true / derived_from: INTENT.md, and it does not govern.
standard_version is removed from BOTH forms. The ruling's general form is that a
layer declaration must not carry a standard version, and INTENT.md is the
declaration, so removing it from the sidecar alone would have left the field in
the only file that actually declares. INTENT.md's version-pinned `standard:`
path is de-versioned for the same reason: a pinned path reads as a validity
condition. The version ops-warden assented at stays with the assent, ADR-0010.
NO LAYER VALUE IS CHANGED. INTENT.md still says Staff and layer.yaml still says
staff. Section 3's vocabulary is closed, four tokens, and case-insensitive: the
two forms were never in disagreement about a layer, and the ruling asked nobody
to re-spell anything. The comment marking the divergence is rewritten from
"unruled, do not touch" to "ruled, folding case is the checker's job".
check_layer_conformance.py would have rejected the conforming declaration this
ruling produces -- it listed standard_version as a required key. It now reads
INTENT.md as the governing form, ASCII-folds before comparing, validates both
values against the closed four-token vocabulary (Taxonomy included; omitting it
is the defect A9 records against the estate's other validator), requires the
derived marking, rejects a returning standard_version in either file, and
reports a post-fold disagreement between the forms as a finding rather than
resolving it away by precedence.
The test asserts the fold, not equality. An equality assertion here would be
this repository quietly performing the re-spelling the ruling declined to order;
the fold still fails on a real layer divergence.
pep-stance.yaml is untouched. A stance map is not a layer declaration, and the
sidecar schema beyond the derived marking and the version is explicitly not
ruled.
layer.yaml is the form seven repositories copied, so the adopter change set is
written out in wiki/playbooks/netkingdom-layer-declaration.md -- including the
trap that an adopter which also copied the checker turns a conforming
declaration into MALFORMED exit 2 by removing the field alone. No other
repository is edited here.
Still open: where the removed version lives. A12 says the derived conformance
record "already MUST" carry it; ops-warden has a re-runnable checker that emits
nothing durable. Asked of gate-house in message 4220413a, unanswered, and left
open rather than answered by choosing. Nothing above depends on it.
Carries WARDEN-WP-0034-T06 to done.
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 02:38:55 +02:00
|
|
|
governing = load_governing_layer()
|
Implement §5.3 machine-readably — layer.yaml, checker, conformance tests
The security layer model moved v0.1 -> v0.4 (accepted) after ops-warden's
assent. Both §5 asks from ADR-0010 were adopted: §5.2 now sanctions the conduit
shape on the supplied-authority property, and §5.3 is the declared engine gap
amendment, carrying the four fields verbatim and crediting ops-warden's
delegation machinery as prior art.
Which creates an obligation. §5.3 requires those fields MACHINE-READABLY, and
§11 makes "every direct Tooling client maps to a declared §5.1/§5.2/§5.3 entry"
a mechanical check. ops-warden's declaration was prose in INTENT.md — the repo
that proposed the shape was not implementing it.
layer.yaml is the map: 5 contacts (2 declared gaps, 1 read-only observation,
2 conduits) plus the non-Tooling clients recorded explicitly so the check is
total rather than silently selective.
scripts/check_layer_conformance.py enforces it and found three undeclared
modules on its first run — all false positives (help text, a docstring, and the
doubles library that SIMULATES bao rather than calling it), which is why the
scan now matches invocation shapes instead of the word: an httpx call built
against the configured OpenBao address, or an argv whose first element is the
bao binary.
tests/test_layer_conformance.py adds the §5.2 test the standard says SHOULD
exist: _caller_env() returns the caller's environment unchanged, and proxy.py
is asserted not to reference X-Vault-Token, approle login, or token create — a
conduit that presents its own token is not a conduit.
No assertion on review dates, deliberately: a date-triggered failure breaks the
build on a calendar day with no code change, the same reasoning WP-0033-T05
recorded for blocker staleness.
398 tests pass, ruff clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YWBMovyFoy9RRrfL7zKvPJ
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 4014535@bnt-lap001
Assistant-Session: d0036016-73e8-4da1-8e47-563e3ab39a3c
2026-08-29 02:45:29 +02:00
|
|
|
decl = load_declaration()
|
|
|
|
|
declared = {c["module"].split("/")[-1] for c in decl["tooling_contacts"]}
|
|
|
|
|
excluded = _excluded(decl)
|
|
|
|
|
found = scan_modules()
|
|
|
|
|
|
|
|
|
|
undeclared = {m: lines for m, lines in found.items() if m not in declared and m not in excluded}
|
|
|
|
|
# A voluntary declaration has no fixed argv shape to detect (an
|
|
|
|
|
# operator-configured command). Over-declaring is safe; not reporting it as
|
|
|
|
|
# stale keeps the signal meaningful.
|
|
|
|
|
voluntary = {
|
|
|
|
|
c["module"].split("/")[-1]
|
|
|
|
|
for c in decl["tooling_contacts"]
|
|
|
|
|
if c.get("detection") == "voluntary"
|
|
|
|
|
}
|
|
|
|
|
stale_decls = declared - set(found) - voluntary
|
|
|
|
|
|
|
|
|
|
if args.report:
|
Apply GH-DEC-2026-017: INTENT.md governs, the sidecar is derived, no version
Verified against gate-house's own committed files before editing, not the inbox
message: GH-DEC-2026-017 in decisions/decisions.md at gate-house@def0af2,
amendments A9-A13 in docs/amendments/v0.8-section-11-declaration-amendments.md,
and sections 3, 4 and 11 of net-kingdom's security-layer-model_v0.8.md. The
ruling and docs/layer-declaration-precedence.md's secondary account agreed.
INTENT.md's frontmatter is the declaration; layer.yaml is a derived artifact,
now marked derived: true / derived_from: INTENT.md, and it does not govern.
standard_version is removed from BOTH forms. The ruling's general form is that a
layer declaration must not carry a standard version, and INTENT.md is the
declaration, so removing it from the sidecar alone would have left the field in
the only file that actually declares. INTENT.md's version-pinned `standard:`
path is de-versioned for the same reason: a pinned path reads as a validity
condition. The version ops-warden assented at stays with the assent, ADR-0010.
NO LAYER VALUE IS CHANGED. INTENT.md still says Staff and layer.yaml still says
staff. Section 3's vocabulary is closed, four tokens, and case-insensitive: the
two forms were never in disagreement about a layer, and the ruling asked nobody
to re-spell anything. The comment marking the divergence is rewritten from
"unruled, do not touch" to "ruled, folding case is the checker's job".
check_layer_conformance.py would have rejected the conforming declaration this
ruling produces -- it listed standard_version as a required key. It now reads
INTENT.md as the governing form, ASCII-folds before comparing, validates both
values against the closed four-token vocabulary (Taxonomy included; omitting it
is the defect A9 records against the estate's other validator), requires the
derived marking, rejects a returning standard_version in either file, and
reports a post-fold disagreement between the forms as a finding rather than
resolving it away by precedence.
The test asserts the fold, not equality. An equality assertion here would be
this repository quietly performing the re-spelling the ruling declined to order;
the fold still fails on a real layer divergence.
pep-stance.yaml is untouched. A stance map is not a layer declaration, and the
sidecar schema beyond the derived marking and the version is explicitly not
ruled.
layer.yaml is the form seven repositories copied, so the adopter change set is
written out in wiki/playbooks/netkingdom-layer-declaration.md -- including the
trap that an adopter which also copied the checker turns a conforming
declaration into MALFORMED exit 2 by removing the field alone. No other
repository is edited here.
Still open: where the removed version lives. A12 says the derived conformance
record "already MUST" carry it; ops-warden has a re-runnable checker that emits
nothing durable. Asked of gate-house in message 4220413a, unanswered, and left
open rather than answered by choosing. Nothing above depends on it.
Carries WARDEN-WP-0034-T06 to done.
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 02:38:55 +02:00
|
|
|
print(f"{decl['repository']} — layer: {governing} (declared in INTENT.md; §11 governing form)")
|
|
|
|
|
print(f" layer.yaml: derived from {decl['derived_from']}, layer: {decl['layer']}")
|
Implement §5.3 machine-readably — layer.yaml, checker, conformance tests
The security layer model moved v0.1 -> v0.4 (accepted) after ops-warden's
assent. Both §5 asks from ADR-0010 were adopted: §5.2 now sanctions the conduit
shape on the supplied-authority property, and §5.3 is the declared engine gap
amendment, carrying the four fields verbatim and crediting ops-warden's
delegation machinery as prior art.
Which creates an obligation. §5.3 requires those fields MACHINE-READABLY, and
§11 makes "every direct Tooling client maps to a declared §5.1/§5.2/§5.3 entry"
a mechanical check. ops-warden's declaration was prose in INTENT.md — the repo
that proposed the shape was not implementing it.
layer.yaml is the map: 5 contacts (2 declared gaps, 1 read-only observation,
2 conduits) plus the non-Tooling clients recorded explicitly so the check is
total rather than silently selective.
scripts/check_layer_conformance.py enforces it and found three undeclared
modules on its first run — all false positives (help text, a docstring, and the
doubles library that SIMULATES bao rather than calling it), which is why the
scan now matches invocation shapes instead of the word: an httpx call built
against the configured OpenBao address, or an argv whose first element is the
bao binary.
tests/test_layer_conformance.py adds the §5.2 test the standard says SHOULD
exist: _caller_env() returns the caller's environment unchanged, and proxy.py
is asserted not to reference X-Vault-Token, approle login, or token create — a
conduit that presents its own token is not a conduit.
No assertion on review dates, deliberately: a date-triggered failure breaks the
build on a calendar day with no code change, the same reasoning WP-0033-T05
recorded for blocker staleness.
398 tests pass, ruff clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YWBMovyFoy9RRrfL7zKvPJ
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 4014535@bnt-lap001
Assistant-Session: d0036016-73e8-4da1-8e47-563e3ab39a3c
2026-08-29 02:45:29 +02:00
|
|
|
print(f"declared by {decl['declared_by']}\n")
|
|
|
|
|
for c in decl["tooling_contacts"]:
|
|
|
|
|
line = f" §{c['shape']} {c['id']:<28} {c['module']}"
|
|
|
|
|
if c["shape"] == "5.3":
|
|
|
|
|
overdue = str(c["review"]) < date.today().isoformat()
|
|
|
|
|
line += f" -> {c['intended_owner']} review {c['review']}"
|
|
|
|
|
if overdue:
|
|
|
|
|
line += " [REVIEW OVERDUE]"
|
|
|
|
|
print(line)
|
|
|
|
|
gaps = [c for c in decl["tooling_contacts"] if c["shape"] == "5.3"]
|
|
|
|
|
print(f"\n{len(gaps)} declared gap(s) — tracked non-conformance, not conformance (§11).")
|
|
|
|
|
|
|
|
|
|
ok = True
|
Apply GH-DEC-2026-017: INTENT.md governs, the sidecar is derived, no version
Verified against gate-house's own committed files before editing, not the inbox
message: GH-DEC-2026-017 in decisions/decisions.md at gate-house@def0af2,
amendments A9-A13 in docs/amendments/v0.8-section-11-declaration-amendments.md,
and sections 3, 4 and 11 of net-kingdom's security-layer-model_v0.8.md. The
ruling and docs/layer-declaration-precedence.md's secondary account agreed.
INTENT.md's frontmatter is the declaration; layer.yaml is a derived artifact,
now marked derived: true / derived_from: INTENT.md, and it does not govern.
standard_version is removed from BOTH forms. The ruling's general form is that a
layer declaration must not carry a standard version, and INTENT.md is the
declaration, so removing it from the sidecar alone would have left the field in
the only file that actually declares. INTENT.md's version-pinned `standard:`
path is de-versioned for the same reason: a pinned path reads as a validity
condition. The version ops-warden assented at stays with the assent, ADR-0010.
NO LAYER VALUE IS CHANGED. INTENT.md still says Staff and layer.yaml still says
staff. Section 3's vocabulary is closed, four tokens, and case-insensitive: the
two forms were never in disagreement about a layer, and the ruling asked nobody
to re-spell anything. The comment marking the divergence is rewritten from
"unruled, do not touch" to "ruled, folding case is the checker's job".
check_layer_conformance.py would have rejected the conforming declaration this
ruling produces -- it listed standard_version as a required key. It now reads
INTENT.md as the governing form, ASCII-folds before comparing, validates both
values against the closed four-token vocabulary (Taxonomy included; omitting it
is the defect A9 records against the estate's other validator), requires the
derived marking, rejects a returning standard_version in either file, and
reports a post-fold disagreement between the forms as a finding rather than
resolving it away by precedence.
The test asserts the fold, not equality. An equality assertion here would be
this repository quietly performing the re-spelling the ruling declined to order;
the fold still fails on a real layer divergence.
pep-stance.yaml is untouched. A stance map is not a layer declaration, and the
sidecar schema beyond the derived marking and the version is explicitly not
ruled.
layer.yaml is the form seven repositories copied, so the adopter change set is
written out in wiki/playbooks/netkingdom-layer-declaration.md -- including the
trap that an adopter which also copied the checker turns a conforming
declaration into MALFORMED exit 2 by removing the field alone. No other
repository is edited here.
Still open: where the removed version lives. A12 says the derived conformance
record "already MUST" carry it; ops-warden has a re-runnable checker that emits
nothing durable. Asked of gate-house in message 4220413a, unanswered, and left
open rather than answered by choosing. Nothing above depends on it.
Carries WARDEN-WP-0034-T06 to done.
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 02:38:55 +02:00
|
|
|
|
|
|
|
|
# §11 as amended (A11): the derived form MUST agree with the governing one,
|
|
|
|
|
# and a disagreement is a finding in its own right — reported, not resolved
|
|
|
|
|
# away by precedence. Comparison folds case (A9): `Staff` and `staff` agree.
|
|
|
|
|
if _fold(decl["layer"]) != _fold(governing):
|
|
|
|
|
ok = False
|
|
|
|
|
print(
|
|
|
|
|
"\nDECLARATION DISAGREEMENT — a finding under §11, not a precedence question:\n"
|
|
|
|
|
f" INTENT.md (governs): layer: {governing}\n"
|
|
|
|
|
f" layer.yaml (derived): layer: {decl['layer']}\n"
|
|
|
|
|
"Precedence says which value is ops-warden's answer. It does not say the\n"
|
|
|
|
|
"disagreement did not happen. Case is already folded, so this is a real\n"
|
|
|
|
|
"disagreement about a layer, not about orthography."
|
|
|
|
|
)
|
|
|
|
|
|
Implement §5.3 machine-readably — layer.yaml, checker, conformance tests
The security layer model moved v0.1 -> v0.4 (accepted) after ops-warden's
assent. Both §5 asks from ADR-0010 were adopted: §5.2 now sanctions the conduit
shape on the supplied-authority property, and §5.3 is the declared engine gap
amendment, carrying the four fields verbatim and crediting ops-warden's
delegation machinery as prior art.
Which creates an obligation. §5.3 requires those fields MACHINE-READABLY, and
§11 makes "every direct Tooling client maps to a declared §5.1/§5.2/§5.3 entry"
a mechanical check. ops-warden's declaration was prose in INTENT.md — the repo
that proposed the shape was not implementing it.
layer.yaml is the map: 5 contacts (2 declared gaps, 1 read-only observation,
2 conduits) plus the non-Tooling clients recorded explicitly so the check is
total rather than silently selective.
scripts/check_layer_conformance.py enforces it and found three undeclared
modules on its first run — all false positives (help text, a docstring, and the
doubles library that SIMULATES bao rather than calling it), which is why the
scan now matches invocation shapes instead of the word: an httpx call built
against the configured OpenBao address, or an argv whose first element is the
bao binary.
tests/test_layer_conformance.py adds the §5.2 test the standard says SHOULD
exist: _caller_env() returns the caller's environment unchanged, and proxy.py
is asserted not to reference X-Vault-Token, approle login, or token create — a
conduit that presents its own token is not a conduit.
No assertion on review dates, deliberately: a date-triggered failure breaks the
build on a calendar day with no code change, the same reasoning WP-0033-T05
recorded for blocker staleness.
398 tests pass, ruff clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YWBMovyFoy9RRrfL7zKvPJ
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 4014535@bnt-lap001
Assistant-Session: d0036016-73e8-4da1-8e47-563e3ab39a3c
2026-08-29 02:45:29 +02:00
|
|
|
if undeclared:
|
|
|
|
|
ok = False
|
|
|
|
|
print("\nUNDECLARED TOOLING CONTACT — a finding under §11, not a tracked gap:")
|
|
|
|
|
for m, lines in sorted(undeclared.items()):
|
|
|
|
|
print(f" src/warden/{m}: line(s) {', '.join(map(str, lines[:6]))}")
|
|
|
|
|
print("\nAdd a §5.1/§5.2/§5.3 entry to layer.yaml, or route it through an engine.")
|
|
|
|
|
|
|
|
|
|
if stale_decls:
|
|
|
|
|
print("\nNote: declared but no contact found (module removed or refactored?):")
|
|
|
|
|
for m in sorted(stale_decls):
|
|
|
|
|
print(f" {m}")
|
|
|
|
|
|
|
|
|
|
if ok and not args.report:
|
2026-09-21 09:38:17 +02:00
|
|
|
print(
|
|
|
|
|
f"PASS — {len(found)} module(s) with Tooling contact, all declared; "
|
|
|
|
|
f"validated against {VALIDATED_AGAINST}"
|
|
|
|
|
)
|
Implement §5.3 machine-readably — layer.yaml, checker, conformance tests
The security layer model moved v0.1 -> v0.4 (accepted) after ops-warden's
assent. Both §5 asks from ADR-0010 were adopted: §5.2 now sanctions the conduit
shape on the supplied-authority property, and §5.3 is the declared engine gap
amendment, carrying the four fields verbatim and crediting ops-warden's
delegation machinery as prior art.
Which creates an obligation. §5.3 requires those fields MACHINE-READABLY, and
§11 makes "every direct Tooling client maps to a declared §5.1/§5.2/§5.3 entry"
a mechanical check. ops-warden's declaration was prose in INTENT.md — the repo
that proposed the shape was not implementing it.
layer.yaml is the map: 5 contacts (2 declared gaps, 1 read-only observation,
2 conduits) plus the non-Tooling clients recorded explicitly so the check is
total rather than silently selective.
scripts/check_layer_conformance.py enforces it and found three undeclared
modules on its first run — all false positives (help text, a docstring, and the
doubles library that SIMULATES bao rather than calling it), which is why the
scan now matches invocation shapes instead of the word: an httpx call built
against the configured OpenBao address, or an argv whose first element is the
bao binary.
tests/test_layer_conformance.py adds the §5.2 test the standard says SHOULD
exist: _caller_env() returns the caller's environment unchanged, and proxy.py
is asserted not to reference X-Vault-Token, approle login, or token create — a
conduit that presents its own token is not a conduit.
No assertion on review dates, deliberately: a date-triggered failure breaks the
build on a calendar day with no code change, the same reasoning WP-0033-T05
recorded for blocker staleness.
398 tests pass, ruff clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YWBMovyFoy9RRrfL7zKvPJ
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 4014535@bnt-lap001
Assistant-Session: d0036016-73e8-4da1-8e47-563e3ab39a3c
2026-08-29 02:45:29 +02:00
|
|
|
elif ok:
|
2026-09-21 09:38:17 +02:00
|
|
|
print(
|
|
|
|
|
"\nPASS — every direct Tooling contact maps to a declared shape; "
|
|
|
|
|
f"validated against {VALIDATED_AGAINST}"
|
|
|
|
|
)
|
Implement §5.3 machine-readably — layer.yaml, checker, conformance tests
The security layer model moved v0.1 -> v0.4 (accepted) after ops-warden's
assent. Both §5 asks from ADR-0010 were adopted: §5.2 now sanctions the conduit
shape on the supplied-authority property, and §5.3 is the declared engine gap
amendment, carrying the four fields verbatim and crediting ops-warden's
delegation machinery as prior art.
Which creates an obligation. §5.3 requires those fields MACHINE-READABLY, and
§11 makes "every direct Tooling client maps to a declared §5.1/§5.2/§5.3 entry"
a mechanical check. ops-warden's declaration was prose in INTENT.md — the repo
that proposed the shape was not implementing it.
layer.yaml is the map: 5 contacts (2 declared gaps, 1 read-only observation,
2 conduits) plus the non-Tooling clients recorded explicitly so the check is
total rather than silently selective.
scripts/check_layer_conformance.py enforces it and found three undeclared
modules on its first run — all false positives (help text, a docstring, and the
doubles library that SIMULATES bao rather than calling it), which is why the
scan now matches invocation shapes instead of the word: an httpx call built
against the configured OpenBao address, or an argv whose first element is the
bao binary.
tests/test_layer_conformance.py adds the §5.2 test the standard says SHOULD
exist: _caller_env() returns the caller's environment unchanged, and proxy.py
is asserted not to reference X-Vault-Token, approle login, or token create — a
conduit that presents its own token is not a conduit.
No assertion on review dates, deliberately: a date-triggered failure breaks the
build on a calendar day with no code change, the same reasoning WP-0033-T05
recorded for blocker staleness.
398 tests pass, ruff clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YWBMovyFoy9RRrfL7zKvPJ
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 4014535@bnt-lap001
Assistant-Session: d0036016-73e8-4da1-8e47-563e3ab39a3c
2026-08-29 02:45:29 +02:00
|
|
|
return 0 if ok else 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
sys.exit(main())
|