Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a126e1-76f8-7643-8cf3-e93336539ade
406 lines
21 KiB
Markdown
406 lines
21 KiB
Markdown
---
|
|
project: informed-decision
|
|
product: Informed Decision
|
|
status: draft
|
|
intent_version: 0.1.0
|
|
date: "2026-09-09"
|
|
domain: infotech
|
|
topic_slug: netkingdom
|
|
# NetKingdom security layer declaration (security-layer-model §11).
|
|
# THIS FRONTMATTER IS THE DECLARATION. GH-DEC-2026-017 §1 rules that INTENT.md
|
|
# governs and that `layer.yaml` is a DERIVED artifact which must agree with it.
|
|
#
|
|
# `layer: surface` stood here from 2026-09-09 to 2026-09-21. GH-DEC-2026-017 §3
|
|
# ruled the §3 vocabulary closed at four tokens — Taxonomy, Tooling, Engine,
|
|
# Staff — and named Staff for this repository. Changed the same day, without
|
|
# argument, as this repository pre-committed in
|
|
# docs/gate-house-decision-request-layer-vocabulary.md §3. The reasoning that
|
|
# produced `surface` is kept as history in layer.yaml; it is not erased.
|
|
#
|
|
# No standard version is carried, per GH-DEC-2026-017 §5 / A12: this declares a
|
|
# standing property, and a version here would read as a validity condition that
|
|
# every revision of the standard invalidated. Version-scoped state belongs in
|
|
# the derived conformance record.
|
|
layer: Staff
|
|
role: pep-shaped # §6.4 shape, confirmed by GH-DEC-2026-012 R1; a role is not a layer
|
|
standard: net-kingdom/canon/standards/ # the body, unversioned on purpose
|
|
companion: 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 in `GOAL.md`; current work belongs in `workplans/`.
|
|
|
|
## Purpose
|
|
|
|
> **informed-decision provides the decision lifecycle service for agents and
|
|
> humans: research, retrieve, prepare, evaluate, register, publish, comment on,
|
|
> refine, and accept decisions. A headless foundation owns the memo lifecycle
|
|
> and evidence; the UI at `decisions.coulomb.social` uses that foundation.
|
|
> Humans alone perform binding dispositions.**
|
|
|
|
Its binding evidence answers the question:
|
|
|
|
> **What was this person shown, in what role, at the moment they bound
|
|
> themselves to this act — and can that be proven afterwards?**
|
|
|
|
Evaluation means assessing evidence, alternatives, consequences and recommendations;
|
|
it does not mean issuing an authorization verdict. This service 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`).
|
|
|
|
## Product direction — 2026-10-04
|
|
|
|
Decisions and their revisions are runtime data. Creating, registering, publishing,
|
|
commenting on, refining or accepting a decision within an admitted class must
|
|
require no image build, infrastructure release, policy redeployment, ConfigMap
|
|
swap or manual store load. Platform and policy changes can still require a
|
|
release; an ordinary new decision cannot.
|
|
|
|
The headless service provides the same lifecycle rules to agent clients and the
|
|
human UI. UI code owns rendering and interaction; it does not own a second
|
|
lifecycle or write the store directly. Research and evaluation records retain
|
|
sources, authorship and uncertainty. Publication has an explicit audience and
|
|
does not imply acceptance or anonymous access. Acceptance identifies an exact
|
|
revision and its presentation evidence.
|
|
|
|
The delivery contract is `docs/specs/DecisionLifecycleService.md`, tracked by
|
|
`INFD-WP-0007`, building on the intake in `INFD-WP-0005`. This direction extends
|
|
the first approver slice; it does not claim those capabilities are deployed.
|
|
|
|
## 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-engine` is 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's `client_id` and 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 presents `approval:approve`
|
|
tokens 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_id` and callback URI that `key-cape` is 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 an `approval: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
|
|
|
|
1. **One object, many depths.** Login and instrument share a schema.
|
|
2. **Presentation is part of the signed payload.** Dynamic linking, not a
|
|
signature over a file nobody read.
|
|
3. **Competence before convenience.** Routing follows mandate.
|
|
4. **Return is success.**
|
|
5. **Dialogue stays on the object.** Side-channel email is an anti-pattern.
|
|
6. **Binding level is explicit.** Kenntnisnahme ≠ Mitzeichnung ≠ QES.
|
|
7. **Evidence is an export, not a screenshot.**
|
|
8. **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.
|
|
9. **Identity is imported.**
|
|
10. **Humans bind, agents draft.** An agent may assemble a memo. It may never
|
|
complete the binding act on the principal's surface.
|
|
11. **Awareness is not consent.** Defaulting a role to last-used is required
|
|
for situational awareness and forbidden from silently entering `view_hash`.
|
|
12. **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
|
|
|
|
**Layer: `Staff`. Role: PEP-shaped.** Both are ruled.
|
|
|
|
The **shape** was ruled by `GH-DEC-2026-012` R1 (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 **layer value** was ruled by `GH-DEC-2026-017` §3 (answering `INFD-IN-0006`)
|
|
on 2026-09-21. §3's vocabulary is **closed** and has four tokens — `Taxonomy`,
|
|
`Tooling`, `Engine`, `Staff`; comparison is ASCII case-insensitive and nobody is
|
|
asked to re-spell anything. `surface` is not among them, and the correct value
|
|
here is `Staff`, with `role: pep-shaped` untouched. `ops-mason` and `ops-warden`
|
|
are the precedent: Staff in the layer column, PEP-shaped in the role column.
|
|
|
|
This repository had pre-committed to changing both files the same day, without
|
|
argument, if the vocabulary was ruled closed and a value was named
|
|
(`docs/gate-house-decision-request-layer-vocabulary.md` §3). It did. **The
|
|
reasoning that produced `surface` is not erased** — it is kept as history in
|
|
`layer.yaml`, because a value written by elimination against a vocabulary that
|
|
turned out to be closed is evidence about the vocabulary, not carelessness.
|
|
|
|
Two things follow, and are recorded rather than argued:
|
|
|
|
- **`informed-decision` was never a §11 non-conformance.** §11's obligations
|
|
attach to estate-authored repositories **in §4**, and this repository holds no
|
|
§4 catalog row. `GH-DEC-2026-017` §4 states that a run which grades it is
|
|
over-scoped, and requires every conformance run to state its scope. The
|
|
correct report is *declared voluntarily, outside catalog scope; value not in
|
|
the vocabulary, correction identified*. The correction was this repository's
|
|
to make and it made it.
|
|
- **The declaration's form changed too.** `INTENT.md` frontmatter **governs**;
|
|
`layer.yaml` is a **derived artifact** that must be marked derived, must name
|
|
`INTENT.md` as what it derives from, and must agree with it
|
|
(`GH-DEC-2026-017` §1 / A11). A declaration carries **no standard version**
|
|
(§5 / A12), so the `standard_version: "0.7"` this repository flagged is gone.
|
|
`ops-warden` owns the reference sidecar form and is updating it; this
|
|
repository applied the two ruled properties and follows that form for the rest.
|
|
|
|
One thing the ruling did **not** settle, carried as `INFD-IN-0007` rather than
|
|
treated as settled: §3.4 says Staff *"MUST NOT hold state that another layer
|
|
depends on at runtime"*, and this repository's presentation records are exactly
|
|
state `audit-core` depends on. The ruling reaches `Staff` by elimination — not
|
|
Engine per `GH-DEC-2026-012` R1, and nothing else in the four is true — which is
|
|
the same route this repository walked, and it gives the value. It does not say
|
|
how a deterministic, non-agentic repository that holds evidentiary state sits
|
|
inside the layer defined by non-determinism and agentic capability. **The value
|
|
is applied regardless**; the question is asked for the next repository in this
|
|
position, not as a condition on the change.
|
|
|
|
### §4 catalog membership — answered: yes
|
|
|
|
`GH-DEC-2026-017` §4 deliberately did **not** enrol this repository, because a
|
|
layer stated about a repository by another is not a declaration and that rule
|
|
applies to catalogue membership at least as strongly. The question was asked,
|
|
and this repository's answer is **yes**: see `docs/section-4-catalog-row.md`.
|
|
|
|
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:
|
|
|
|
1. **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*.
|
|
2. **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.
|
|
3. **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.
|
|
|
|
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_hash` is 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 `approved` as permission to act.** `approved` is a state of an
|
|
object, not authorization. `approval-engine` actively 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
|
|
breaks `GH-DEC-2026-003` and 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-engine` never receives an `approval:approve`
|
|
token from this component's client, the surface is decorative and the gap it
|
|
claimed to close is still open.
|
|
|
|
## Success Criteria
|
|
|
|
1. `key-cape` holds a registered browser client whose `client_id` and callback
|
|
URI this repository owns and published, and `KEY-WP-0013-T02` is unblocked.
|
|
2. A human approver completes an approval entry against `approval-engine`
|
|
entirely through this surface, with an access token carrying
|
|
`aud=approval-engine`, `principal_type: human`, and scope `approval:approve`.
|
|
3. The approval entry is reconstructable from a `view_hash` — the estate can
|
|
show what the approver was looking at.
|
|
4. Required highlights cannot be bypassed: a bind attempt without acks fails.
|
|
5. `return`, `discuss`, and `escalate` are exercisable on a real approval and
|
|
are not modelled as `decline`.
|
|
6. The same schema renders an L0 login banner and an L2 ADR accept, with the
|
|
binding/awareness split intact and the isolation vectors green.
|
|
7. An evidence bundle exports and verifies offline against
|
|
`audit-core`'s record of the same transitions.
|
|
8. No endpoint in this repository answers an authorization question.
|
|
|
|
|
|
## Bounded Staff-evidence doctrine response — 2026-10-11
|
|
|
|
GH-DEC-2026-025 accepts the exact bounded disposition: this repository remains
|
|
Staff/PEP-shaped and carries the unresolved §3.4 deterministic-evidence tension.
|
|
The answer to INFD-IN-0007 is to state that tension openly, not claim it has
|
|
been solved. NetKingdom has assembled a proposed successor; NET-IN-0004 retains
|
|
separate accepted standard voice/publication. Accepted v0.8 remains untouched;
|
|
this source receipt is not acceptance of the whole successor or enrolment by
|
|
another repository. INFD-IN-0007 stays open pending that publication boundary.
|
|
|
|
The existing independent evidence and identity/approval/PDP limits remain.
|
|
The source now has local transactional evidence/outbox, per-class heartbeat
|
|
and scheduled reconciliation mechanisms; finished INFD-WP-0005/0007 preserve
|
|
those implementation receipts. Full class-specific emission guarantee and
|
|
verification remain owed/not declared, not fulfilled by delivered rows, matching
|
|
counts or a layer/pin PASS. INFD-IN-0009 retains the unpromoted residual source
|
|
verification/declaration work; the §3.4 tension is a separate retained finding.
|
|
Current bounded evidence: docs/evidence/2026-10-11-staff-evidence-source-reconciliation.md.
|