Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a126e1-76f8-7643-8cf3-e93336539ade
402 lines
20 KiB
YAML
402 lines
20 KiB
YAML
# informed-decision — NetKingdom security layer declaration (DERIVED)
|
|
#
|
|
# THIS FILE DOES NOT GOVERN. GH-DEC-2026-017 §1 (A11) rules that the `layer:`
|
|
# key in INTENT.md frontmatter IS the declaration, and that an equivalent
|
|
# declaration file is a DERIVED ARTIFACT which must be marked as derived, must
|
|
# name INTENT.md as what it derives from, and must agree with it. §11 already
|
|
# said a repository declares its layer in its own INTENT.md; the file form was
|
|
# added to give the declaration a machine-readable shape, not a second
|
|
# authority.
|
|
#
|
|
# A disagreement between the two forms is a finding in its own right and must be
|
|
# reported rather than resolved away by precedence. There is none here: both
|
|
# files carried `surface` in the same casing before the ruling and both carry
|
|
# `Staff` after it, changed in one commit.
|
|
#
|
|
# Framework: net-kingdom/canon/standards/ — the body, UNVERSIONED on purpose.
|
|
# Companion: net-kingdom/SECURITY-COMPANION.md
|
|
# Voice: INTENT.md (this repository's own, per §11 "who must declare")
|
|
# Rulings: GH-DEC-2026-012 (INFD-IN-0001) — the shape
|
|
# GH-DEC-2026-017 (INFD-IN-0006) — the layer value, the form, the version
|
|
#
|
|
# Reference form: ops-warden's, adopted by audit-core and kings-guard, with
|
|
# kings-guard's adaptation for a repository with no Tooling contacts. ops-warden
|
|
# owns that form and is updating it for GH-DEC-2026-017 §1 and §5 in a parallel
|
|
# session; this file applies the two RULED properties (derived marking, absence
|
|
# of a standard version) and follows ops-warden's shape for everything else
|
|
# rather than inventing one.
|
|
|
|
schema_version: "0.1"
|
|
framework: netkingdom-security-layer-model
|
|
repository: informed-decision
|
|
|
|
# §11 derived-artifact rule + GH-DEC-2026-017 §1.
|
|
derived: true
|
|
derives_from: INTENT.md
|
|
derives_from_note: >-
|
|
INTENT.md frontmatter governs. This file is regenerated from it by hand and
|
|
changes in the same commit, so it is derived at the same commit by
|
|
construction; if the two ever disagree, INTENT.md is this repository's answer
|
|
and the disagreement is itself a finding.
|
|
|
|
# NO standard_version, and no companion_version — GH-DEC-2026-017 §5 (A12).
|
|
# A layer declaration asserts a STANDING property: which layer this repository
|
|
# is. That does not change when the standard is revised, and a version here
|
|
# makes every revision read as though it invalidated the declaration. The field
|
|
# was flagged by this repository on 2026-09-21 and by access-engine in its own
|
|
# file; the ruling removes it estate-wide from ops-warden's reference form.
|
|
# Version-scoped state belongs in the derived conformance record, which must
|
|
# carry the version it was derived at. `companion_version` is removed on the
|
|
# same reasoning; it is a version pin in a declaration and nothing in the
|
|
# ruling's argument distinguishes it. Raised with ops-warden as part of the
|
|
# reference-form update rather than decided here for the estate.
|
|
|
|
# §3 vocabulary — RULED CLOSED, value corrected 2026-09-21 (INFD-IN-0006).
|
|
#
|
|
# GH-DEC-2026-017 §3: the §3 vocabulary is CLOSED and has four tokens —
|
|
# Taxonomy, Tooling, Engine, Staff. Comparison is ASCII case-insensitive (§2 /
|
|
# A9), so no repository is asked to re-spell anything. `surface` is not among
|
|
# them: "surface is not a layer... Its correct declaration is layer: Staff, role:
|
|
# pep-shaped, which its own file already reasons from two ways." ops-mason and
|
|
# ops-warden are the precedent: Staff in the layer column, PEP-shaped in the
|
|
# role column.
|
|
#
|
|
# Changed the same day the ruling was received, in one commit, with no argument
|
|
# — exactly as this repository pre-committed in
|
|
# docs/gate-house-decision-request-layer-vocabulary.md §3. `role: pep-shaped` is
|
|
# untouched and was already right; a role is not a layer (GH-DEC-2026-012 R2,
|
|
# restated by GH-DEC-2026-017 §3 for the declaration field).
|
|
layer: Staff
|
|
role: pep-shaped
|
|
declared_by: INTENT.md
|
|
declared_at: "2026-09-09" # the declaration; the VALUE was corrected 2026-09-21
|
|
value_corrected_at: "2026-09-21"
|
|
ruling: GH-DEC-2026-017
|
|
shape_ruling: GH-DEC-2026-012
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# HISTORY — why `surface` was written. KEPT ON PURPOSE, not erased.
|
|
#
|
|
# GH-DEC-2026-017 §3's reversal condition names this reasoning directly, so it
|
|
# has to remain readable: "§3's closure reverses on an argued amendment to §3,
|
|
# from a repository that bears a cost under the four-layer cut."
|
|
#
|
|
# From 2026-09-09 (commit f6376dd) to 2026-09-21 this file and INTENT.md both
|
|
# declared `layer: surface`, in the same casing, meaning the
|
|
# presentation-and-binding tier: the runtime a human touches, where a decision
|
|
# rendered elsewhere is shown to a named person, that person binds their
|
|
# identity to the act, and the evidence that the presentation happened is
|
|
# produced.
|
|
#
|
|
# It was chosen by ELIMINATION, not casually. GH-DEC-2026-012 R1 ruled this
|
|
# repository out of Engine and left the layer to it to declare, and each
|
|
# remaining §3 value was read as false of it:
|
|
# - not Staff — deterministic by construction (the same approval rendered to
|
|
# the same principal in the same role yields the same
|
|
# view_hash, asserted by test), and holding state audit-core
|
|
# depends on at runtime, which §3.4 forbids Staff;
|
|
# - not Tooling — persists nothing another layer reads;
|
|
# - not Taxonomy— nothing but a runtime position.
|
|
# Faced with picking a value it believed false or writing the true word and
|
|
# carrying the finding, this repository wrote the word and asked for a ruling.
|
|
# It did not ask for §3 to be amended in its favour, and it does not now.
|
|
#
|
|
# The ruling reaches Staff by the same elimination from the other end — not an
|
|
# Engine, and nothing else in the four is true, so Staff — and gives the value,
|
|
# which is what was asked for and what binds. The part of the elimination above
|
|
# that the ruling does not address is recorded as INFD-IN-0007 below. It is a
|
|
# question, not a reservation: the value is applied unconditionally.
|
|
#
|
|
# Request: docs/gate-house-decision-request-layer-vocabulary.md
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# OPEN, non-blocking — INFD-IN-0007.
|
|
#
|
|
# §3.4 defines Staff as interactive and non-deterministic, working through
|
|
# agentic capability, and says Staff repositories MUST NOT hold state that
|
|
# another layer depends on at runtime. This repository is deterministic by test,
|
|
# forbids an agent from completing its protected act at all, and holds
|
|
# presentation evidence audit-core depends on. It is Staff by ruling and the
|
|
# declaration above says so. What is not yet written down is how §3's
|
|
# determinism cut reaches a deterministic, non-agentic, evidence-holding
|
|
# repository — the derivation this repository asked for as a non-condition, and
|
|
# which the ruling answers as far as the VALUE and not as far as the FIT.
|
|
# Asked once more of gate-house; no deadline, no dependency, nothing waits on it.
|
|
section_3_4_fit:
|
|
status: carried-tension
|
|
intake: INFD-IN-0007
|
|
blocks_nothing: true
|
|
bounded_doctrine_response: GH-DEC-2026-025
|
|
accepted_standard_voice: pending-NET-IN-0004
|
|
tension_resolved: false
|
|
note: >-
|
|
The bounded founder disposition answers the doctrine question by carrying
|
|
the tension explicitly. It grants no conformance or Engine-state exception.
|
|
Accepted successor standard voice/publication remains pending.
|
|
|
|
# §4 catalog membership — ASKED by GH-DEC-2026-017 §4, ANSWERED here.
|
|
#
|
|
# gate-house deliberately did not enrol this repository: adding a row is a canon
|
|
# change, and §11's own rule — a layer stated ABOUT a repository BY another is
|
|
# not a declaration — applies to catalogue membership at least as strongly. The
|
|
# question was put, not decided. This repository's answer is YES, with the
|
|
# obligation that comes with it accepted rather than negotiated.
|
|
#
|
|
# Full argument: docs/section-4-catalog-row.md. Carried by gate-house as
|
|
# GH-WP-0004-T06.
|
|
catalog:
|
|
section_4_row_today: false
|
|
declared_voluntarily: true
|
|
scope_report: declared-voluntarily-outside-catalog-scope
|
|
requested: true
|
|
requested_at: "2026-09-21"
|
|
requested_row:
|
|
repository: informed-decision
|
|
layer: Staff
|
|
role: pep-shaped
|
|
evidence_source: "yes"
|
|
accepts_emission_guarantee: true
|
|
note: >-
|
|
Until the row exists, §11 does not bind this repository and a run that
|
|
grades it is over-scoped (GH-DEC-2026-017 §4). That is the reason to ask for
|
|
the row, not a reason to avoid it: this repository's presentation evidence
|
|
is the only record of what a human was shown before binding, and an evidence
|
|
obligation nobody is allowed to check is the weaker position.
|
|
|
|
# §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: nesting
|
|
linkage_rule: >-
|
|
view_hash CARRIES approval-engine's binding.digest as a field. That digest
|
|
is referenced, never recomputed or restated from this repository's own
|
|
vocabulary, and the act-scope is no longer independently canonicalized here
|
|
— so the act has exactly one canonicalization, computed by the layer that
|
|
owns it.
|
|
# GH-DEC-2026-015 (INFD-IN-0004) re-ruled: nesting is PERMITTED for this pair,
|
|
# conditioned on approval-engine stating its presentation exclusion as
|
|
# NORMATIVE and TESTED rather than design intent.
|
|
#
|
|
# ACTIVATED 2026-09-10, after verifying the condition here rather than taking
|
|
# it on report: approval-engine/docs/approval-claim.md carries "Presentation
|
|
# exclusion — GH-DEC-2026-015 §4" in normative language, and
|
|
# tests/test_claim_contract.py::test_presentation_changes_cannot_change_the_approved_act
|
|
# pins the input set from BOTH sides — widening (presentation material leaves
|
|
# the digest unchanged) and narrowing (each of the five act fields changes it).
|
|
# The narrowing half matters: without it a digest over four fields, or over a
|
|
# constant, would pass the widening half perfectly. Run and confirmed passing.
|
|
reruled_by: GH-DEC-2026-015
|
|
nesting_permitted_when: >-
|
|
approval-engine states the presentation exclusion from binding.digest as
|
|
normative and tested.
|
|
nesting_permission_active: true
|
|
nesting_activated_at: "2026-09-10"
|
|
nesting_condition_evidence:
|
|
doc: approval-engine/docs/approval-claim.md#presentation-exclusion
|
|
test: tests/test_claim_contract.py::test_presentation_changes_cannot_change_the_approved_act
|
|
evidence_record: approval-engine/docs/evidence/2026-09-10-presentation-exclusion.json
|
|
# OPEN, raised with approval-engine rather than assumed. Their `principal` is
|
|
# the party ON WHOSE BEHALF the approval was issued; ours is the person being
|
|
# BOUND — the approver. Different roles, so this repository still commits its
|
|
# own principal in view_hash. Dropping it would remove *who was shown this*
|
|
# and gut the promise. If the two are the same field, ours drops too.
|
|
principal_role_overlap: open
|
|
# The cycle condition remains the thing to protect, and it is now protected by
|
|
# approval-engine's normative exclusion rather than by refusing nesting.
|
|
cycle_condition: >-
|
|
Mutual containment. view_hash carries binding.digest; binding.digest MUST
|
|
NOT cover presentation material, so containment stays one-directional and
|
|
the GH-DEC-2026-008 cycle cannot arise. If that exclusion is ever relaxed,
|
|
this linkage must be revisited before the widening ships — a fail-closed
|
|
consumer obeying a cyclic claim denies permanently.
|
|
|
|
# §5 applies to Staff, and this repository is now Staff by ruling — so the line
|
|
# below is the §11 mechanical check landing on it directly rather than by
|
|
# analogy. It is a browser-facing surface with no Tooling contact, so the check
|
|
# is total with an empty map and this repository is CONFORMING on §5, not
|
|
# blocked-clean and not a declared gap.
|
|
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
|
|
# A10 (GH-DEC-2026-018 §5) — emission is marked, never inferred. This
|
|
# repository EMITS into the estate's evidence stream; audit-core holds
|
|
# custody, which is disjoint from emission and discharges nothing of this
|
|
# emitter's guarantee.
|
|
emission_guarantee_owed: true
|
|
event_classes:
|
|
- id: presentation
|
|
kind: load-bearing
|
|
classification: volume
|
|
note: >-
|
|
One per render. Classified volume by this repository, which is the
|
|
classification a conformance run is SUPPLIED and MUST NOT infer.
|
|
- id: disposition
|
|
kind: load-bearing
|
|
classification: rare
|
|
note: >-
|
|
The binding act. Rare and security-relevant: heartbeat AND
|
|
reconciliation, never rate monitoring alone — a quiet month of
|
|
dispositions is indistinguishable from suppression by rate.
|
|
- id: stance-application
|
|
kind: load-bearing
|
|
classification: rare
|
|
note: Fail-closed stance applied at a binding attempt. Same form as disposition.
|
|
emission_guarantee_status: not-yet-declarable
|
|
emission_guarantee_blocked_on: >-
|
|
Current source implements transactional recording/outbox, 86400-second
|
|
per-class heartbeats, 30-second pump ticks and 300-second reconciliation.
|
|
Original AUDIT-WP-0009/outbox pointers are historical, not current verified
|
|
blockers. Full source class-specific declaration and native verification
|
|
remain owed: time-basis-aware reconciliation/detection/monitoring and
|
|
per-target rare-class heartbeat receipts are not established by retained
|
|
aggregate counts. See INFD-IN-0009; no residual implementation is promoted.
|
|
completeness_claimed: false
|
|
reconciliation_review: docs/evidence/2026-10-11-staff-evidence-source-reconciliation.md
|
|
residual_source_record: INFD-IN-0009
|
|
mechanism_inventory:
|
|
local_record_and_outbox: implemented-transactionally
|
|
heartbeat_seconds_per_declared_class: 86400
|
|
audit_pump_tick_seconds: 30
|
|
reconciliation_tick_seconds: 300
|
|
reconciliation_source_time_basis: occurred_at
|
|
reconciliation_receiver_time_basis: accepted_at
|
|
automatic_loss_finding: false
|
|
operating_full_class_guarantee_verified: false
|
|
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": []
|