Gate House ruled all three questions within a day, attributing the speed to the request being filed before the architecture with candidate answers and their costs. R1 PEP-shaped, confirmed as proposed. The ruling settles the shape; the layer stays ours to declare, so layer.yaml is written in this repository's voice rather than transcribed from the reply. R2 yes to a presentation claim, no second catalog row, under three limits now declared in layer.yaml and tested. Limit 2 — the claim must never be an input to the decision it presents for — is load-bearing: our self-dealing argument was accepted because it holds, not despite it. Limit 3 drives architecture, since here the actor being audited and the evidence source are the same component. R3 (b) with the authority rule: binding digest authoritative for what the request is, view_hash only for what was shown, neither substitutable, and a disagreement between them is a finding against the presenting surface rather than a fact about the request. Linkage is co-reference; nesting was refused because it reproduces the GH-DEC-2026-008 hash cycle. Built to v0.8 obligation 3 rather than migrating later: axis enumerated, unknown resolves to fail_closed, absent distinguishable from unknown in the record, and published-equals-shipped asserted by test rather than claimed. Every stance is fail_closed, which is a conclusion not a shortcut — ops-warden can justify fail_open on a continuity argument that does not exist here. GH-DEC-2026-010 inherited as a declared gap in four documents: a decision cannot today be proven to have come from access-engine. The decision path must not be described as validated while FLEX-WP-0024 is open. 46 tests pass. T05 and T07 unblocked. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V3W1dQG7GFFM9d94jFx7iR Assistant: claude-code Assistant-Model: opus Assistant-Process: 1565372@bnt-lap001 Assistant-Session: 16bb2f25-b34c-49ef-8e94-5fec3567a568
184 lines
7.9 KiB
YAML
184 lines
7.9 KiB
YAML
# informed-decision — NetKingdom security layer declaration
|
|
#
|
|
# Framework: net-kingdom/canon/standards/security-layer-model_v0.7.md
|
|
# Companion: net-kingdom/SECURITY-COMPANION.md v0.2
|
|
# Voice: INTENT.md (this repository's own, per §11 "who must declare")
|
|
# Ruling: GH-DEC-2026-012 (gate-house@0a1d1d9) answered INFD-IN-0001
|
|
#
|
|
# Reference form: ops-warden's, adopted by audit-core and kings-guard, with
|
|
# kings-guard's adaptation for a repository with no Tooling contacts.
|
|
#
|
|
# GH-DEC-2026-012 R1 confirmed the SHAPE. The layer is declared here, in this
|
|
# repository's own voice, because a layer someone else states about you is not
|
|
# a declaration.
|
|
|
|
schema_version: "0.1"
|
|
framework: netkingdom-security-layer-model
|
|
standard_version: "0.7"
|
|
companion_version: "0.2"
|
|
repository: informed-decision
|
|
layer: surface
|
|
role: pep-shaped
|
|
declared_by: INTENT.md
|
|
declared_at: "2026-09-09"
|
|
ruling: GH-DEC-2026-012
|
|
|
|
# §6.4 — informed-decision is PEP-shaped: it causes a protected side effect on
|
|
# the far side of a decision (recording an approver entry against an approval
|
|
# object). Companion §5 is owed and §6.4 applies in full.
|
|
#
|
|
# Built to v0.8 obligation 3, not v0.7, per GH-DEC-2026-011 — see pep-stance.yaml.
|
|
pep_stance: pep-stance.yaml
|
|
|
|
protected_action: "Approver entry recorded against an approval object (POST /v1/approvals/{id}/entries)"
|
|
decision_engine: access-engine
|
|
|
|
# §6 — no repository other than access-engine exposes an authorization decision.
|
|
# This surface renders a question and records a human's answer. A disposition is
|
|
# evidence of an act, never a verdict.
|
|
decision_surfaces_exposed: none
|
|
|
|
# §3.3 / GH-DEC-2026-012 R2 — YES to a presentation claim, and NO second catalog
|
|
# row: PEP and PIP are shapes a repository has; §4 records the layers it
|
|
# occupies. The permission carries three limits, and they are the substance of
|
|
# it rather than caveats on it.
|
|
presentation_claim:
|
|
emitted: true
|
|
carries: presentation-only
|
|
limits:
|
|
- id: L1-presentation-only
|
|
rule: >-
|
|
The claim carries presentation and nothing else. It MUST NOT carry,
|
|
restate, summarise or imply the decision, the verdict, or whether the
|
|
act was permitted. A consumer learns from it only what was SHOWN, never
|
|
what was DECIDED.
|
|
- id: L2-not-an-input
|
|
rule: >-
|
|
The claim MUST NOT be an input to the decision it presents for. A policy
|
|
reading view_hash to decide whether an act is permitted would let the
|
|
presenting surface contribute to its own authorization.
|
|
note: >-
|
|
Load-bearing, not a formality. GH-DEC-2026-012 accepted this
|
|
repository's argument that a renderer attesting its own rendering is not
|
|
the self-dealing that kept the approval object out of access-engine —
|
|
but only because this limit holds. Without it the two collapse into the
|
|
same failure.
|
|
- id: L3-independent-evidence-path
|
|
rule: >-
|
|
The evidence copy reaches audit-core INDEPENDENTLY of this repository.
|
|
The claim endpoint and the evidence path are different things and
|
|
neither substitutes for the other. The copy that is evidence MUST NOT be
|
|
reachable only through the party it is evidence about.
|
|
note: >-
|
|
The limit that matters most here: audit evidence is protected from the
|
|
actor being audited, and in this component the actor and the source are
|
|
the same. Architecture consequence, tracked in
|
|
docs/specs/ArchitectureBlueprint.md.
|
|
|
|
# §17 — the shared request-claim schema is still unowned. This repository
|
|
# publishes at its own boundary and yields to that schema when it exists.
|
|
# Position accepted by GH-DEC-2026-012 and matching approval-engine's in
|
|
# APPROVAL-IN-0001.
|
|
request_claim_schema:
|
|
status: unowned-upstream
|
|
local_shape: published-at-own-boundary
|
|
yields_to: taxonomy-request-claim-schema
|
|
|
|
# GH-DEC-2026-012 R3 — (b), with the authority rule written down.
|
|
binding_digest_relationship:
|
|
ruling: GH-DEC-2026-012
|
|
view_hash_authoritative_for: what-was-shown
|
|
binding_digest_authoritative_for: what-the-request-is
|
|
binding_digest_owner: approval-engine
|
|
substitutable: false
|
|
disagreement_is: >-
|
|
A finding against the presenting surface, never a fact about the request.
|
|
linkage: co-reference
|
|
linkage_rule: >-
|
|
The presentation record carries the approval or binding identifier
|
|
explicitly, and both attestations are read against that one reference. This
|
|
repository MUST NOT recompute or restate approval-engine's binding digest
|
|
from its own vocabulary — it references the digest that layer computed and
|
|
recorded.
|
|
nesting_forbidden: >-
|
|
view_hash MUST NOT contain the binding digest, and MUST NOT travel inside
|
|
hashed request material while containing it. Option (c) was refused because
|
|
nesting reproduces the hash cycle that made GH-DEC-2026-008 unimplementable:
|
|
a claim required to name the digest of a request that would come to contain
|
|
it, where a fail-closed consumer denies permanently.
|
|
|
|
# §5 applies to Staff. This is a browser-facing surface with no Tooling contact.
|
|
tooling_contacts: []
|
|
|
|
# §11 — record non-Tooling clients so the check is total.
|
|
non_tooling_clients: []
|
|
|
|
intended_non_tooling_clients:
|
|
- target: approval-engine
|
|
layer: engine
|
|
rationale: >-
|
|
GET /v1/approvals/{id} and /claim (approval:read) to render; POST
|
|
/v1/approvals/{id}/entries (approval:approve) to record a binding. Never
|
|
/consume. Requirements: approval-engine/docs/approver-surface-requirements.md.
|
|
- target: access-engine
|
|
layer: engine
|
|
rationale: >-
|
|
Decision consumed before rendering an approval to a person. A 200 from
|
|
approval-engine is not entitlement. This surface consumes a decision and
|
|
never renders one.
|
|
- target: key-cape
|
|
layer: engine
|
|
rationale: >-
|
|
Identity. Authorization-code + PKCE browser client. Identity is imported,
|
|
never invented here.
|
|
- target: audit-core
|
|
layer: engine
|
|
rationale: >-
|
|
Evidence destination for presentation records and dispositions. Must be an
|
|
independent path per limit L3-independent-evidence-path.
|
|
- target: state-hub
|
|
layer: not-catalogued
|
|
rationale: >-
|
|
Progress events. Outside §5 by the v0.5 scope rule. Recorded, not policed.
|
|
|
|
# §9.6 — presentation evidence is load-bearing: it is the only record of what a
|
|
# human was shown before binding. Atomicity and attestation cover accident and
|
|
# later tampering, never a compromised source.
|
|
evidence:
|
|
kind: load-bearing
|
|
residual: compromised-surface-presents-x-attests-y
|
|
residual_closed: false
|
|
custody: same-bound-as-every-other-source # §16 decided: no stronger archive
|
|
note: >-
|
|
GH-DEC-2026-012 states the residual is not closed in those words, and this
|
|
repository is not credited with closing it. Same disposition as
|
|
approval-engine's equivalent residual for adversarial omission at a
|
|
compromised source.
|
|
|
|
# INHERITED DECLARED GAP — GH-DEC-2026-010.
|
|
#
|
|
# Obligation 1 now requires a decision be ATTRIBUTABLE to access-engine. No
|
|
# consumer can satisfy that today: flex-auth's decision envelope is unsigned.
|
|
# This is a declared §13 gap tracked as FLEX-WP-0024, not a clean path this
|
|
# repository can walk.
|
|
#
|
|
# Stated here, and in SCOPE.md and ArchitectureBlueprint.md, because
|
|
# GH-DEC-2026-012 requires it be said in this repository's own documents rather
|
|
# than describing validation as complete.
|
|
inherited_gaps:
|
|
- id: GH-DEC-2026-010-attributability
|
|
obligation: 1
|
|
gap: >-
|
|
A decision consumed from access-engine cannot today be proven to have come
|
|
from access-engine — the envelope is unsigned.
|
|
tracked_by: FLEX-WP-0024
|
|
consequence_here: >-
|
|
This surface's record can show that a decision was obtained and what it
|
|
said. It cannot yet show it was access-engine that said it. Validation of
|
|
the decision path MUST NOT be described as complete while this is open.
|
|
status: open
|
|
|
|
declared_shapes:
|
|
"5.1": []
|
|
"5.2": []
|
|
"5.3": []
|