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
110 lines
5.1 KiB
YAML
110 lines
5.1 KiB
YAML
# informed-decision — PEP unreachable-engine stance map
|
|
#
|
|
# Framework: net-kingdom/canon/standards/security-layer-model_v0.7.md §6.4, §9.3, §9.7
|
|
# Built to: v0.8 obligation 3 (GH-DEC-2026-011), not v0.7 — per GH-DEC-2026-012,
|
|
# so this is built to rather than migrated to.
|
|
# Ruling: GH-DEC-2026-012
|
|
# Validate: pytest tests/test_layer_conformance.py
|
|
#
|
|
# §6.4 obligation 3 requires a declared unreachable-engine stance that is total,
|
|
# scoped per zone, carries no implicit default and no per-call discretion, and is
|
|
# published rather than held in code comments. A map that lives only in a module
|
|
# default is not published — it is merely written down.
|
|
#
|
|
# The property that makes this worth reading: it is asserted equal to the shipped
|
|
# map in informed_decision/stance.py by tests/test_layer_conformance.py. A
|
|
# published map that may drift from the code is worse than none, because it
|
|
# invites reliance it cannot support.
|
|
|
|
schema_version: "0.1"
|
|
framework: netkingdom-security-layer-model
|
|
standard_version: "0.7"
|
|
built_to_obligation_3_of: "0.8"
|
|
repository: informed-decision
|
|
pep_shape: true
|
|
declared_by: layer.yaml
|
|
ruling: GH-DEC-2026-012
|
|
|
|
protected_action: "Approver entry recorded against an approval object"
|
|
decision_engine: access-engine
|
|
|
|
# v0.8 obligation 3: the map MUST enumerate its axis rather than lean on a
|
|
# catch-all. The axis here is the memo's binding_level — this repository's own
|
|
# graded property, and the one that determines how costly a wrong bind is.
|
|
axis: binding_level
|
|
axis_source: decision-memo.schema.json#/properties/binding_level
|
|
|
|
# Total by enumeration, not by catch-all. Every value of the axis appears
|
|
# explicitly, plus the two non-value outcomes required to be distinguishable.
|
|
#
|
|
# Every stance is fail_closed, and that is a conclusion rather than a shortcut.
|
|
# ops-warden can justify fail_open on some zones because refusing removes
|
|
# production host access to close a documentation gap — a continuity argument.
|
|
# No such argument exists here. Refusing to render or to bind delays a decision;
|
|
# it does not remove a capability anyone depends on to keep a system running.
|
|
# Binding a human's identity to an act without an authorization decision is the
|
|
# precise failure this repository exists to prevent, so there is no level at
|
|
# which proceeding-without-a-decision is the safer error.
|
|
stance:
|
|
acknowledgment: fail_closed
|
|
organizational: fail_closed
|
|
aes: fail_closed
|
|
qes: fail_closed
|
|
unknown: fail_closed # v0.8 obligation 3: unknown MUST resolve to fail_closed
|
|
absent: fail_closed # distinct from unknown in the record — see below
|
|
|
|
# v0.8 obligation 3 requires an absent scope to be DISTINGUISHABLE in the record
|
|
# from an unknown one. They resolve to the same stance here but must never be
|
|
# recorded as the same fact:
|
|
# absent — the memo carried no binding_level at all (a defect in the memo)
|
|
# unknown — a binding_level was present but is not a value this map enumerates
|
|
# (a version skew between memo and this map)
|
|
# Collapsing them would hide a schema-drift incident inside a malformed-input
|
|
# statistic.
|
|
scope_absence:
|
|
distinguishable: true
|
|
recorded_as:
|
|
absent: "binding_level.absent"
|
|
unknown: "binding_level.unknown"
|
|
|
|
# §6.4 obligation 1 requires a decision record for a protected side effect.
|
|
# Where the engine is unreachable there is no decision to hold, so this surface
|
|
# records the APPLICATION OF THE STANCE instead.
|
|
on_apply:
|
|
recorded_fields:
|
|
- memo_id
|
|
- memo_version
|
|
- binding_level
|
|
- binding_level_state # present | absent | unknown
|
|
- stance_applied
|
|
- decision_id # only where a decision was actually rendered
|
|
- decision_attributable # see inherited gap below
|
|
- presentation_id
|
|
user_visible: >-
|
|
The approver is told the act could not be authorized and that nothing was
|
|
bound. The surface never presents a fail_closed outcome as a decline by the
|
|
approver: no disposition is recorded, because the human did not make one.
|
|
|
|
# GH-DEC-2026-010, inherited. Obligation 1 requires a decision be ATTRIBUTABLE to
|
|
# access-engine, and no consumer can satisfy that today — flex-auth's envelope is
|
|
# unsigned (declared §13 gap, FLEX-WP-0024). `decision_attributable` is therefore
|
|
# recorded as false and MUST NOT be reported as satisfied while that is open.
|
|
inherited_gap:
|
|
id: GH-DEC-2026-010-attributability
|
|
decision_attributable_today: false
|
|
tracked_by: FLEX-WP-0024
|
|
|
|
# §13.1 / GH-DEC-2026-011 — a dated classification-coverage figure beside the
|
|
# stance. Honest figure for a repository at spec stage: the axis is fully
|
|
# enumerated against the schema, and no protected action has shipped yet.
|
|
classification_coverage:
|
|
as_of: "2026-09-09"
|
|
axis_values_enumerated: 4
|
|
axis_values_in_schema: 4
|
|
coverage: "4/4 (100%) of binding_level values enumerated"
|
|
protected_actions_shipped: 0
|
|
note: >-
|
|
Coverage is complete against the schema, not against production behaviour:
|
|
nothing is deployed. Re-date this figure when the walking skeleton
|
|
(INFD-WP-0001-T08) ships, and treat a coverage figure that predates a schema
|
|
change as stale.
|