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
15 KiB
| project | product | status | intent_version | date | domain | topic_slug | layer | role | standard | companion |
|---|---|---|---|---|---|---|---|---|---|---|
| informed-decision | Informed Decision | draft | 0.1.0 | 2026-09-09 | infotech | netkingdom | surface | pep-shaped | net-kingdom/canon/standards/security-layer-model_v0.7.md | net-kingdom/SECURITY-COMPANION.md |
INTENT
This file captures why this repository exists and the kind of system it is meant to become. It is aspirational and stable, not a description of current implementation. Implemented boundary belongs in
SCOPE.md; the current stage belongs inGOAL.md; current work belongs inworkplans/.
Purpose
informed-decision owns the surface on which a human is shown a decision and binds their identity to it — and owns the evidence that the presentation actually happened.
It answers one question, totally and decidably:
What was this person shown, in what role, at the moment they bound themselves to this act — and can that be proven afterwards?
Nothing else. It does not decide whether the act is permitted (access-engine),
does not own the approval object (approval-engine), does not author the
doctrine that requires an approval (gate-house), does not authenticate the
person (key-cape), and does not archive the trail (audit-core).
Why This Exists
Every layer of the NetKingdom estate has an owner except the one a human actually touches.
approval-engine's INTENT.md names it under Non-Goals, twice and
deliberately: "Not a workflow or ticketing system", "Not an approvals inbox
or notification surface." That exclusion is correct — an engine that renders
its own object is self-dealing — but it leaves a hole, and the hole is now
load-bearing:
approval-engineis a bearer-token resource server with no Ingress, no redirect endpoint and no browser client (deploy/approval-engine.yaml: Namespace + ClusterIP + StatefulSet).key-cape(KEY-WP-0013-T02) asked approval-engine for the human approver client'sclient_idand callback URI on 2026-09-08.- approval-engine correctly refused to invent them, recording in
docs/keycape-service-registrations.md: "The human approver flow therefore belongs to whichever browser-facing approver UI presentsapproval:approvetokens to this engine. That component is not in this repo."
So the approver UI is not merely missing. It is a named, unassigned dependency that currently blocks an OIDC client registration in another repository. This repository claims it.
The claim is not opportunistic. The founding exploration
(history/20260909-initial-exploration/) arrived at the same object from the
opposite direction — the German Umlaufmappe / Zeichnungsbuch, a portable
decision object that carries a question, the context needed to answer it, the
requested act, and a cryptographic binding between identity, what was shown,
and what was bound. That is exactly the artifact the estate is missing, and it
generalizes past approvals without ever becoming a decision point.
The Concept — the Decision Memo
A Decision Memo is a portable object presented to one human who holds a mandate. It carries:
- a question that must be answered, and a requested act;
- the brief and consequences a reasonable decision-maker needs;
- a packet of hashed documents and highlights pointing into it;
- a binding slice — the identity and scope being committed, which is signed;
- an awareness slice — orientation (proposed role, other roles, other tenants, last session), which is shown and hashed but not signed;
- a route (
Zeichnungsleiste), a thread, and a record of every presentation and disposition; - an append-only evidence chain.
Two hashes are computed over every presentation:
| Hash | Over | Signed? |
|---|---|---|
view_hash |
the binding document | yes, from organizational level up |
awareness_hash |
the awareness document | no, unless a field was promoted |
view_hash is the mechanism. It is what turns "the file was signed" into
"this person, in this role, was shown this view, and bound this act."
Scale Invariance Is the Thesis
One object model, one evidence model, one UX grammar, from a ten-second login to a multi-party instrument:
| Level | Act | Typical binding |
|---|---|---|
| L0 | Informed login / session | acknowledgment / organizational |
| L1 | Privileged authorization (JIT elevation) | organizational |
| L2 | Formal ADR / decision-record accept | organizational / AES |
| L3 | Management approval | organizational / AES |
| L4 | Contract / instrument | AES / QES |
| L5 | Multi-party international instrument | QES per party (horizon, not v1) |
If L0 and L3 share the schema, the transitions, and the two hashes, the thesis holds. If they fork, it does not — and the estate has bought a bespoke approvals inbox instead of a decision surface.
The approval approver UI is L3. It is the first stage precisely because it is a real consumer with a real blocking dependency, not a demo.
The Disposition Vocabulary
The differentiator is not another workflow engine. It is that approve/reject is the wrong vocabulary for judgment. The verbs are:
comment · discuss (Rücksprache) · return for improvement (Rückgabe) ·
forward · escalate · acknowledge (Kenntnisnahme) · accept
(Mitzeichnung / Schlusszeichnung) · decline · withdraw · configure
accept on a Kenntnisnahme step is illegal on purpose. Return is success,
not failure — a memo sent back for improvement is the surface working.
What informed-decision Owns
- the Decision Memo object, its versions, and its lifecycle;
- the presentation record — what was rendered, to whom, when, in which locale and UI release;
- canonicalization of the binding and awareness documents, and the
computation of
view_hash/awareness_hash; - highlight acknowledgment — required highlights acked before a bind is permitted;
- the disposition vocabulary and its legality tables;
- the evidence bundle as an export — the reconstructable answer to who decided what, having seen what;
- the browser-facing OIDC client for human principals, including the
client_idand callback URI thatkey-capeis waiting for; - the pre-sign / post-sign split: identity and bind-scope are committed; hats, last-used role, and other-tenant orientation are awareness unless explicitly promoted.
What informed-decision Does Not Own
- the decision —
access-engine, always and only (statute §6). This repository renders a question and records an answer; it never evaluates whether an actor may do a thing; - the approval object —
approval-engine. This surface calls that engine's mutations with anapproval:approve-scoped token; it never holds approval current-state and never answers "is this approval valid"; - approval doctrine — which acts need approval, how many approvers, which
separations of duty —
gate-house; - identity and authentication —
key-cape. Identity is imported (OIDC, passkeys, eID, EUDI Wallet, QTSP), never invented here; - the evidence archive —
audit-core. This repository emits and exports; the trail is held there; - credentials materialized after a decision —
secrets-engine; - notification transport — a memo may be announced by other means; the dialogue stays on the object.
Design Principles
- One object, many depths. Login and instrument share a schema.
- Presentation is part of the signed payload. Dynamic linking, not a signature over a file nobody read.
- Competence before convenience. Routing follows mandate.
- Return is success.
- Dialogue stays on the object. Side-channel email is an anti-pattern.
- Binding level is explicit. Kenntnisnahme ≠ Mitzeichnung ≠ QES.
- Evidence is an export, not a screenshot.
- Least privilege of attention. Highlights first, full packet available, no dark patterns — and the UI must make unmistakable that the whole instrument is bound, not only the highlights.
- Identity is imported.
- Humans bind, agents draft. An agent may assemble a memo. It may never complete the binding act on the principal's surface.
- Awareness is not consent. Defaulting a role to last-used is required
for situational awareness and forbidden from silently entering
view_hash. - Informedness without surveillance. Evidence is the hash of the presented view plus explicit highlight acknowledgment — never keystroke analytics, dwell timers, or attention theater.
Layer Placement — Ruled
PEP-shaped, confirmed by GH-DEC-2026-012 (answering INFD-IN-0001).
Not an Engine: this repository holds no state another layer reads at runtime for
a verdict, and renders no decision. Companion §5 is owed and statute §6.4
applies in full. The declaration is layer.yaml, in this repository's own voice
— a layer someone else states about you is not a declaration.
The ruling also confirmed that emitting a presentation claim does not require a second catalog row: PEP and PIP are shapes a repository has, and §4 records the layers it occupies. That permission carries three limits, and they are the substance of it rather than caveats on it:
- The claim carries presentation and nothing else. It must never 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.
- The claim must not be an input to the decision it presents for. A policy
reading
view_hashto decide whether an act is permitted would let the presenting surface contribute to its own authorization. - The evidence copy reaches
audit-coreindependently of this repository. The claim endpoint and the evidence path are different things and neither substitutes for the other.
Limit 2 is load-bearing. 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 that limit
holds. Without it, the two collapse into the same failure.
Limit 3 is the one that most shapes the architecture: audit evidence is protected from the actor being audited, and here the actor and the source are the same component.
view_hash and the binding digest
Ruled as option (b): they are distinct attestations with an authority rule.
approval-engine's binding digest is authoritative for what the request is.view_hashis authoritative for what was shown, and nothing else.- Neither may be substituted for the other.
- A disagreement between them is a finding against the presenting surface, never a fact about the request.
They link by co-reference, not nesting: the presentation record carries the
approval or binding identifier explicitly, and both attestations are read
against that one reference. This repository must never recompute or restate
approval-engine's binding digest in its own vocabulary — it references the
digest that layer computed and recorded.
Nesting was refused for a reason worth carrying: it reproduces the hash cycle
that made GH-DEC-2026-008 unimplementable, where a claim had to name the
digest of a request that would come to contain it, and a fail-closed consumer
obeying it would deny permanently.
An inherited gap, stated rather than glossed
GH-DEC-2026-010 requires a decision be attributable to access-engine.
No consumer can satisfy that today: the decision envelope is unsigned, a
declared §13 gap tracked as FLEX-WP-0024. This repository's record can show
that a decision was obtained and what it said; it cannot yet show that
access-engine said it. The decision path must not be described as validated
while that is open.
What Would Make This Repository Wrong
- It starts deciding. Any surface that answers "may this actor do X" rather than "here is the question, and here is what you were shown" is the failure statute §6 names.
- It becomes an approvals inbox and nothing else. If the object that ships cannot also carry an L0 login banner and an L2 ADR accept, the scale-invariance thesis is dead and the estate bought a queue.
- It forks the schema per level. Three levels, three object models, one broken promise.
- Awareness leaks into the signature. If a last-used role or a tenant
orientation hint enters
view_hash, the surface signs something the person did not commit to. - Highlights shrink the legal object. If acking three highlights is presented as binding only those three sections, the UI has produced a lie.
- An agent binds. If any automation can complete a disposition on a principal's behalf, the identity half is fiction.
- It renders
approvedas permission to act.approvedis a state of an object, not authorization.approval-engineactively refuses to serialize a decision. A surface that presents approval status as "you may now do the thing" has re-implemented a PDP in the browser — the same failure as an authorization endpoint, wearing UI copy instead of an API. - It reimplements
approval-engine. Caching approval validity, inferring consumption from a decision record, or holding approval current-state here breaksGH-DEC-2026-003and the atomicity contract. - It invents identity. A local password, a local session token that is not
derived from
key-cape, or a self-issued assurance level. - Nobody uses it. If
approval-enginenever receives anapproval:approvetoken from this component's client, the surface is decorative and the gap it claimed to close is still open.
Success Criteria
key-capeholds a registered browser client whoseclient_idand callback URI this repository owns and published, andKEY-WP-0013-T02is unblocked.- A human approver completes an approval entry against
approval-engineentirely through this surface, with an access token carryingaud=approval-engine,principal_type: human, and scopeapproval:approve. - The approval entry is reconstructable from a
view_hash— the estate can show what the approver was looking at. - Required highlights cannot be bypassed: a bind attempt without acks fails.
return,discuss, andescalateare exercisable on a real approval and are not modelled asdecline.- The same schema renders an L0 login banner and an L2 ADR accept, with the binding/awareness split intact and the isolation vectors green.
- An evidence bundle exports and verifies offline against
audit-core's record of the same transitions. - No endpoint in this repository answers an authorization question.