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
18 KiB
| id | type | title | domain | repo | status | owner | topic_slug | created | updated | reviewed_at | reviewed_against_commit | reviewed_note | origin | origin_ref | state_hub_workstream_id |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| INFD-WP-0001 | workplan | Founding specs and approver-UI ownership | infotech | informed-decision | active | claude | netkingdom | 2026-09-09 | 2026-09-09 | 2026-09-09 | ee2cca5 |
Reviewed against approval-engine's INTENT, SCOPE, layer.yaml, APPROVAL-WP-0002 and docs/keycape-service-registrations.md; the accepted NetKingdom security layer model v0.7 and companion v0.2; the repo-classification and project-repository-flavor standards; and the Decision Memo schema, state-transition tables and canonicalization vectors in history/20260909-initial-exploration. Repo-owned specification work can proceed. T05 and T07 remain externally gated on the gate-house ruling requested as INFD-IN-0001; T08 is additionally gated on APPROVAL-WP-0002-T01 and a deployed approval-engine. | founding | history/20260909-initial-exploration/InitialExploration.md | a985a65a-08f7-5a39-8645-b618ea022657 |
INFD-WP-0001 — Founding specs and approver-UI ownership
Establish informed-decision as a governed repository in the NetKingdom estate,
settle who owns the browser-facing approver UI that approval-engine
deliberately does not contain, and produce the specification set that Stage 1
implementation will be built against.
The trigger is concrete and dated. On 2026-09-08 key-cape (KEY-WP-0013-T02)
asked approval-engine for the human approver client's client_id and callback
URI. approval-engine correctly declined to invent them and recorded in
docs/keycape-service-registrations.md that the human approver flow "belongs to
whichever browser-facing approver UI presents approval:approve tokens to this
engine. That component is not in this repo." APPROVAL-WP-0002-T01 remains
progress partly because of it. This workplan closes that gap by naming the
owner and shipping the contract.
Reviewed 2026-09-09; the plan is active. Reviewed against the contracts
listed in the frontmatter. T02 remains the gate for the architecture: if
gate-house places this component differently, T05 and T07 are rewritten before
they are written. T03, T04 and T06 are independent of the ruling because they
describe what the surface must do and what the evidence must contain, neither of
which changes with the catalog row.
Scope boundary for this workplan: specification and contract, plus one
walking skeleton. Full L3 product build is residual and belongs to
INFD-WP-0002.
Establish the founding documents
id: INFD-WP-0001-T01
status: done
priority: high
state_hub_task_id: "abe83f6a-18d2-5fe5-bd01-56b6fd0babbe"
Write the repository's stable statements of purpose and current stage, derived from the founding exploration rather than reinvented.
Acceptance: INTENT.md states purpose, the Decision Memo concept, ownership and
non-ownership against the named estate repositories, design principles, wrongness
conditions and success criteria; GOAL.md states the Stage 1 outcome, exclusions,
invariants and definition of done; README.md orients a new reader in under a
minute; history/20260909-initial-exploration/ is preserved unmodified as the
provenance record.
Completed 2026-09-09: INTENT.md, GOAL.md, README.md, SCOPE.md,
AGENTS.md and .repo-classification.yaml written; repo registered in the
State Hub and INFD-WP-0001 indexed by fix-consistency.
Two corrections made during the same task, recorded rather than silently fixed:
GOAL.mdfirst declaredrepo_flavor: project. That is wrong.project-repository-flavor_v0.1.mdreserves theprj-flavor for bounded cross-repo coordination efforts and states that durable products useINTENT.mdand an ordinary category. This is a durable product;.repo-classification.yamlsetscategory: product.GOAL.mdis retained as the stage statement, which the flavor standard does not forbid.SCOPE.mdwas initially deferred to T06 on the reasoning that a scope file written before the layer ruling describes an imagined boundary. The Repo Manager requires it (C-35), and the reasoning was better served by writing an honestly empty one: the shippedSCOPE.mdstates plainly that nothing is implemented and that T06 rewrites it. T06 now rewrites rather than creates.
Settle layer placement and approver-UI ownership with gate-house
id: INFD-WP-0001-T02
status: done
priority: high
state_hub_task_id: "4f94134b-2260-5404-84e0-12f2b08ef565"
Take the ownership question to gate-house as doctrine rather than asserting a
catalog row. The proposal to argue: informed-decision owns the browser-facing
approver surface, the presentation record and the evidence of informedness; it
is PEP-shaped under statute §6.4 and companion §5 because it is
browser-facing and causes a protected side effect on the far side of a decision;
it supplies exactly one PIP-like fact — what was presented — as a claim, and
never evaluates it.
Raise explicitly, and do not paper over:
- §17 has no request-claim schema owner assigned. A
view_hash-bearing presentation claim must yield to that schema when it exists rather than inventing a permanent local shape. approval-engine's claim already carries "a digest over the same canonical binding the decision point already computes". Whetherview_hashis that digest, a sibling of it, or a distinct presentation attestation is a real question and the wrong answer creates two competing canonicalizations of the same act. This is the single highest-risk unknown in the workplan.- A surface that renders both the question and the answer is adjacent to the
self-dealing objection that kept the object out of
access-engine. State why it is not the same failure: this repository holds no state a decision reads as authority.
Acceptance: an intake is filed with gate-house; a ruling or a recorded decision
exists; layer.yaml is written from the ruling and matches the catalog row, not
this workplan's prose; INTENT.md and GOAL.md are amended if the ruling
differs from the proposal; the view_hash-versus-binding-digest relationship is
recorded as a decision, not left implicit. Blocking for T05 and T07.
Product Requirements Document
id: INFD-WP-0001-T03
status: done
priority: high
state_hub_task_id: "86465a35-1af5-5956-a767-57ad838dffa9"
Write docs/specs/ProductRequirementsDocument.md for Stage 1: the L3 approval
approver surface, scoped to one real consumer.
Must cover: the personas (approver holding a mandate, requester, observer/auditor);
the disposition vocabulary and which verbs are legal on which step kinds; the
required-highlight acknowledgment gate; the pre-sign/awareness split as it
appears in the UI; the evidence bundle as an export; accessibility and locale
(DE/EN, given the Umlaufmappe framing); and the explicit non-requirements from
GOAL.md — no mandate graph, no QES, no notification transport.
State the anti-requirements as first-class: no dark patterns, no dwell timers, no keystroke analytics, and a UI that makes unmistakable that the whole instrument is bound rather than only the acknowledged highlights.
Acceptance: every requirement traces to either a GOAL.md definition-of-done
item or a named external contract; each requirement is testable; the document
names what it is deliberately not requiring and why.
Completed 2026-09-09: docs/specs/ProductRequirementsDocument.md. 30 numbered
requirements, each with a trace: line to a GOAL.md DoD item, an INTENT.md
principle or wrongness condition, a state-transition guard, or a named external
contract, and each with an observable pass condition. Anti-requirements
(PR-70..75) are stated as testable absences: no dwell timers, no attention
analytics, no dark patterns, no auto-approval, no approval-state caching, no
authorization endpoint. Four known limitations are recorded up front rather than
discovered later — chiefly that escalate without a mandate graph is forwarding
(L-01) and that view_hash is computed by the renderer, so a compromised
surface can present X and attest Y (L-02). Four open questions are left for
review rather than answered by assumption.
Use Case Catalog
id: INFD-WP-0001-T04
status: done
priority: medium
state_hub_task_id: "00a83db5-fe0e-522a-b885-6f9ef034bc07"
Write docs/specs/UseCaseCatalog.md covering the full depth spectrum L0–L5, with
Stage 1 scope marked, so that scale invariance is testable as a design property
rather than a claim in a vision statement.
For each level: actor, trigger, requested act, binding level, the verbs that must be available, the evidence produced, and the estate repository that is the counterparty. Include the L0 login banner and the L2 ADR accept in full even though they are out of Stage 1 build scope — their purpose here is to constrain the schema so the object cannot fork later.
Include the negative cases: accept on a Kenntnisnahme step (illegal by design),
a bind attempt with unacknowledged required highlights, an agent attempting a
disposition, and a tenant switch requiring a new bind.
Acceptance: every use case maps onto the single Decision Memo schema with no level-specific object; each negative case names the invariant it protects; the catalog states for each level which estate repository would consume it.
Completed 2026-09-09: docs/specs/UseCaseCatalog.md. Six use cases L0-L5 with
counterparty and stage, ten negative cases each bound to a guard or isolation
vector, and a closing section naming the four changes that would fork the
object — a level-specific status, multiple questions per memo, a per-level
packet model, and an approvals-inbox entity that acquires state. Each case
records what it contributes as a constraint on the shared schema, so the
scale-invariance claim is checkable rather than asserted.
Architecture Blueprint
id: INFD-WP-0001-T05
status: todo
priority: high
state_hub_task_id: "20ea118e-0657-5054-8aa2-b316444f4000"
Write docs/specs/ArchitectureBlueprint.md. Depends on T02 — the layer ruling
determines what this component is permitted to be.
Must cover: the component boundary and its position in the security layer model;
the call graph to key-cape (OIDC authorization-code + PKCE for humans),
approval-engine (bearer approval:approve, never approval:consume),
access-engine (decision, never rendered here) and audit-core (evidence
emission); the storage posture for memos, presentations and dispositions;
the deployment shape including the Ingress and external origin that
approval-engine explicitly does not have; and the failure modes — what the
surface does when approval-engine, key-cape or audit-core is unavailable.
Fail-closed is the default and must be stated per dependency. A surface that degrades into showing a memo it cannot bind is acceptable; a surface that degrades into binding without evidence is not.
Acceptance: no component in the diagram renders an authorization decision; the
token audiences, scopes and principal types match approval-engine's
docs/keycape-service-registrations.md exactly; every external dependency has a
stated unavailable-stance; the blueprint names which parts are Stage 1 and which
are placeholders.
Evidence model, schema promotion and canonicalization under test
id: INFD-WP-0001-T06
status: progress
priority: high
state_hub_task_id: "47cb3f7a-e349-5c81-a304-86275e058a85"
Promote the exploration artifacts from history/ into governed, tested
repository assets, and write docs/specs/EvidenceModel.md.
Move decision-memo.schema.json to schemas/, canonicalize.py into the
package, and the fixtures in vectors/ into the test suite. history/ stays
untouched as provenance; the governed copies are the ones that change.
The four isolation properties from the exploration become tests that must stay green:
- shuffling object keys does not change either hash;
- editing an awareness field does not change
view_hash; - changing
binding.targetdoes changeview_hash; - selecting a role after login emits
session.hat_selectedand does not rewriteview_hash.
EvidenceModel.md covers what an evidence bundle contains, how it verifies
offline, its relationship to audit-core's archive, and — carried over from
approval-engine's reasoning rather than rediscovered — the honest statement
that a hash chain proves records were not altered after arrival and cannot prove
a record was never sent.
Rewrite SCOPE.md as the last step of this task. The version shipped in
T01 is honestly empty — it states that nothing is implemented. Replace it with
the real implemented-and-first-cut boundary once the layer ruling and the specs
have fixed it, and drop the T01 status banner.
Acceptance: schema, canonicalizer and vectors live outside history/ and are
exercised in CI; the three published expected hashes reproduce byte-for-byte;
EvidenceModel.md states the residual it does not close; SCOPE.md describes
the implemented-and-first-cut boundary rather than the aspiration, and no longer
carries the T01 "nothing is implemented" banner.
2026-09-09 — substantive half done; task stays progress because the SCOPE.md
rewrite is gated on T02. Delivered:
schemas/decision-memo.schema.jsonplus both worked examples;informed_decision/canonicalize.pyas the governed canonicalizer, with the ad-hoc__main__block replaced bypython -m informed_decision; fixtures undertests/vectors/.history/is untouched.tests/test_canonicalize.py— 20 tests, all green. The three published hashes reproduce byte for byte, and all four isolation properties are pinned.docs/specs/EvidenceModel.md.pyproject.toml,Makefile(make test,make check).
Two things worth recording rather than burying:
- Isolation properties 1, 2 and 4 are all negative — they assert the hash does
not change. A canonicalizer returning a constant would pass all three.
Property 3 plus per-field variants over
question,requested_act,binding_levelandpacketare what stop the suite being vacuous. test_governed_vectors_match_the_preserved_history_copyasserts the governed fixtures have not drifted from the founding copies, so quietly editing a vector to make a failing test pass is itself a failure.
Remaining for done: rewrite SCOPE.md after the T02 ruling.
Publish the OIDC browser-client contract to key-cape
id: INFD-WP-0001-T07
status: todo
priority: high
state_hub_task_id: "38a83a76-f152-55bf-8a9a-6132fd6d9642"
Own and publish the two strings approval-engine could not supply: the human
approver client's client_id and its full callback URI. Depends on T02 for the
ownership ruling and on T05 for the deployment origin.
The registration is an authorization-code + PKCE public or confidential browser
client — not client_credentials — and the resulting access token must carry
aud=approval-engine, principal_type: human, tenant: tenant:platform and
scope approval:approve. Redirect URIs match exactly at /authorize, so the
origin must be a real deployed origin, decided in T05, not a placeholder.
Do not request approval:consume: approval-engine refuses it for human
principals, and consumption belongs to the PEP that causes the side effect.
Acceptance: docs/keycape-client-registration.md publishes both strings and the
expected token shape; the contract is sent to key-cape referencing
KEY-WP-0013-T02, and to approval-engine referencing its
docs/keycape-service-registrations.md follow-up; a token issued against the
registration is accepted by approval-engine's verifier; KEY-WP-0013-T02 is
unblocked. This is the task that discharges the gap that created this
repository.
Walking skeleton — one approval, end to end
id: INFD-WP-0001-T08
status: todo
priority: medium
state_hub_task_id: "b5c1d329-9580-5672-9640-2930cbbb729a"
Prove the specs against reality with the thinnest possible L3 path: sign in via
key-cape, list approvals awaiting this principal from approval-engine,
render one as a Decision Memo with brief, packet and highlights, acknowledge the
required highlights, and submit an approval entry with a stored presentation
record carrying view_hash.
return and discuss are in this skeleton, not deferred. They are the
differentiator; a skeleton with only approve/reject proves the wrong product.
Acceptance: one approval is approved by a real human through this surface
against a deployed approval-engine; the approval entry is reconstructable from
a stored presentation; a bind attempt with unacknowledged required highlights
fails closed; return produces a structured reason and is distinguishable from
decline in the record; no code path in this repository evaluates whether the
act is permitted.
Gated externally on approval-engine APPROVAL-WP-0002-T01 reaching done and
on the service being deployed with an origin this surface can reach.
Known risks
- T02 is a hard gate. Writing the blueprint before the layer ruling risks building a component the statute does not permit in that shape.
- Two canonicalizations. If
view_hashandapproval-engine's binding digest are not reconciled in T02, the estate ends up with two hashes over the same act and no rule for which one is authoritative. - Deployment origin is on someone else's critical path. T07 cannot complete without a real external origin, and this repository does not yet own an Ingress. This is the most likely cause of slip.
- Scope pressure toward an approvals inbox. The fastest way to close
KEY-WP-0013-T02is to build a queue with two buttons. That would satisfy the dependency and abandon the thesis. T04 exists to make the cost of that visible.