Declare the layer per GH-DEC-2026-012; close T02
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
This commit is contained in:
parent
f36e2b789a
commit
f6376ddff5
9 changed files with 614 additions and 20 deletions
110
pep-stance.yaml
Normal file
110
pep-stance.yaml
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
# 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.
|
||||
Loading…
Add table
Add a link
Reference in a new issue