# 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.