File the gate-house decision request that gates INFD-WP-0001-T02, before any architecture is written, so the ruling constrains the design rather than being retrofitted to it. Three rulings requested: layer and role (proposed PEP-shaped, §6.4/companion §5); whether a presentation attestation also makes this a PIP or must reach consumers only through audit-core; and the relationship between view_hash and approval-engine's binding digest. The third is the highest risk and the reason this is filed first. Both digests claim to canonicalize "the binding" but cover different material — the approval digest exists without a human in the loop, view_hash covers the brief, packet, highlights, locale and UI release. Three candidate rulings are set out with what each costs; the proposal is distinct attestations with an explicit authority rule, but any of the three is implementable. The outcome to avoid is both shipping with no stated relationship. The self-dealing objection is argued against ourselves rather than left for review, and the residual is stated plainly: a compromised surface can present X and attest Y, structurally the same residual approval-engine names for adversarial omission at a compromised source. No claim is made to close it. 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
175 lines
8.5 KiB
Markdown
175 lines
8.5 KiB
Markdown
# Decision request to gate-house — layer placement and approver-UI ownership
|
|
|
|
**From:** informed-decision
|
|
**Raised:** 2026-09-09
|
|
**Intake:** `INFD-IN-0001`
|
|
**Blocks:** `INFD-WP-0001-T02`, and through it T05 and T07
|
|
**Standard:** `net-kingdom/canon/standards/security-layer-model_v0.7.md`,
|
|
companion v0.2
|
|
|
|
---
|
|
|
|
## 1. The gap being closed
|
|
|
|
`approval-engine` names an approvals inbox under Non-Goals, deliberately and
|
|
correctly — an engine that renders its own object is self-dealing, and the same
|
|
reasoning kept the approval object out of `access-engine`.
|
|
|
|
The consequence is that the surface a human actually touches has no owner. This
|
|
is no longer theoretical:
|
|
|
|
- `approval-engine` is a bearer-token resource server with no Ingress, no
|
|
redirect endpoint and no browser client (`deploy/approval-engine.yaml` is
|
|
Namespace + ClusterIP + StatefulSet).
|
|
- On 2026-09-08 `key-cape` (`KEY-WP-0013-T02`) asked `approval-engine` for the
|
|
human approver client's `client_id` and full callback URI.
|
|
- `approval-engine` declined to invent them and recorded 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 and is not named in
|
|
`APPROVAL-WP-0002`."*
|
|
- `APPROVAL-WP-0002-T01` remains `progress` in part because of it.
|
|
|
|
`informed-decision` exists to take this. **We are not asking whether the work is
|
|
ours to do. We are asking what layer the statute says we are, and asking it
|
|
before we build, so the answer constrains the architecture rather than being
|
|
retrofitted to it.**
|
|
|
|
## 2. What is being asked
|
|
|
|
Three rulings, in dependency order. R3 is the one we least want to get wrong.
|
|
|
|
### R1 — Layer and role
|
|
|
|
**Proposal:** `informed-decision` is **PEP-shaped** under statute §6.4 and owes
|
|
companion §5.
|
|
|
|
Reasoning: it is browser-facing and it causes a protected side effect on the far
|
|
side of a decision — it submits an approval entry to `approval-engine` carrying
|
|
an authenticated human's identity. `approval-engine`'s own INTENT anticipates
|
|
exactly this class of caller: *"Callers that do are PEP-shaped and owe
|
|
companion §5 / statute §6.4."*
|
|
|
|
We are **not** proposing an Engine row. We hold no state another layer reads at
|
|
runtime to reach a verdict.
|
|
|
|
### R2 — Does a presentation record make this a PIP as well?
|
|
|
|
`informed-decision` produces one fact other layers may want as a claim: **what
|
|
was presented, to whom, in what version** — carried as `view_hash`. We do not
|
|
evaluate that fact; we emit it.
|
|
|
|
**Proposal:** the presentation attestation is a PIP-like claim emitted by a
|
|
PEP-shaped component, not a second catalog row. If the statute does not permit
|
|
a component to be both, we ask which one governs and whether the presentation
|
|
claim must instead be published as evidence to `audit-core` and read from there.
|
|
|
|
We flag §17: the shared request-claim schema has **no assigned owner**. Whatever
|
|
shape we publish must yield to that schema when it exists rather than becoming a
|
|
permanent local invention — the same position `approval-engine` took in
|
|
`APPROVAL-IN-0001`.
|
|
|
|
### R3 — `view_hash` versus the approval binding digest
|
|
|
|
**This is the highest-risk item in the request and the reason it is filed before
|
|
any code.**
|
|
|
|
`approval-engine`'s claim already carries *"a digest over the same canonical
|
|
binding the decision point already computes, so that approved and approved for
|
|
this exact request are distinguishable at decision time."*
|
|
|
|
`informed-decision` computes `view_hash`: a SHA-256 over a canonicalized
|
|
*binding document* — the memo id and version, question, requested act, binding
|
|
level, brief, locale, UI release, normalized packet and highlights, and the
|
|
identity/scope being committed. Algorithm and vectors:
|
|
`history/20260909-initial-exploration/canonicalize.md`.
|
|
|
|
These are **not obviously the same hash**, and they are **not obviously
|
|
different**. Both claim to canonicalize "the binding". They differ in what they
|
|
cover:
|
|
|
|
| | approval-engine binding digest | informed-decision `view_hash` |
|
|
| --- | --- | --- |
|
|
| Covers action, target, actor, principal, purpose | yes | yes, as `binding` |
|
|
| Covers the brief, packet and highlights shown to the human | no | yes |
|
|
| Covers locale and UI release | no | yes |
|
|
| Exists when no human is in the loop | yes | no |
|
|
| Purpose | replay protection at decision time | proof of what was presented |
|
|
|
|
Three candidate rulings, with what each costs:
|
|
|
|
- **(a) They are the same digest.** Cleanest for the estate — one
|
|
canonicalization, one authority. Cost: the approval binding digest would have
|
|
to cover presentation material that does not exist for machine-to-machine
|
|
approvals, or `view_hash` would have to drop the packet and highlights, which
|
|
destroys the property this repository exists to provide.
|
|
- **(b) `view_hash` is a distinct presentation attestation carried alongside the
|
|
binding digest.** Our proposal. Cost: two hashes over one act, requiring an
|
|
explicit rule that the binding digest is authoritative for replay protection
|
|
and `view_hash` is authoritative only for *what was shown*. Neither may be
|
|
substituted for the other.
|
|
- **(c) `view_hash` contains the binding digest as a field.** Composition rather
|
|
than duplication; `view_hash` becomes a superset commitment. Cost: ordering
|
|
dependency — the approval must exist before a memo can be rendered.
|
|
|
|
**We propose (b) and will implement whichever is ruled.** What we ask gate-house
|
|
to prevent is the outcome where both hashes ship without a stated relationship
|
|
and the estate later discovers it has two canonicalizations of the same act with
|
|
no rule for which one governs.
|
|
|
|
## 3. The self-dealing objection, stated against ourselves
|
|
|
|
A surface that renders both the question and the answer sits close to the
|
|
objection that kept the approval object out of `access-engine` and the inbox out
|
|
of `approval-engine`. We think it is not the same failure, and we would rather
|
|
argue it here than be told later:
|
|
|
|
- `access-engine` could not own the approval object because an evaluator that
|
|
owns what it evaluates can grade its own inputs.
|
|
- `approval-engine` could not own the inbox because an engine that renders its
|
|
own object controls the presentation of the evidence it issues.
|
|
- `informed-decision` **holds no state any layer reads as authority.** It does
|
|
not evaluate, does not issue the approval, and does not archive the trail.
|
|
The presentation record is evidence *about* the act, produced by the party
|
|
that performed the presentation — which is the only party that can produce it.
|
|
|
|
The residual we accept and do not paper over: **a compromised surface can
|
|
present X and attest Y.** `view_hash` is computed by the same component that
|
|
renders. This is structurally the same residual `approval-engine` names for
|
|
adversarial omission at a compromised source, and we make the same claim it
|
|
does — atomicity and attestation cover accident and later tampering, not a
|
|
compromised source. We do not claim otherwise, and we ask that any ruling not
|
|
credit us with closing it.
|
|
|
|
## 4. What we are not asking
|
|
|
|
- Not asking for approval doctrine. Which acts need approval, how many
|
|
approvers, and which separations of duty apply stay `gate-house`'s.
|
|
- Not asking to render decisions. No endpoint here answers "may this actor do
|
|
X"; `access-engine` remains the only PDP.
|
|
- Not asking to hold approval state. `approval-engine` remains the sole
|
|
mutator, and `GH-DEC-2026-003` ordering is honoured unchanged.
|
|
- Not asking for a Railiance operational axis.
|
|
|
|
## 5. What we do on each answer
|
|
|
|
| Ruling | Consequence |
|
|
| --- | --- |
|
|
| R1 confirms PEP-shaped | `layer.yaml` written as such; companion §5 declared shapes enumerated in T05 |
|
|
| R1 places us elsewhere | `INTENT.md`, `GOAL.md`, `SCOPE.md` amended to match; the ruling wins |
|
|
| R2 permits a presentation claim | Published at our boundary, explicitly yielding to §17 |
|
|
| R2 refuses it | Presentation evidence goes to `audit-core` only; no claim endpoint |
|
|
| R3 = (a) | One digest; `view_hash` is retired or redefined as its input |
|
|
| R3 = (b) | Both ship with a stated authority rule, recorded as a decision |
|
|
| R3 = (c) | Composition; memo rendering is ordered after approval issuance |
|
|
|
|
Until R1 and R3 are answered, `INFD-WP-0001-T05` (ArchitectureBlueprint) and
|
|
T07 (the `key-cape` client registration) do not proceed. T03, T04 and T06 are
|
|
independent of the ruling and continue.
|
|
|
|
## 6. Cost of delay
|
|
|
|
`KEY-WP-0013-T02` is blocked today on two strings this repository now owns and
|
|
cannot responsibly publish until it knows what it is. Registering a redirect URI
|
|
for a component whose layer is unsettled is the drift statute §17 exists to
|
|
prevent.
|