informed-decision/docs/gate-house-decision-request-layer-placement.md
tegwick ebd35b59cf Raise INFD-IN-0001: layer placement and approver-UI ownership
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
2026-09-09 14:07:13 +02:00

8.5 KiB

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.