# SCOPE > Implemented-and-first-cut boundary for agents and contributors. Aspirational > direction belongs in `INTENT.md`; the current stage belongs in `GOAL.md`; > current work and gates belong in `workplans/`. ## Requested expansion — 2026-10-04 (not implemented) The product now targets the full decision lifecycle for agents and humans with an API foundation and a UI at `decisions.coulomb.social`. See `docs/specs/DecisionLifecycleService.md` and `INFD-WP-0007`. Existing memo, presentation, disposition, storage, review and intake modules are reusable building blocks; they are not a complete headless lifecycle API. Research, evaluation, collaborative authoring, audience-scoped publication and revision workflows still need implementation. Frictionless intake has local implementation but its live delivery remains under `INFD-WP-0005`. The dated deployment snapshot below is historical, not a fresh observation of production. ## Status — 2026-09-27 **Deployed and in live use.** `decisions.coulomb.social` serves `forgejo.coulomb.social/coulomb/informed-decision@sha256:0557edff...` in namespace `informed-decision` on railiance01, behind `key-cape` and the `informed-decision.compact-sitting` Flex Auth package (currently v6). As observed today: the durable evidence store carries 99 delivered audit events and 15 confirmed human submissions; platform-root signed in and approved a memo through this exact surface. This status was last "not deployed" on 2026-09-11 — everything below it in this section was written against a production system, not a plan. 382 tests pass locally (66 skipped — the opt-in real-Approval-Engine suite, `INFD_APPROVAL_ENGINE_SOURCE`); 440 pass with that suite enabled, 8 skipped. 11/11 container checks. The 2026-09-21 milestone passed Chromium 13/13 and 433 tests against real Flex Auth/Approval Engine/Audit Core; no newer Chromium run has been recorded since. Four unrelated, pre-existing failures persist in both configurations (`waitress` not installed locally; one clock-adjacent browser-auth test) and are not this repository's regression. Component tests use actual Flex Auth, Approval Engine and Audit Core with synthetic identity/custody: - layer and stance declarations — `layer.yaml`, `pep-stance.yaml`, `informed_decision/stance.py`, with published-equals-shipped asserted; - the governed canonicalizer and schema, with the three published vectors reproducing byte for byte and all four isolation properties pinned; - the **domain core**: `memo.py` (the Decision Memo, its versions and the binding document), `presentation.py` (the sole writer of `view_hash`), `disposition.py` (the verb vocabulary and guards `G_NOAGENT`, `G_STEP`, `G_PRES`, `G_ACTOR`, `G_ACK`, `G_REASONS`, `G_SEALED`), `provenance.py` (claim routes, A-16), `evidence.py` (the local outbox and commitment records); - `approval_client.py` — the seam to `approval-engine` plus a fake; - `oidc.py` and `web.py` — public-client PKCE sign-in, verified human/MFA profile, bounded server-side sessions, protected cookies and CSRF sign-out; - `approval_http.py` and `http_transport.py` — get-by-id and human-entry transport, declared-control checks, real entry correlation, no consume route or automatic mutation retry. Protected browser actions use this adapter; - `store.py` / `records.py` — private durable packet/memo/presentation/ disposition storage, append-only acknowledgments, transactional outbox and submission correlation, safe reservation and backup/restore; - `audit.py` — idempotent Audit Core delivery, bounded retry/blocked states, explicit per-class count/time-basis comparison. Heartbeats are generated without hiding undelivered evidence; - `policy.py` / `review.py` / `ui.py` — fresh entitlement before rendering and actions, exact response pins, immutable observations, required highlights, accept/return/discuss/decline and visible original/unresolved entry state; - the **decision overview** on the signed-in home page (`INFD-WP-0003`): the reviewer's memos grouped as open, accepted, declined, returned, closed, needing attention or not available. Each row now asks `list`, not `read` (`INFD-WP-0004`) — a comfortable, 12-hour-fresh identity bar for *seeing* your decisions, separate from the strict 900-second bar `read`/`accept`/etc. keep for actually binding one. As of today each row also names the **requesting party** — approval-engine's `binding.principal`, the party the approval was issued on behalf of, distinct from the memo's own `binding.principal` (the reviewer being bound). The overview records nothing and never presents or binds; - `runtime.py` — explicit owner configuration, rotating credential-file readers, 30-second audit draining, heartbeat/reconciliation and delivery readiness. - `Containerfile`, `container.py`, `requirements.lock` and deployment renderer — a locally built/scanned image, private projected-config handoff, one serving writer, backup/inspection commands and eight review-only Kubernetes objects. Network-isolated container restart/restore preserves unresolved submissions. The durable `Store` supplies transactional atomicity for every write path; the legacy in-memory `evidence.Outbox` is a test double only, not part of the deployed path. `/readyz` requires an owner runtime configuration and recent audit delivery health — without either it returns 503 and rollouts are refused by the readiness probe, not merely warned. Two production incidents this repository did not cause, both diagnosed by reading `policy_observations` directly on the live pod rather than guessing: (1) `key-cape` was backdating a freshly-verified MFA to a stale `kc_login` session cookie (`INFD-IN-0005`), and, separately, (2) `key-cape`'s provider-metadata/JWKS discovery fetch was missing the split-horizon `X-Forwarded-Proto`/`X-Forwarded-Host` headers its token exchange already carried, which broke every login on Authelia 4.38 the moment a routine restart hit that code path. Both are fixed and deployed in `key-cape` (`911e9de`, `8be8065`); this repository's own review correctly treated both as upstream `policy_denied`/`LoginError` outcomes to relay, not decide. See [browser-authentication.md](docs/browser-authentication.md), [durable-review-evidence.md](docs/durable-review-evidence.md) and [protected-browser-review.md](docs/protected-browser-review.md). The [deployment packet](deploy/README.md) documents the render/dry-run candidate path; the actual live rollout is `docker build` → push to the Forgejo OCI registry → pin the digest in `deploy/sitting-admission.json` → `kubectl set image` (Recreate) → `kubectl exec` backup/inspect before and after, since there is no CI pipeline in this repository (unlike `key-cape`'s Forgejo Actions build-on-push). ## One-liner informed-decision is the presentation and binding surface for decisions: it renders a Decision Memo to the human who holds the mandate, records what was shown, and binds their identity to the act — and owns the browser-facing approver UI that `approval-engine` deliberately does not contain. ## Layer **Declared `layer: Staff`, role `pep-shaped`**, in `INTENT.md` frontmatter (governing) and `layer.yaml` (derived, marked as such, agreeing) — `GH-DEC-2026-017`, correcting the `layer: surface` this repository declared by elimination from 2026-09-09 to 2026-09-21 (§3's vocabulary is closed at four tokens; `surface` was never one of them). Not an Engine. Companion §5 owed, statute §6.4 in full — `GH-DEC-2026-012`'s shape ruling is unchanged by the layer correction. Open, no deadline, nothing waits on it: `INFD-IN-0007` asks how §3.4's "Staff is interactive and non-deterministic, and MUST NOT hold state another layer depends on at runtime" reaches a repository that is deterministic by test and holds presentation evidence `audit-core` depends on. The value is applied unconditionally either way; this asks only about the *fit*, for the next repository in this position. Coupled to this repository's own requested (not yet drafted) §4 catalog row. Separately, this repository approved two narrow §11 declaration-form amendments on 2026-09-27 (`GH-DEC-2026-021`: A11 r2 — `INTENT.md` frontmatter governs, a derived file must agree and disagreement is itself a finding; A12 r3 — no version *pin* in a declaration, but a prose citation like "outside §5 by the v0.5 scope rule" is provenance, not reached). Both were already this repository's practice; approving changed no file. It emits one PIP-like fact — *what was presented* — as a claim, under three limits that are the substance of the permission rather than caveats on it: 1. the claim carries presentation and nothing else, and must never carry, restate, summarise or imply a decision or verdict; 2. the claim must never be an input to the decision it presents for; 3. the evidence copy reaches `audit-core` **independently** of this repository. Limit 2 is load-bearing: the argument that a renderer attesting its own rendering is not self-dealing was accepted *because* that limit holds. ## Core Idea A decision surface is not a workflow engine and not a decision point. This repository owns the Decision Memo object, the presentation record, the canonicalization producing `view_hash` / `awareness_hash`, the disposition vocabulary, and the evidence bundle export. It does not evaluate whether an act is permitted, does not hold approval current-state, and does not archive the trail. ## In Scope — first cut (Stage 1) **Built and tested:** - Canonicalization of the binding and awareness documents, with the three published vectors reproducing byte for byte and all four isolation properties pinned (`tests/test_canonicalize.py`). - The Decision Memo schema and worked examples, governed under `schemas/`. - The unreachable-engine stance map, built to v0.8 obligation 3, with published-equals-shipped asserted by test (`tests/test_layer_conformance.py`). **Built with durable custody and protected HTTP integration:** - The presentation record: what was rendered, to whom, when, in which locale and UI release. - Required-highlight acknowledgment as a precondition of binding. - The disposition vocabulary and its legality tables. Only `accept` reaches `approval-engine`; `return`, `discuss`, `escalate` and the rest are memo-level. - The browser-facing OIDC client: authorization-code + S256 PKCE against `key-cape`, scopes `[openid, approval:read, approval:approve]`. - An L3 approver surface calling `approval-engine`'s approval-entry mutation. **Specified, not built:** - The evidence bundle as an offline-verifiable export. - German browser acceptance and the broader step/awareness UI. The current browser profile refuses unsupported locale/step/level rather than overstating it. ## Out of Scope - Authorization decisions — `access-engine`, always and only (statute §6). - The approval object, its state machine, validity and consumption — `approval-engine`. Never cached, never inferred, never `approval:consume`. - Approval doctrine — `gate-house`. - Identity and authentication — `key-cape`. Imported, never invented. The `assurance` shape is `key-cape`'s and is cited, not restated. - The evidence archive — `audit-core`. - Credentials materialized after a decision — `secrets-engine`. - Notification transport, ticketing, general workflow. - **An approvals inbox backed by `approval-engine`.** Foreclosed upstream as well as here: `approval-engine` exposes get-by-id only and will not add a list. The decision overview (Status, above) is not this — it lists *this repository's own memos*, sourced from the local `Store` plus a per-row `list` PDP check and get-by-id engine status, never a listing capability approval-engine itself provides. - L4/L5, QES, QTSP, qualified archival retention. - The mandate graph — so a Stage 1 `escalate` is an assertion, not a verified claim. ## What this repository does not claim Stated here because a scope file that only lists capabilities overstates them. - **The decision path is not validated.** `GH-DEC-2026-010` requires a decision be attributable to `access-engine`. `FLEX-WP-0024` (finished, 2026-09-14) now lets flex-auth sign an envelope when a key is configured — but this repository does not verify a signature anywhere in `policy.py`, and `store.py`'s schema hard-constrains `decision_attributable` to `0` (`CHECK(decision_attributable=0)`). The gap flex-auth closed on its side is still fully open on this one; nothing here must describe validation as complete. - **The residual is open.** A compromised surface can present X and attest Y. `GH-DEC-2026-012` states it is not closed and does not credit this repository with closing it. - **`view_hash` is not inside the approval entry.** `POST /entries` discards its body by design. Correlation is `(approval_id, subject, approved_at)`, so an auditor holding only the approval object cannot reach the presentation. - **Commitment-only evidence is not reconstructability.** `GH-DEC-2026-014` granted it for Stage 1 and bounded it: it satisfies non-alteration, and moves integrity out of our control while leaving *availability* entirely inside it. The party that can withhold the content is the party the evidence is about. Narrowed by the required existence assertion; not closed. - **The registration-bound tenant is a declared bounded gap**, not the terminal state. `GH-DEC-2026-013` ruled directory-sourced terminal and admitted `key-cape`'s shape because its distinguishing case fails closed. Build to it as transitional. - **Deployed does not mean contained.** This surface is live in production and observed there (see Status), but that observation is manual — `kubectl exec` plus `informed-decision-admin inspect`/`backup` around each rollout. There is no automated post-deploy verification, no CI pipeline in this repository, and no alerting wired to `/readyz` degrading. ## Open - **`INFD-IN-0005`, narrowed.** The two live-blocking defects it predicted (MFA backdated on reuse; a downstream fetch missing split-horizon headers) are fixed and deployed. The original ask — Authelia `prompt=login`/`max_age` support, so a step-up can be requested rather than merely checked after the fact, is complete in INFD-WP-0006, with live fresh-login/p01 acceptance. An actionable freshness error in the browser instead of the flat "Review unavailable" remains open in the existing intake record. - **`INFD-IN-0007`** — see Layer. No deadline. - **A reusable account/session-status component**, requested of `user-engine` as `USER-IN-0002` on 2026-09-27: identity, MFA-freshness, logout, to replace the bare "Signed in as uid=..." string and make the `list`-vs-`read` freshness split (see Status) legible instead of a silent wall. Not started; `user-engine` owns the data/API contract and whether it lands as a new small repository or inside an existing one. - **The decision_attributable gap** — see "What this repository does not claim." Unowned by anyone as an active task; recorded so it is not mistaken for closed now that flex-auth can sign. *Closed 2026-09-10:* the human token tenant (`GH-DEC-2026-013`, `key-cape` `329e48f`) and the evidence payload question (`GH-DEC-2026-014`). *Closed since, not previously recorded here:* native browser registration and human proof (`INFD-WP-0001-T08`) and `audit-core` custody/live delivery (`AUDIT-IN-0003`, `AUDIT-WP-0009`) — both live and observed in production as of this Status section. ## Offline workload intake — 2026-10-03 INFD-WP-0005 implements a separate workload-only WSGI intake application, injected TokenReview and create-only approval transports, per-request grant reload, per-submitter daily limits, and a schema-3 durable ledger. It atomically loads pinned memos and packet bytes and queues notification/posed jobs. Human terminal dispositions atomically queue optional hub resolution; a leased worker retries delivery with stable ids and leaves disabled/unconfigured adapters pending. An uncertain approval create never reposts automatically; retained receipts can resume local loading. Tests cover schema-1/2 upgrade, rollback, replay/restart, revocation and write-back. T07 also supplies opt-in scheduled delivery, matching hub message receipts and stable write keys, and immutable posed audit evidence with receipts, readiness, heartbeat and reconciliation. Actual Audit Core component tests exercise lost-reply deduplication and counts. This is local implementation, not a deployed intake listener. Attribute contracts, forwarding, workload custody, private listener composition and live acceptance are tracked as blocked tasks in INFD-WP-0005, with acceptance requirements in `docs/intake-dependency-requirements.md`.