Declare layer machine-readably (§11); adopt v0.6 corrections
The standard moved v0.4 -> v0.6. All four findings from our v0.4 review
were adopted in v0.5, and v0.6 went further on two of them.
§11 now requires a machine-readable declaration — prose cannot
distinguish a declaration from a transcribed review. We had none.
Added layer.yaml (form adapted from ops-warden's reference
implementation), scripts/check_layer_conformance.py, and
tests/test_layer_conformance.py.
The check makes our central claim mechanical rather than asserted: no
direct Tooling client in src/. The test exercises the negative case on a
synthetic tree, so it fails if the checker goes blind. pyyaml is added as
a DEV dependency only — `dependencies = []` is load-bearing for the §5
claim and stays empty.
Adopted from v0.6:
- containment is no longer ours (§9.2). Actuation is an Engine concept,
unowned and held at zero; kings-guard proposes containment and never
performs it. The register row is now a dependency, not our gap.
- observation is scoped to Staff-reachable sources, with identity and
secret observation pending — our finding 1, adopted near-verbatim.
- access-engine DECLINED the authentication-evidence gap; owner is now
the identity layer plus audit-core, reproposed and unassented.
- §11 blocked-clean recorded, with the rule that it must not rank below
conforming — our finding 2.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UEtvmYUBP2fDtirJGWn5MW
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 4014379@bnt-lap001
Assistant-Session: 4af9e20f-1768-4afc-951b-b507784e382b
2026-08-29 10:20:39 +02:00
|
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
"""Check kings-guard against the NetKingdom security layer model (§5, §11).
|
|
|
|
|
|
|
|
|
|
|
|
Read-only. kings-guard's whole position under the standard rests on one claim:
|
|
|
|
|
|
|
|
|
|
|
|
it holds no direct client for any Tooling-layer system, and the
|
|
|
|
|
|
capabilities that would need one sit at zero instead (§11 blocked-clean)
|
|
|
|
|
|
|
2026-09-05 00:42:19 +02:00
|
|
|
|
That claim has been asserted in prose since KG-DEC-2026-001. §11 (v0.7) requires
|
Declare layer machine-readably (§11); adopt v0.6 corrections
The standard moved v0.4 -> v0.6. All four findings from our v0.4 review
were adopted in v0.5, and v0.6 went further on two of them.
§11 now requires a machine-readable declaration — prose cannot
distinguish a declaration from a transcribed review. We had none.
Added layer.yaml (form adapted from ops-warden's reference
implementation), scripts/check_layer_conformance.py, and
tests/test_layer_conformance.py.
The check makes our central claim mechanical rather than asserted: no
direct Tooling client in src/. The test exercises the negative case on a
synthetic tree, so it fails if the checker goes blind. pyyaml is added as
a DEV dependency only — `dependencies = []` is load-bearing for the §5
claim and stays empty.
Adopted from v0.6:
- containment is no longer ours (§9.2). Actuation is an Engine concept,
unowned and held at zero; kings-guard proposes containment and never
performs it. The register row is now a dependency, not our gap.
- observation is scoped to Staff-reachable sources, with identity and
secret observation pending — our finding 1, adopted near-verbatim.
- access-engine DECLINED the authentication-evidence gap; owner is now
the identity layer plus audit-core, reproposed and unassented.
- §11 blocked-clean recorded, with the rule that it must not rank below
conforming — our finding 2.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UEtvmYUBP2fDtirJGWn5MW
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 4014379@bnt-lap001
Assistant-Session: 4af9e20f-1768-4afc-951b-b507784e382b
2026-08-29 10:20:39 +02:00
|
|
|
|
a machine-readable declaration because prose cannot distinguish a declaration
|
|
|
|
|
|
from a transcribed review. This script is what makes the claim checkable: it
|
|
|
|
|
|
fails if a Tooling client appears in src/ without a matching layer.yaml entry.
|
|
|
|
|
|
|
|
|
|
|
|
The failure it exists to catch is a *convenience* — someone reaching for an
|
|
|
|
|
|
OpenBao or cluster client during an incident because the engine surface still
|
|
|
|
|
|
does not exist (§9.2). That is precisely the "small convenience" §6 warns about,
|
|
|
|
|
|
and it would arrive as a one-line import.
|
|
|
|
|
|
|
2026-09-21 07:35:40 +02:00
|
|
|
|
Declaration form (GH-DEC-2026-017, amendments A9, A11, A12): INTENT.md's
|
|
|
|
|
|
frontmatter `layer:` key governs; layer.yaml is a derived artifact that must be
|
|
|
|
|
|
marked derived, name INTENT.md, and agree with it. Layer comparison ASCII-folds
|
|
|
|
|
|
case against §3's closed four-token vocabulary, so `Staff` and `staff` agree and
|
|
|
|
|
|
neither file is re-spelled. A disagreement that survives the fold is reported as
|
2026-09-21 09:38:27 +02:00
|
|
|
|
a finding, not resolved by precedence. Neither form may carry a version of the
|
|
|
|
|
|
standard or its companion in any key or value (A12 r2, GH-DEC-2026-020 §1–§2):
|
|
|
|
|
|
not only a key named `standard_version`, but `companion_version`, any other
|
|
|
|
|
|
version key, and a version-bearing path or file name such as a `standard:` of
|
|
|
|
|
|
`…security-layer-model_v0.7.md`. Comments are not read (YAML drops them) and
|
|
|
|
|
|
`schema_version` is the sidecar's own schema, so neither is reached. Only
|
|
|
|
|
|
INTENT.md frontmatter and layer.yaml are read for A12: stance, claims and
|
|
|
|
|
|
classification maps are not declarations and this run never applies A12 to them
|
|
|
|
|
|
(GH-DEC-2026-020 §3).
|
|
|
|
|
|
|
|
|
|
|
|
A bare revision citation in a prose value — `layer.yaml` cites "v0.6 §13" as
|
|
|
|
|
|
provenance in a gap record — is reported on every run, not failed: whether A12 r2's
|
|
|
|
|
|
"any value" reaches a citation rather than a pin is raised with gate-house by
|
|
|
|
|
|
kings-guard (see decisions/decisions.md KG-DEC-2026-005), not settled here.
|
|
|
|
|
|
|
|
|
|
|
|
Every run prints, first, the standard version this check was built and validated
|
|
|
|
|
|
against (VALIDATED_AGAINST) and the scope it ranges over (SCOPE), including runs
|
|
|
|
|
|
that fail (GH-DEC-2026-020 §4). A run is sufficient; nothing durable is emitted.
|
2026-09-21 07:35:40 +02:00
|
|
|
|
|
Declare layer machine-readably (§11); adopt v0.6 corrections
The standard moved v0.4 -> v0.6. All four findings from our v0.4 review
were adopted in v0.5, and v0.6 went further on two of them.
§11 now requires a machine-readable declaration — prose cannot
distinguish a declaration from a transcribed review. We had none.
Added layer.yaml (form adapted from ops-warden's reference
implementation), scripts/check_layer_conformance.py, and
tests/test_layer_conformance.py.
The check makes our central claim mechanical rather than asserted: no
direct Tooling client in src/. The test exercises the negative case on a
synthetic tree, so it fails if the checker goes blind. pyyaml is added as
a DEV dependency only — `dependencies = []` is load-bearing for the §5
claim and stays empty.
Adopted from v0.6:
- containment is no longer ours (§9.2). Actuation is an Engine concept,
unowned and held at zero; kings-guard proposes containment and never
performs it. The register row is now a dependency, not our gap.
- observation is scoped to Staff-reachable sources, with identity and
secret observation pending — our finding 1, adopted near-verbatim.
- access-engine DECLINED the authentication-evidence gap; owner is now
the identity layer plus audit-core, reproposed and unassented.
- §11 blocked-clean recorded, with the rule that it must not rank below
conforming — our finding 2.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UEtvmYUBP2fDtirJGWn5MW
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 4014379@bnt-lap001
Assistant-Session: 4af9e20f-1768-4afc-951b-b507784e382b
2026-08-29 10:20:39 +02:00
|
|
|
|
Review dates are reported, never enforced: a date-triggered failure breaks the
|
|
|
|
|
|
build on a calendar day with no code change.
|
|
|
|
|
|
|
2026-09-21 07:35:40 +02:00
|
|
|
|
Exit 0 clean, 1 undeclared contact found or the two declaration forms disagree,
|
|
|
|
|
|
2 declaration malformed.
|
Declare layer machine-readably (§11); adopt v0.6 corrections
The standard moved v0.4 -> v0.6. All four findings from our v0.4 review
were adopted in v0.5, and v0.6 went further on two of them.
§11 now requires a machine-readable declaration — prose cannot
distinguish a declaration from a transcribed review. We had none.
Added layer.yaml (form adapted from ops-warden's reference
implementation), scripts/check_layer_conformance.py, and
tests/test_layer_conformance.py.
The check makes our central claim mechanical rather than asserted: no
direct Tooling client in src/. The test exercises the negative case on a
synthetic tree, so it fails if the checker goes blind. pyyaml is added as
a DEV dependency only — `dependencies = []` is load-bearing for the §5
claim and stays empty.
Adopted from v0.6:
- containment is no longer ours (§9.2). Actuation is an Engine concept,
unowned and held at zero; kings-guard proposes containment and never
performs it. The register row is now a dependency, not our gap.
- observation is scoped to Staff-reachable sources, with identity and
secret observation pending — our finding 1, adopted near-verbatim.
- access-engine DECLINED the authentication-evidence gap; owner is now
the identity layer plus audit-core, reproposed and unassented.
- §11 blocked-clean recorded, with the rule that it must not rank below
conforming — our finding 2.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UEtvmYUBP2fDtirJGWn5MW
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 4014379@bnt-lap001
Assistant-Session: 4af9e20f-1768-4afc-951b-b507784e382b
2026-08-29 10:20:39 +02:00
|
|
|
|
"""
|
|
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
|
|
import argparse
|
|
|
|
|
|
import ast
|
2026-09-02 00:11:57 +02:00
|
|
|
|
import re
|
Declare layer machine-readably (§11); adopt v0.6 corrections
The standard moved v0.4 -> v0.6. All four findings from our v0.4 review
were adopted in v0.5, and v0.6 went further on two of them.
§11 now requires a machine-readable declaration — prose cannot
distinguish a declaration from a transcribed review. We had none.
Added layer.yaml (form adapted from ops-warden's reference
implementation), scripts/check_layer_conformance.py, and
tests/test_layer_conformance.py.
The check makes our central claim mechanical rather than asserted: no
direct Tooling client in src/. The test exercises the negative case on a
synthetic tree, so it fails if the checker goes blind. pyyaml is added as
a DEV dependency only — `dependencies = []` is load-bearing for the §5
claim and stays empty.
Adopted from v0.6:
- containment is no longer ours (§9.2). Actuation is an Engine concept,
unowned and held at zero; kings-guard proposes containment and never
performs it. The register row is now a dependency, not our gap.
- observation is scoped to Staff-reachable sources, with identity and
secret observation pending — our finding 1, adopted near-verbatim.
- access-engine DECLINED the authentication-evidence gap; owner is now
the identity layer plus audit-core, reproposed and unassented.
- §11 blocked-clean recorded, with the rule that it must not rank below
conforming — our finding 2.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UEtvmYUBP2fDtirJGWn5MW
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 4014379@bnt-lap001
Assistant-Session: 4af9e20f-1768-4afc-951b-b507784e382b
2026-08-29 10:20:39 +02:00
|
|
|
|
import sys
|
|
|
|
|
|
from datetime import date
|
|
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
|
|
|
|
|
|
import yaml
|
|
|
|
|
|
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
|
|
|
|
SRC = ROOT / "src" / "kings_guard"
|
|
|
|
|
|
DECL = ROOT / "layer.yaml"
|
2026-09-21 07:35:40 +02:00
|
|
|
|
INTENT = ROOT / "INTENT.md"
|
|
|
|
|
|
|
|
|
|
|
|
# The standard text this checker was built and validated against. This is the
|
|
|
|
|
|
# derived conformance record's version (GH-DEC-2026-017 §5 / A12), moved here
|
|
|
|
|
|
# from layer.yaml's former `standard_version: "0.7"`, which recorded the same
|
|
|
|
|
|
# fact in a place the ruling says a declaration must not carry it. Bump it when
|
|
|
|
|
|
# the checker is re-validated against a newer accepted text.
|
|
|
|
|
|
VALIDATED_AGAINST = "net-kingdom/canon/standards/security-layer-model_v0.7.md"
|
|
|
|
|
|
|
2026-09-21 09:38:27 +02:00
|
|
|
|
# The scope every run ranges over, printed on every run (GH-DEC-2026-020 §4, A11).
|
|
|
|
|
|
# This is a single-repository run, not an estate run: it grades kings-guard, a §4
|
|
|
|
|
|
# row, and nothing else.
|
|
|
|
|
|
SCOPE = (
|
|
|
|
|
|
"kings-guard only (§4 row, Staff): INTENT.md frontmatter, layer.yaml, "
|
|
|
|
|
|
"src/kings_guard, repository tree for credential files"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# A12 r2 detection. A key naming a version is a pin, except the sidecar's own
|
|
|
|
|
|
# schema_version. A value naming the standard or companion with a version, or any
|
|
|
|
|
|
# versioned file name, is a pin. In identity-bearing keys any version token is a
|
|
|
|
|
|
# pin. A bare "vN.N" elsewhere in a value is a citation: reported, not failed.
|
|
|
|
|
|
A12_EXEMPT_KEYS = {"schema_version"}
|
|
|
|
|
|
A12_IDENTITY_KEYS = {"standard", "companion", "framework"}
|
|
|
|
|
|
A12_PIN_VALUE = re.compile(
|
|
|
|
|
|
r"""(?ix)
|
|
|
|
|
|
(?:security[-_ ]?layer[-_ ]?model|security[-_ ]?companion)[^\s'"]*?[-_.]v?\d+(?:\.\d+)+
|
|
|
|
|
|
| [-_]v\d+(?:\.\d+)*\.(?:md|ya?ml|json)\b
|
|
|
|
|
|
"""
|
|
|
|
|
|
)
|
|
|
|
|
|
A12_VERSION_TOKEN = re.compile(r"\bv?\d+\.\d+(?:\.\d+)*\b")
|
|
|
|
|
|
A12_CITATION = re.compile(r"\bv\d+\.\d+\b")
|
|
|
|
|
|
|
2026-09-21 07:35:40 +02:00
|
|
|
|
# §3's closed layer vocabulary (A9): four tokens, compared ASCII case-insensitively.
|
|
|
|
|
|
LAYER_VOCABULARY = {"taxonomy", "tooling", "engine", "staff"}
|
|
|
|
|
|
EXPECTED_LAYER = "staff" # kings-guard's own §4 row, folded
|
Declare layer machine-readably (§11); adopt v0.6 corrections
The standard moved v0.4 -> v0.6. All four findings from our v0.4 review
were adopted in v0.5, and v0.6 went further on two of them.
§11 now requires a machine-readable declaration — prose cannot
distinguish a declaration from a transcribed review. We had none.
Added layer.yaml (form adapted from ops-warden's reference
implementation), scripts/check_layer_conformance.py, and
tests/test_layer_conformance.py.
The check makes our central claim mechanical rather than asserted: no
direct Tooling client in src/. The test exercises the negative case on a
synthetic tree, so it fails if the checker goes blind. pyyaml is added as
a DEV dependency only — `dependencies = []` is load-bearing for the §5
claim and stays empty.
Adopted from v0.6:
- containment is no longer ours (§9.2). Actuation is an Engine concept,
unowned and held at zero; kings-guard proposes containment and never
performs it. The register row is now a dependency, not our gap.
- observation is scoped to Staff-reachable sources, with identity and
secret observation pending — our finding 1, adopted near-verbatim.
- access-engine DECLINED the authentication-evidence gap; owner is now
the identity layer plus audit-core, reproposed and unassented.
- §11 blocked-clean recorded, with the rule that it must not rank below
conforming — our finding 2.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UEtvmYUBP2fDtirJGWn5MW
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 4014379@bnt-lap001
Assistant-Session: 4af9e20f-1768-4afc-951b-b507784e382b
2026-08-29 10:20:39 +02:00
|
|
|
|
|
|
|
|
|
|
# Import roots that would constitute a direct Tooling-layer client under §4.
|
|
|
|
|
|
# Matched against the top-level module of every import in src/.
|
|
|
|
|
|
TOOLING_IMPORTS = {
|
|
|
|
|
|
"hvac": "OpenBao / Vault client",
|
|
|
|
|
|
"bao": "OpenBao client",
|
|
|
|
|
|
"kubernetes": "cluster client",
|
|
|
|
|
|
"kubernetes_asyncio": "cluster client",
|
|
|
|
|
|
"psycopg": "direct database connection",
|
|
|
|
|
|
"psycopg2": "direct database connection",
|
|
|
|
|
|
"asyncpg": "direct database connection",
|
|
|
|
|
|
"sqlalchemy": "direct database connection",
|
|
|
|
|
|
"pymysql": "direct database connection",
|
|
|
|
|
|
"redis": "direct datastore connection",
|
|
|
|
|
|
"ldap3": "direct LDAP client (key-cape tooling)",
|
|
|
|
|
|
"python_ldap": "direct LDAP client (key-cape tooling)",
|
|
|
|
|
|
"docker": "container runtime client",
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-09-02 00:11:57 +02:00
|
|
|
|
# §3.4 rule 1 — no standing credential held in the repository or its
|
|
|
|
|
|
# configuration. Filenames that would be a standing secret, and assignments
|
|
|
|
|
|
# of well-known secret env vars to string literals in src/.
|
|
|
|
|
|
CREDENTIAL_FILENAMES = {
|
|
|
|
|
|
".env",
|
|
|
|
|
|
".env.local",
|
|
|
|
|
|
".env.production",
|
|
|
|
|
|
"credentials.json",
|
|
|
|
|
|
"secrets.yaml",
|
|
|
|
|
|
"secrets.yml",
|
|
|
|
|
|
"id_rsa",
|
|
|
|
|
|
"id_ed25519",
|
|
|
|
|
|
"id_ecdsa",
|
|
|
|
|
|
}
|
|
|
|
|
|
CREDENTIAL_LITERAL = re.compile(
|
|
|
|
|
|
r"""(?x)
|
|
|
|
|
|
\b(?:VAULT_TOKEN|OPENBAO_TOKEN|BAO_TOKEN|AWS_SECRET_ACCESS_KEY|
|
|
|
|
|
|
PRIVATE_KEY|BEGIN\ (?:RSA\ )?PRIVATE\ KEY)
|
|
|
|
|
|
"""
|
|
|
|
|
|
)
|
|
|
|
|
|
SKIP_CREDENTIAL_SCAN_DIRS = {".git", ".venv", "__pycache__", ".pytest_cache", ".ruff_cache"}
|
|
|
|
|
|
|
Declare layer machine-readably (§11); adopt v0.6 corrections
The standard moved v0.4 -> v0.6. All four findings from our v0.4 review
were adopted in v0.5, and v0.6 went further on two of them.
§11 now requires a machine-readable declaration — prose cannot
distinguish a declaration from a transcribed review. We had none.
Added layer.yaml (form adapted from ops-warden's reference
implementation), scripts/check_layer_conformance.py, and
tests/test_layer_conformance.py.
The check makes our central claim mechanical rather than asserted: no
direct Tooling client in src/. The test exercises the negative case on a
synthetic tree, so it fails if the checker goes blind. pyyaml is added as
a DEV dependency only — `dependencies = []` is load-bearing for the §5
claim and stays empty.
Adopted from v0.6:
- containment is no longer ours (§9.2). Actuation is an Engine concept,
unowned and held at zero; kings-guard proposes containment and never
performs it. The register row is now a dependency, not our gap.
- observation is scoped to Staff-reachable sources, with identity and
secret observation pending — our finding 1, adopted near-verbatim.
- access-engine DECLINED the authentication-evidence gap; owner is now
the identity layer plus audit-core, reproposed and unassented.
- §11 blocked-clean recorded, with the rule that it must not rank below
conforming — our finding 2.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UEtvmYUBP2fDtirJGWn5MW
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 4014379@bnt-lap001
Assistant-Session: 4af9e20f-1768-4afc-951b-b507784e382b
2026-08-29 10:20:39 +02:00
|
|
|
|
|
2026-09-21 07:35:40 +02:00
|
|
|
|
def fold(value: object) -> str:
|
|
|
|
|
|
"""ASCII case-fold, per §3 as amended (A9): two spellings are one token."""
|
|
|
|
|
|
return str(value).encode("ascii", "replace").decode("ascii").lower()
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-09-21 09:38:27 +02:00
|
|
|
|
def a12_findings(node: object, where: str) -> tuple[list[str], list[str]]:
|
|
|
|
|
|
"""Every key and value of a declaration form, walked (A12 r2).
|
|
|
|
|
|
|
|
|
|
|
|
Returns (pins, citations). Pins fail the run; citations are reported.
|
|
|
|
|
|
"""
|
|
|
|
|
|
pins: list[str] = []
|
|
|
|
|
|
citations: list[str] = []
|
|
|
|
|
|
|
|
|
|
|
|
def walk(value: object, path: str, key: str | None) -> None:
|
|
|
|
|
|
if isinstance(value, dict):
|
|
|
|
|
|
for k, v in value.items():
|
|
|
|
|
|
k_str = str(k)
|
|
|
|
|
|
sub = f"{path}.{k_str}" if path else k_str
|
|
|
|
|
|
if "version" in k_str.lower() and k_str not in A12_EXEMPT_KEYS:
|
|
|
|
|
|
pins.append(f"{where}: key '{sub}' carries a version")
|
|
|
|
|
|
if k_str in A12_EXEMPT_KEYS:
|
|
|
|
|
|
continue
|
|
|
|
|
|
walk(v, sub, k_str)
|
|
|
|
|
|
return
|
|
|
|
|
|
if isinstance(value, list):
|
|
|
|
|
|
for i, v in enumerate(value):
|
|
|
|
|
|
walk(v, f"{path}[{i}]", key)
|
|
|
|
|
|
return
|
|
|
|
|
|
if value is None or isinstance(value, bool):
|
|
|
|
|
|
return
|
|
|
|
|
|
text = str(value)
|
|
|
|
|
|
if A12_PIN_VALUE.search(text) or (
|
|
|
|
|
|
key in A12_IDENTITY_KEYS and A12_VERSION_TOKEN.search(text)
|
|
|
|
|
|
):
|
|
|
|
|
|
pins.append(f"{where}: '{path}' = {text!r} names a versioned standard")
|
|
|
|
|
|
elif A12_CITATION.search(text):
|
|
|
|
|
|
match = A12_CITATION.search(text).group(0)
|
|
|
|
|
|
citations.append(f"{where}: '{path}' cites {match} in prose")
|
|
|
|
|
|
|
|
|
|
|
|
walk(node, "", None)
|
|
|
|
|
|
return pins, citations
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _refuse_pins(pins: list[str]) -> None:
|
|
|
|
|
|
if pins:
|
|
|
|
|
|
_malformed(
|
|
|
|
|
|
"a layer declaration MUST NOT carry a standard or companion version "
|
|
|
|
|
|
"in any key or value (§11 as amended by A12 r2, GH-DEC-2026-020 §1–§2):\n "
|
|
|
|
|
|
+ "\n ".join(pins)
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-09-21 07:35:40 +02:00
|
|
|
|
def _malformed(message: str) -> None:
|
|
|
|
|
|
print(f"FAIL: {message}", file=sys.stderr)
|
|
|
|
|
|
raise SystemExit(2)
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-09-21 09:38:27 +02:00
|
|
|
|
def load_intent_frontmatter() -> dict:
|
|
|
|
|
|
"""INTENT.md's frontmatter, parsed; the governing declaration form (§11)."""
|
2026-09-21 07:35:40 +02:00
|
|
|
|
if not INTENT.exists():
|
|
|
|
|
|
_malformed(f"no {INTENT.name} — §11's governing declaration form")
|
|
|
|
|
|
lines = INTENT.read_text().splitlines()
|
|
|
|
|
|
if not lines or lines[0].strip() != "---":
|
|
|
|
|
|
_malformed(f"{INTENT.name} has no frontmatter to carry the declaration (§11)")
|
|
|
|
|
|
try:
|
|
|
|
|
|
end = lines[1:].index("---") + 1
|
|
|
|
|
|
except ValueError:
|
|
|
|
|
|
_malformed(f"{INTENT.name} frontmatter is not terminated")
|
|
|
|
|
|
try:
|
|
|
|
|
|
front = yaml.safe_load("\n".join(lines[1:end])) or {}
|
|
|
|
|
|
except yaml.YAMLError as exc:
|
|
|
|
|
|
_malformed(f"{INTENT.name} frontmatter is not parseable: {exc}")
|
2026-09-21 09:38:27 +02:00
|
|
|
|
if not isinstance(front, dict):
|
|
|
|
|
|
_malformed(f"{INTENT.name} frontmatter is not a mapping")
|
|
|
|
|
|
return front
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def load_governing_layer() -> str:
|
|
|
|
|
|
"""The declaration: INTENT.md frontmatter `layer:` (§11, GH-DEC-2026-017 §1)."""
|
|
|
|
|
|
front = load_intent_frontmatter()
|
2026-09-21 07:35:40 +02:00
|
|
|
|
if "layer" not in front:
|
|
|
|
|
|
_malformed(f"{INTENT.name} frontmatter has no 'layer' key — §11's declaration")
|
2026-09-21 09:38:27 +02:00
|
|
|
|
_refuse_pins(a12_findings(front, f"{INTENT.name} frontmatter")[0])
|
2026-09-21 07:35:40 +02:00
|
|
|
|
layer = front["layer"]
|
|
|
|
|
|
if fold(layer) not in LAYER_VOCABULARY:
|
|
|
|
|
|
_malformed(
|
|
|
|
|
|
f"{INTENT.name} declares layer {layer!r}, outside §3's closed vocabulary "
|
|
|
|
|
|
f"{sorted(LAYER_VOCABULARY)} (case-insensitive)"
|
|
|
|
|
|
)
|
|
|
|
|
|
if fold(layer) != EXPECTED_LAYER:
|
|
|
|
|
|
_malformed(f"{INTENT.name} declares layer {layer!r}, expected Staff (§4 row)")
|
|
|
|
|
|
return str(layer)
|
|
|
|
|
|
|
|
|
|
|
|
|
Declare layer machine-readably (§11); adopt v0.6 corrections
The standard moved v0.4 -> v0.6. All four findings from our v0.4 review
were adopted in v0.5, and v0.6 went further on two of them.
§11 now requires a machine-readable declaration — prose cannot
distinguish a declaration from a transcribed review. We had none.
Added layer.yaml (form adapted from ops-warden's reference
implementation), scripts/check_layer_conformance.py, and
tests/test_layer_conformance.py.
The check makes our central claim mechanical rather than asserted: no
direct Tooling client in src/. The test exercises the negative case on a
synthetic tree, so it fails if the checker goes blind. pyyaml is added as
a DEV dependency only — `dependencies = []` is load-bearing for the §5
claim and stays empty.
Adopted from v0.6:
- containment is no longer ours (§9.2). Actuation is an Engine concept,
unowned and held at zero; kings-guard proposes containment and never
performs it. The register row is now a dependency, not our gap.
- observation is scoped to Staff-reachable sources, with identity and
secret observation pending — our finding 1, adopted near-verbatim.
- access-engine DECLINED the authentication-evidence gap; owner is now
the identity layer plus audit-core, reproposed and unassented.
- §11 blocked-clean recorded, with the rule that it must not rank below
conforming — our finding 2.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UEtvmYUBP2fDtirJGWn5MW
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 4014379@bnt-lap001
Assistant-Session: 4af9e20f-1768-4afc-951b-b507784e382b
2026-08-29 10:20:39 +02:00
|
|
|
|
def load_declaration() -> dict:
|
2026-09-21 07:35:40 +02:00
|
|
|
|
"""The derived form, layer.yaml (§11 derived-artifact rule)."""
|
Declare layer machine-readably (§11); adopt v0.6 corrections
The standard moved v0.4 -> v0.6. All four findings from our v0.4 review
were adopted in v0.5, and v0.6 went further on two of them.
§11 now requires a machine-readable declaration — prose cannot
distinguish a declaration from a transcribed review. We had none.
Added layer.yaml (form adapted from ops-warden's reference
implementation), scripts/check_layer_conformance.py, and
tests/test_layer_conformance.py.
The check makes our central claim mechanical rather than asserted: no
direct Tooling client in src/. The test exercises the negative case on a
synthetic tree, so it fails if the checker goes blind. pyyaml is added as
a DEV dependency only — `dependencies = []` is load-bearing for the §5
claim and stays empty.
Adopted from v0.6:
- containment is no longer ours (§9.2). Actuation is an Engine concept,
unowned and held at zero; kings-guard proposes containment and never
performs it. The register row is now a dependency, not our gap.
- observation is scoped to Staff-reachable sources, with identity and
secret observation pending — our finding 1, adopted near-verbatim.
- access-engine DECLINED the authentication-evidence gap; owner is now
the identity layer plus audit-core, reproposed and unassented.
- §11 blocked-clean recorded, with the rule that it must not rank below
conforming — our finding 2.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UEtvmYUBP2fDtirJGWn5MW
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 4014379@bnt-lap001
Assistant-Session: 4af9e20f-1768-4afc-951b-b507784e382b
2026-08-29 10:20:39 +02:00
|
|
|
|
if not DECL.exists():
|
2026-09-21 07:35:40 +02:00
|
|
|
|
_malformed(f"no declaration at {DECL.relative_to(ROOT)} (§11)")
|
Declare layer machine-readably (§11); adopt v0.6 corrections
The standard moved v0.4 -> v0.6. All four findings from our v0.4 review
were adopted in v0.5, and v0.6 went further on two of them.
§11 now requires a machine-readable declaration — prose cannot
distinguish a declaration from a transcribed review. We had none.
Added layer.yaml (form adapted from ops-warden's reference
implementation), scripts/check_layer_conformance.py, and
tests/test_layer_conformance.py.
The check makes our central claim mechanical rather than asserted: no
direct Tooling client in src/. The test exercises the negative case on a
synthetic tree, so it fails if the checker goes blind. pyyaml is added as
a DEV dependency only — `dependencies = []` is load-bearing for the §5
claim and stays empty.
Adopted from v0.6:
- containment is no longer ours (§9.2). Actuation is an Engine concept,
unowned and held at zero; kings-guard proposes containment and never
performs it. The register row is now a dependency, not our gap.
- observation is scoped to Staff-reachable sources, with identity and
secret observation pending — our finding 1, adopted near-verbatim.
- access-engine DECLINED the authentication-evidence gap; owner is now
the identity layer plus audit-core, reproposed and unassented.
- §11 blocked-clean recorded, with the rule that it must not rank below
conforming — our finding 2.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UEtvmYUBP2fDtirJGWn5MW
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 4014379@bnt-lap001
Assistant-Session: 4af9e20f-1768-4afc-951b-b507784e382b
2026-08-29 10:20:39 +02:00
|
|
|
|
try:
|
|
|
|
|
|
data = yaml.safe_load(DECL.read_text())
|
|
|
|
|
|
except yaml.YAMLError as exc:
|
|
|
|
|
|
print(f"FAIL: {DECL.name} is not parseable: {exc}", file=sys.stderr)
|
|
|
|
|
|
raise SystemExit(2) from exc
|
2026-09-21 07:35:40 +02:00
|
|
|
|
for key in ("layer", "repository", "tooling_contacts", "derived", "derived_from"):
|
Declare layer machine-readably (§11); adopt v0.6 corrections
The standard moved v0.4 -> v0.6. All four findings from our v0.4 review
were adopted in v0.5, and v0.6 went further on two of them.
§11 now requires a machine-readable declaration — prose cannot
distinguish a declaration from a transcribed review. We had none.
Added layer.yaml (form adapted from ops-warden's reference
implementation), scripts/check_layer_conformance.py, and
tests/test_layer_conformance.py.
The check makes our central claim mechanical rather than asserted: no
direct Tooling client in src/. The test exercises the negative case on a
synthetic tree, so it fails if the checker goes blind. pyyaml is added as
a DEV dependency only — `dependencies = []` is load-bearing for the §5
claim and stays empty.
Adopted from v0.6:
- containment is no longer ours (§9.2). Actuation is an Engine concept,
unowned and held at zero; kings-guard proposes containment and never
performs it. The register row is now a dependency, not our gap.
- observation is scoped to Staff-reachable sources, with identity and
secret observation pending — our finding 1, adopted near-verbatim.
- access-engine DECLINED the authentication-evidence gap; owner is now
the identity layer plus audit-core, reproposed and unassented.
- §11 blocked-clean recorded, with the rule that it must not rank below
conforming — our finding 2.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UEtvmYUBP2fDtirJGWn5MW
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 4014379@bnt-lap001
Assistant-Session: 4af9e20f-1768-4afc-951b-b507784e382b
2026-08-29 10:20:39 +02:00
|
|
|
|
if key not in data:
|
2026-09-21 07:35:40 +02:00
|
|
|
|
_malformed(f"{DECL.name} missing required key '{key}' (§11)")
|
|
|
|
|
|
if data["derived"] is not True:
|
|
|
|
|
|
_malformed(f"{DECL.name} must be marked 'derived: true' (§11, GH-DEC-2026-017 §1)")
|
|
|
|
|
|
if data["derived_from"] != "INTENT.md":
|
|
|
|
|
|
_malformed(
|
|
|
|
|
|
f"{DECL.name} derives from {data['derived_from']!r}; §11 names INTENT.md "
|
|
|
|
|
|
"as the governing declaration"
|
|
|
|
|
|
)
|
2026-09-21 09:38:27 +02:00
|
|
|
|
_refuse_pins(a12_findings(data, DECL.name)[0])
|
2026-09-21 07:35:40 +02:00
|
|
|
|
if fold(data["layer"]) not in LAYER_VOCABULARY:
|
|
|
|
|
|
_malformed(
|
|
|
|
|
|
f"{DECL.name} declares layer {data['layer']!r}, outside §3's closed "
|
|
|
|
|
|
f"vocabulary {sorted(LAYER_VOCABULARY)} (case-insensitive)"
|
|
|
|
|
|
)
|
Declare layer machine-readably (§11); adopt v0.6 corrections
The standard moved v0.4 -> v0.6. All four findings from our v0.4 review
were adopted in v0.5, and v0.6 went further on two of them.
§11 now requires a machine-readable declaration — prose cannot
distinguish a declaration from a transcribed review. We had none.
Added layer.yaml (form adapted from ops-warden's reference
implementation), scripts/check_layer_conformance.py, and
tests/test_layer_conformance.py.
The check makes our central claim mechanical rather than asserted: no
direct Tooling client in src/. The test exercises the negative case on a
synthetic tree, so it fails if the checker goes blind. pyyaml is added as
a DEV dependency only — `dependencies = []` is load-bearing for the §5
claim and stays empty.
Adopted from v0.6:
- containment is no longer ours (§9.2). Actuation is an Engine concept,
unowned and held at zero; kings-guard proposes containment and never
performs it. The register row is now a dependency, not our gap.
- observation is scoped to Staff-reachable sources, with identity and
secret observation pending — our finding 1, adopted near-verbatim.
- access-engine DECLINED the authentication-evidence gap; owner is now
the identity layer plus audit-core, reproposed and unassented.
- §11 blocked-clean recorded, with the rule that it must not rank below
conforming — our finding 2.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UEtvmYUBP2fDtirJGWn5MW
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 4014379@bnt-lap001
Assistant-Session: 4af9e20f-1768-4afc-951b-b507784e382b
2026-08-29 10:20:39 +02:00
|
|
|
|
return data
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-09-21 07:35:40 +02:00
|
|
|
|
def forms_disagree(governing: object, derived: object) -> bool:
|
|
|
|
|
|
"""A11: the derived form must agree with INTENT.md, after the A9 case fold."""
|
|
|
|
|
|
return fold(governing) != fold(derived)
|
|
|
|
|
|
|
|
|
|
|
|
|
Declare layer machine-readably (§11); adopt v0.6 corrections
The standard moved v0.4 -> v0.6. All four findings from our v0.4 review
were adopted in v0.5, and v0.6 went further on two of them.
§11 now requires a machine-readable declaration — prose cannot
distinguish a declaration from a transcribed review. We had none.
Added layer.yaml (form adapted from ops-warden's reference
implementation), scripts/check_layer_conformance.py, and
tests/test_layer_conformance.py.
The check makes our central claim mechanical rather than asserted: no
direct Tooling client in src/. The test exercises the negative case on a
synthetic tree, so it fails if the checker goes blind. pyyaml is added as
a DEV dependency only — `dependencies = []` is load-bearing for the §5
claim and stays empty.
Adopted from v0.6:
- containment is no longer ours (§9.2). Actuation is an Engine concept,
unowned and held at zero; kings-guard proposes containment and never
performs it. The register row is now a dependency, not our gap.
- observation is scoped to Staff-reachable sources, with identity and
secret observation pending — our finding 1, adopted near-verbatim.
- access-engine DECLINED the authentication-evidence gap; owner is now
the identity layer plus audit-core, reproposed and unassented.
- §11 blocked-clean recorded, with the rule that it must not rank below
conforming — our finding 2.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UEtvmYUBP2fDtirJGWn5MW
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 4014379@bnt-lap001
Assistant-Session: 4af9e20f-1768-4afc-951b-b507784e382b
2026-08-29 10:20:39 +02:00
|
|
|
|
def imported_modules(path: Path) -> set[str]:
|
|
|
|
|
|
"""Top-level module name of every import in one file."""
|
|
|
|
|
|
try:
|
|
|
|
|
|
tree = ast.parse(path.read_text())
|
|
|
|
|
|
except SyntaxError:
|
|
|
|
|
|
return set()
|
|
|
|
|
|
found: set[str] = set()
|
|
|
|
|
|
for node in ast.walk(tree):
|
|
|
|
|
|
if isinstance(node, ast.Import):
|
|
|
|
|
|
found.update(alias.name.split(".")[0] for alias in node.names)
|
|
|
|
|
|
elif isinstance(node, ast.ImportFrom):
|
|
|
|
|
|
if node.level == 0 and node.module:
|
|
|
|
|
|
found.add(node.module.split(".")[0])
|
|
|
|
|
|
return found
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def scan() -> list[tuple[Path, str, str]]:
|
|
|
|
|
|
hits: list[tuple[Path, str, str]] = []
|
|
|
|
|
|
for path in sorted(SRC.rglob("*.py")):
|
|
|
|
|
|
for module in sorted(imported_modules(path)):
|
|
|
|
|
|
if module in TOOLING_IMPORTS:
|
|
|
|
|
|
hits.append((path, module, TOOLING_IMPORTS[module]))
|
|
|
|
|
|
return hits
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-09-02 00:11:57 +02:00
|
|
|
|
def scan_standing_credentials() -> list[tuple[Path, str]]:
|
|
|
|
|
|
"""§3.4 rule 1: no standing credential in the repository or its config."""
|
|
|
|
|
|
hits: list[tuple[Path, str]] = []
|
|
|
|
|
|
for path in ROOT.rglob("*"):
|
|
|
|
|
|
if not path.is_file():
|
|
|
|
|
|
continue
|
|
|
|
|
|
if any(part in SKIP_CREDENTIAL_SCAN_DIRS for part in path.parts):
|
|
|
|
|
|
continue
|
|
|
|
|
|
if path.name in CREDENTIAL_FILENAMES:
|
|
|
|
|
|
hits.append((path, f"credential-shaped file {path.name}"))
|
|
|
|
|
|
continue
|
|
|
|
|
|
if path.suffix in {".pem", ".key"} and "test" not in path.parts:
|
|
|
|
|
|
hits.append((path, f"key material file {path.name}"))
|
|
|
|
|
|
if SRC.is_dir():
|
|
|
|
|
|
for path in sorted(SRC.rglob("*.py")):
|
|
|
|
|
|
text = path.read_text(encoding="utf-8")
|
|
|
|
|
|
if CREDENTIAL_LITERAL.search(text):
|
|
|
|
|
|
hits.append((path, "standing-credential literal or private-key block"))
|
|
|
|
|
|
return hits
|
|
|
|
|
|
|
|
|
|
|
|
|
Declare layer machine-readably (§11); adopt v0.6 corrections
The standard moved v0.4 -> v0.6. All four findings from our v0.4 review
were adopted in v0.5, and v0.6 went further on two of them.
§11 now requires a machine-readable declaration — prose cannot
distinguish a declaration from a transcribed review. We had none.
Added layer.yaml (form adapted from ops-warden's reference
implementation), scripts/check_layer_conformance.py, and
tests/test_layer_conformance.py.
The check makes our central claim mechanical rather than asserted: no
direct Tooling client in src/. The test exercises the negative case on a
synthetic tree, so it fails if the checker goes blind. pyyaml is added as
a DEV dependency only — `dependencies = []` is load-bearing for the §5
claim and stays empty.
Adopted from v0.6:
- containment is no longer ours (§9.2). Actuation is an Engine concept,
unowned and held at zero; kings-guard proposes containment and never
performs it. The register row is now a dependency, not our gap.
- observation is scoped to Staff-reachable sources, with identity and
secret observation pending — our finding 1, adopted near-verbatim.
- access-engine DECLINED the authentication-evidence gap; owner is now
the identity layer plus audit-core, reproposed and unassented.
- §11 blocked-clean recorded, with the rule that it must not rank below
conforming — our finding 2.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UEtvmYUBP2fDtirJGWn5MW
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 4014379@bnt-lap001
Assistant-Session: 4af9e20f-1768-4afc-951b-b507784e382b
2026-08-29 10:20:39 +02:00
|
|
|
|
def main() -> int:
|
|
|
|
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
|
|
|
|
parser.add_argument("--report", action="store_true", help="print the declaration summary")
|
|
|
|
|
|
args = parser.parse_args()
|
|
|
|
|
|
|
2026-09-21 09:38:27 +02:00
|
|
|
|
# Every run, pass or fail, states what it checks against and over what
|
|
|
|
|
|
# (GH-DEC-2026-020 §4). Printed before anything can exit.
|
|
|
|
|
|
print(f"checking against: {VALIDATED_AGAINST}")
|
|
|
|
|
|
print(f"scope: {SCOPE}")
|
|
|
|
|
|
|
2026-09-21 07:35:40 +02:00
|
|
|
|
governing = load_governing_layer()
|
Declare layer machine-readably (§11); adopt v0.6 corrections
The standard moved v0.4 -> v0.6. All four findings from our v0.4 review
were adopted in v0.5, and v0.6 went further on two of them.
§11 now requires a machine-readable declaration — prose cannot
distinguish a declaration from a transcribed review. We had none.
Added layer.yaml (form adapted from ops-warden's reference
implementation), scripts/check_layer_conformance.py, and
tests/test_layer_conformance.py.
The check makes our central claim mechanical rather than asserted: no
direct Tooling client in src/. The test exercises the negative case on a
synthetic tree, so it fails if the checker goes blind. pyyaml is added as
a DEV dependency only — `dependencies = []` is load-bearing for the §5
claim and stays empty.
Adopted from v0.6:
- containment is no longer ours (§9.2). Actuation is an Engine concept,
unowned and held at zero; kings-guard proposes containment and never
performs it. The register row is now a dependency, not our gap.
- observation is scoped to Staff-reachable sources, with identity and
secret observation pending — our finding 1, adopted near-verbatim.
- access-engine DECLINED the authentication-evidence gap; owner is now
the identity layer plus audit-core, reproposed and unassented.
- §11 blocked-clean recorded, with the rule that it must not rank below
conforming — our finding 2.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UEtvmYUBP2fDtirJGWn5MW
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 4014379@bnt-lap001
Assistant-Session: 4af9e20f-1768-4afc-951b-b507784e382b
2026-08-29 10:20:39 +02:00
|
|
|
|
decl = load_declaration()
|
|
|
|
|
|
declared = {c.get("id") for c in decl.get("tooling_contacts") or []}
|
|
|
|
|
|
hits = scan()
|
2026-09-02 00:11:57 +02:00
|
|
|
|
credential_hits = scan_standing_credentials()
|
Declare layer machine-readably (§11); adopt v0.6 corrections
The standard moved v0.4 -> v0.6. All four findings from our v0.4 review
were adopted in v0.5, and v0.6 went further on two of them.
§11 now requires a machine-readable declaration — prose cannot
distinguish a declaration from a transcribed review. We had none.
Added layer.yaml (form adapted from ops-warden's reference
implementation), scripts/check_layer_conformance.py, and
tests/test_layer_conformance.py.
The check makes our central claim mechanical rather than asserted: no
direct Tooling client in src/. The test exercises the negative case on a
synthetic tree, so it fails if the checker goes blind. pyyaml is added as
a DEV dependency only — `dependencies = []` is load-bearing for the §5
claim and stays empty.
Adopted from v0.6:
- containment is no longer ours (§9.2). Actuation is an Engine concept,
unowned and held at zero; kings-guard proposes containment and never
performs it. The register row is now a dependency, not our gap.
- observation is scoped to Staff-reachable sources, with identity and
secret observation pending — our finding 1, adopted near-verbatim.
- access-engine DECLINED the authentication-evidence gap; owner is now
the identity layer plus audit-core, reproposed and unassented.
- §11 blocked-clean recorded, with the rule that it must not rank below
conforming — our finding 2.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UEtvmYUBP2fDtirJGWn5MW
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 4014379@bnt-lap001
Assistant-Session: 4af9e20f-1768-4afc-951b-b507784e382b
2026-08-29 10:20:39 +02:00
|
|
|
|
|
|
|
|
|
|
undeclared = [h for h in hits if h[1] not in declared]
|
2026-09-02 00:11:57 +02:00
|
|
|
|
rules = decl.get("agent_principal_rules") or {}
|
|
|
|
|
|
checks = decl.get("agent_principal_rule_checks") or {}
|
Declare layer machine-readably (§11); adopt v0.6 corrections
The standard moved v0.4 -> v0.6. All four findings from our v0.4 review
were adopted in v0.5, and v0.6 went further on two of them.
§11 now requires a machine-readable declaration — prose cannot
distinguish a declaration from a transcribed review. We had none.
Added layer.yaml (form adapted from ops-warden's reference
implementation), scripts/check_layer_conformance.py, and
tests/test_layer_conformance.py.
The check makes our central claim mechanical rather than asserted: no
direct Tooling client in src/. The test exercises the negative case on a
synthetic tree, so it fails if the checker goes blind. pyyaml is added as
a DEV dependency only — `dependencies = []` is load-bearing for the §5
claim and stays empty.
Adopted from v0.6:
- containment is no longer ours (§9.2). Actuation is an Engine concept,
unowned and held at zero; kings-guard proposes containment and never
performs it. The register row is now a dependency, not our gap.
- observation is scoped to Staff-reachable sources, with identity and
secret observation pending — our finding 1, adopted near-verbatim.
- access-engine DECLINED the authentication-evidence gap; owner is now
the identity layer plus audit-core, reproposed and unassented.
- §11 blocked-clean recorded, with the rule that it must not rank below
conforming — our finding 2.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UEtvmYUBP2fDtirJGWn5MW
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 4014379@bnt-lap001
Assistant-Session: 4af9e20f-1768-4afc-951b-b507784e382b
2026-08-29 10:20:39 +02:00
|
|
|
|
|
|
|
|
|
|
if args.report:
|
2026-09-21 07:35:40 +02:00
|
|
|
|
print(f"kings-guard — layer: {governing} (declared in INTENT.md; §11 governing form)")
|
|
|
|
|
|
print(f" layer.yaml: derived from {decl['derived_from']}, layer: {decl['layer']}")
|
|
|
|
|
|
print(f" checker validated against: {VALIDATED_AGAINST}")
|
Declare layer machine-readably (§11); adopt v0.6 corrections
The standard moved v0.4 -> v0.6. All four findings from our v0.4 review
were adopted in v0.5, and v0.6 went further on two of them.
§11 now requires a machine-readable declaration — prose cannot
distinguish a declaration from a transcribed review. We had none.
Added layer.yaml (form adapted from ops-warden's reference
implementation), scripts/check_layer_conformance.py, and
tests/test_layer_conformance.py.
The check makes our central claim mechanical rather than asserted: no
direct Tooling client in src/. The test exercises the negative case on a
synthetic tree, so it fails if the checker goes blind. pyyaml is added as
a DEV dependency only — `dependencies = []` is load-bearing for the §5
claim and stays empty.
Adopted from v0.6:
- containment is no longer ours (§9.2). Actuation is an Engine concept,
unowned and held at zero; kings-guard proposes containment and never
performs it. The register row is now a dependency, not our gap.
- observation is scoped to Staff-reachable sources, with identity and
secret observation pending — our finding 1, adopted near-verbatim.
- access-engine DECLINED the authentication-evidence gap; owner is now
the identity layer plus audit-core, reproposed and unassented.
- §11 blocked-clean recorded, with the rule that it must not rank below
conforming — our finding 2.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UEtvmYUBP2fDtirJGWn5MW
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 4014379@bnt-lap001
Assistant-Session: 4af9e20f-1768-4afc-951b-b507784e382b
2026-08-29 10:20:39 +02:00
|
|
|
|
print(f" tooling contacts declared: {len(declared)}")
|
|
|
|
|
|
print(f" unowned capabilities (§11 blocked-clean): "
|
|
|
|
|
|
f"{len(decl.get('unowned_capabilities') or [])}")
|
|
|
|
|
|
today = date.today()
|
|
|
|
|
|
for cap in decl.get("unowned_capabilities") or []:
|
|
|
|
|
|
review = cap.get("review")
|
|
|
|
|
|
stale = ""
|
|
|
|
|
|
if review and date.fromisoformat(str(review)) < today:
|
|
|
|
|
|
stale = " [REVIEW OVERDUE]"
|
|
|
|
|
|
print(f" - {cap['id']}: {cap.get('owner_status', '?')}{stale}")
|
2026-09-02 00:11:57 +02:00
|
|
|
|
print(" agent-principal rule checks (§3.4):")
|
|
|
|
|
|
for name, meta in checks.items():
|
|
|
|
|
|
form = meta.get("form", "unspecified") if isinstance(meta, dict) else "unspecified"
|
|
|
|
|
|
print(f" - {name}: {form} (claimed={rules.get(name)})")
|
Declare layer machine-readably (§11); adopt v0.6 corrections
The standard moved v0.4 -> v0.6. All four findings from our v0.4 review
were adopted in v0.5, and v0.6 went further on two of them.
§11 now requires a machine-readable declaration — prose cannot
distinguish a declaration from a transcribed review. We had none.
Added layer.yaml (form adapted from ops-warden's reference
implementation), scripts/check_layer_conformance.py, and
tests/test_layer_conformance.py.
The check makes our central claim mechanical rather than asserted: no
direct Tooling client in src/. The test exercises the negative case on a
synthetic tree, so it fails if the checker goes blind. pyyaml is added as
a DEV dependency only — `dependencies = []` is load-bearing for the §5
claim and stays empty.
Adopted from v0.6:
- containment is no longer ours (§9.2). Actuation is an Engine concept,
unowned and held at zero; kings-guard proposes containment and never
performs it. The register row is now a dependency, not our gap.
- observation is scoped to Staff-reachable sources, with identity and
secret observation pending — our finding 1, adopted near-verbatim.
- access-engine DECLINED the authentication-evidence gap; owner is now
the identity layer plus audit-core, reproposed and unassented.
- §11 blocked-clean recorded, with the rule that it must not rank below
conforming — our finding 2.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UEtvmYUBP2fDtirJGWn5MW
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 4014379@bnt-lap001
Assistant-Session: 4af9e20f-1768-4afc-951b-b507784e382b
2026-08-29 10:20:39 +02:00
|
|
|
|
|
2026-09-21 09:38:27 +02:00
|
|
|
|
citations = (
|
|
|
|
|
|
a12_findings(load_intent_frontmatter(), f"{INTENT.name} frontmatter")[1]
|
|
|
|
|
|
+ a12_findings(decl, DECL.name)[1]
|
|
|
|
|
|
)
|
|
|
|
|
|
for citation in citations:
|
|
|
|
|
|
print(f"NOTE (A12 r2 reach unruled, reported not failed): {citation}")
|
|
|
|
|
|
|
2026-09-21 07:35:40 +02:00
|
|
|
|
if forms_disagree(governing, decl["layer"]):
|
|
|
|
|
|
print("", file=sys.stderr)
|
|
|
|
|
|
print("FAIL: the two declaration forms disagree (§11, A11)", file=sys.stderr)
|
|
|
|
|
|
print(f" INTENT.md (governs): layer: {governing}", file=sys.stderr)
|
|
|
|
|
|
print(f" layer.yaml (derived): layer: {decl['layer']}", file=sys.stderr)
|
|
|
|
|
|
print(" Case is already folded, so this is a real layer disagreement.", file=sys.stderr)
|
|
|
|
|
|
print(" It is a finding in its own right; precedence does not erase it.", file=sys.stderr)
|
|
|
|
|
|
return 1
|
|
|
|
|
|
|
Declare layer machine-readably (§11); adopt v0.6 corrections
The standard moved v0.4 -> v0.6. All four findings from our v0.4 review
were adopted in v0.5, and v0.6 went further on two of them.
§11 now requires a machine-readable declaration — prose cannot
distinguish a declaration from a transcribed review. We had none.
Added layer.yaml (form adapted from ops-warden's reference
implementation), scripts/check_layer_conformance.py, and
tests/test_layer_conformance.py.
The check makes our central claim mechanical rather than asserted: no
direct Tooling client in src/. The test exercises the negative case on a
synthetic tree, so it fails if the checker goes blind. pyyaml is added as
a DEV dependency only — `dependencies = []` is load-bearing for the §5
claim and stays empty.
Adopted from v0.6:
- containment is no longer ours (§9.2). Actuation is an Engine concept,
unowned and held at zero; kings-guard proposes containment and never
performs it. The register row is now a dependency, not our gap.
- observation is scoped to Staff-reachable sources, with identity and
secret observation pending — our finding 1, adopted near-verbatim.
- access-engine DECLINED the authentication-evidence gap; owner is now
the identity layer plus audit-core, reproposed and unassented.
- §11 blocked-clean recorded, with the rule that it must not rank below
conforming — our finding 2.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UEtvmYUBP2fDtirJGWn5MW
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 4014379@bnt-lap001
Assistant-Session: 4af9e20f-1768-4afc-951b-b507784e382b
2026-08-29 10:20:39 +02:00
|
|
|
|
if undeclared:
|
|
|
|
|
|
print("", file=sys.stderr)
|
|
|
|
|
|
print("FAIL: undeclared Tooling-layer client (§11 undeclared violation)", file=sys.stderr)
|
|
|
|
|
|
for path, module, what in undeclared:
|
|
|
|
|
|
rel = path.relative_to(ROOT)
|
|
|
|
|
|
print(f" {rel}: imports '{module}' — {what}", file=sys.stderr)
|
|
|
|
|
|
print("", file=sys.stderr)
|
|
|
|
|
|
print(" A Staff repository may not hold a direct Tooling client (§5).", file=sys.stderr)
|
|
|
|
|
|
print(" Route it through the owning engine, or if none exists, raise an", file=sys.stderr)
|
|
|
|
|
|
print(" engine gap — do not declare this to make the check pass.", file=sys.stderr)
|
|
|
|
|
|
return 1
|
|
|
|
|
|
|
2026-09-02 00:11:57 +02:00
|
|
|
|
if credential_hits:
|
|
|
|
|
|
print("", file=sys.stderr)
|
|
|
|
|
|
print("FAIL: standing credential material (§3.4 rule 1)", file=sys.stderr)
|
|
|
|
|
|
for path, what in credential_hits:
|
|
|
|
|
|
try:
|
|
|
|
|
|
rel = path.relative_to(ROOT)
|
|
|
|
|
|
except ValueError:
|
|
|
|
|
|
rel = path
|
|
|
|
|
|
print(f" {rel}: {what}", file=sys.stderr)
|
|
|
|
|
|
print("", file=sys.stderr)
|
|
|
|
|
|
print(" Authority is per task, time-bounded, and attributable to the", file=sys.stderr)
|
|
|
|
|
|
print(" principal acted for. Do not hold a standing secret here.", file=sys.stderr)
|
|
|
|
|
|
return 1
|
|
|
|
|
|
|
|
|
|
|
|
if rules.get("no_standing_credential") is not True:
|
|
|
|
|
|
print("FAIL: layer.yaml does not claim no_standing_credential (§3.4 rule 1)", file=sys.stderr)
|
|
|
|
|
|
return 2
|
|
|
|
|
|
|
Declare layer machine-readably (§11); adopt v0.6 corrections
The standard moved v0.4 -> v0.6. All four findings from our v0.4 review
were adopted in v0.5, and v0.6 went further on two of them.
§11 now requires a machine-readable declaration — prose cannot
distinguish a declaration from a transcribed review. We had none.
Added layer.yaml (form adapted from ops-warden's reference
implementation), scripts/check_layer_conformance.py, and
tests/test_layer_conformance.py.
The check makes our central claim mechanical rather than asserted: no
direct Tooling client in src/. The test exercises the negative case on a
synthetic tree, so it fails if the checker goes blind. pyyaml is added as
a DEV dependency only — `dependencies = []` is load-bearing for the §5
claim and stays empty.
Adopted from v0.6:
- containment is no longer ours (§9.2). Actuation is an Engine concept,
unowned and held at zero; kings-guard proposes containment and never
performs it. The register row is now a dependency, not our gap.
- observation is scoped to Staff-reachable sources, with identity and
secret observation pending — our finding 1, adopted near-verbatim.
- access-engine DECLINED the authentication-evidence gap; owner is now
the identity layer plus audit-core, reproposed and unassented.
- §11 blocked-clean recorded, with the rule that it must not rank below
conforming — our finding 2.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UEtvmYUBP2fDtirJGWn5MW
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 4014379@bnt-lap001
Assistant-Session: 4af9e20f-1768-4afc-951b-b507784e382b
2026-08-29 10:20:39 +02:00
|
|
|
|
if not args.report:
|
2026-09-02 00:11:57 +02:00
|
|
|
|
print(
|
|
|
|
|
|
f"OK: no direct Tooling client in {SRC.relative_to(ROOT)}; "
|
2026-09-21 07:35:40 +02:00
|
|
|
|
"no standing credential (§5, §11, §3.4 rule 1); "
|
2026-09-21 09:38:27 +02:00
|
|
|
|
"declaration forms agree; no standard or companion version in "
|
|
|
|
|
|
f"either form; validated against {VALIDATED_AGAINST}; scope: {SCOPE}"
|
2026-09-02 00:11:57 +02:00
|
|
|
|
)
|
Declare layer machine-readably (§11); adopt v0.6 corrections
The standard moved v0.4 -> v0.6. All four findings from our v0.4 review
were adopted in v0.5, and v0.6 went further on two of them.
§11 now requires a machine-readable declaration — prose cannot
distinguish a declaration from a transcribed review. We had none.
Added layer.yaml (form adapted from ops-warden's reference
implementation), scripts/check_layer_conformance.py, and
tests/test_layer_conformance.py.
The check makes our central claim mechanical rather than asserted: no
direct Tooling client in src/. The test exercises the negative case on a
synthetic tree, so it fails if the checker goes blind. pyyaml is added as
a DEV dependency only — `dependencies = []` is load-bearing for the §5
claim and stays empty.
Adopted from v0.6:
- containment is no longer ours (§9.2). Actuation is an Engine concept,
unowned and held at zero; kings-guard proposes containment and never
performs it. The register row is now a dependency, not our gap.
- observation is scoped to Staff-reachable sources, with identity and
secret observation pending — our finding 1, adopted near-verbatim.
- access-engine DECLINED the authentication-evidence gap; owner is now
the identity layer plus audit-core, reproposed and unassented.
- §11 blocked-clean recorded, with the rule that it must not rank below
conforming — our finding 2.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UEtvmYUBP2fDtirJGWn5MW
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 4014379@bnt-lap001
Assistant-Session: 4af9e20f-1768-4afc-951b-b507784e382b
2026-08-29 10:20:39 +02:00
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
|
raise SystemExit(main())
|