Open INFD-WP-0004 and draft the flex-auth list-action request (INFD-IN-0008)

The live overview is refused on every row: compact-sitting v2 gates read
with a 900 s MFA window and does not name the T03 memos. Propose a
limited-disclosure list action with a comfortable bar; read and every act
stay strict.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 359683@bnt-lap001
Assistant-Session: eebdc939-7a9b-4e50-9d39-c8437e8a14ec
This commit is contained in:
tegwick 2026-09-21 22:45:07 +02:00
parent 77792fa4f5
commit c9c05e595b
3 changed files with 245 additions and 0 deletions

View file

@ -0,0 +1,114 @@
# Request to flex-auth: a `list` action for the decision overview
**From:** informed-decision (`INFD-WP-0004`, intake `INFD-IN-0008`)
**To:** flex-auth, as the owner of the `informed-decision.*` policy packages
**Date:** 2026-09-21
**Status:** draft, not yet sent
## What we ask
Please admit a policy for a new consumer action, **`list`**, on
`decision-memo` resources of system `informed-decision`. The identity bar for
`list` should allow comfortable browsing, and it should cover the memos of
**both** admitted packages (`informed-decision.t03-review` and
`informed-decision.compact-sitting`). This repository proposes the rule;
flex-auth decides it. Nothing here grants anything until you publish a
package, version and digest.
## Why
`INFD-WP-0003` put a decision overview on the signed-in home page. Each row
asks Flex Auth for `read`, the same action that gates rendering a memo for
binding. Since 2026-09-21 the review deployment points at
`informed-decision.compact-sitting` v2. In production this has two
consequences:
1. **Every row is refused, even after the operator signs in again.** The
`read` rule requires `age <= 900` on `assurance.at`. KeyCape copies the
previous session's timestamp even after an actual MFA (`INFD-IN-0005`).
Authelia 4.38 cannot be made to force reauthentication (`cbea539`). So a
browsing session usually cannot meet a bar designed for binding.
Confirming this against the live policy observations is pending.
2. **The three `SECRETS-WP-0010-T03-*` memos are out of scope for good.** They
were admitted under `informed-decision.t03-review`. The served sitting
package does not name them, so their own reviewer cannot see their outcome.
Looking back at your own decisions should not need to meet the bar for signing
a new one. Binding keeps its strict bar. Only the list gets a lighter one.
## The consumer contract for `list`
The request shape is unchanged (`docs/flex-auth-review-contract.md`): the same
closed profile, caller, subject object and memo resource, and the same
`context` (`memo_version`, `approval_id`, `approval_binding_digest`). Only
`action` is `"list"`. It is one request per memo row. There is no wildcard and
no collection resource.
After an `allow` for `list`, the consumer shows **only** the following:
- memo id and version, and the memo's question;
- the live Approval Engine status, read by the approval id the memo carries;
- the requesting person's own recorded responses on that memo: verb, memo
version, time and submission state. Notes are excluded.
It does **not** show the brief, terms, justification, highlights, packet,
attachments or anyone else's responses. A `list` allow never enables
`acknowledge` or any disposition. Opening the memo for review still asks
`read`, and every act still asks its own action under the current strict rules.
The consumer still requires `memo.binding.principal.id == subject` before it
asks. That structural match is not an entitlement.
## Proposed rule
Identity: the same as today, minus the freshness window.
```rego
input.subject.type == "human"
input.subject.tenant == "tenant:platform"
input.subject.attributes.principal_type_source == "authentication-derived"
input.subject.attributes.tenant_source in {"registration-supplied", "directory-asserted"}
"net-kingdom-admins" in input.subject.attributes.groups
input.subject.attributes.assurance.level == "aal2"
input.subject.attributes.assurance.mfa == true
input.subject.attributes.assurance.source == "key-cape"
# no `age <= 900` for list
input.action == "list"
```
For the resource, the owner can choose between two scopes:
- **(A) Resource-type-wide.** This covers any `decision-memo` of system
`informed-decision` in `tenant:platform`. It needs no package revision per
sitting. It relies on the consumer's structural recipient match to keep other
people's memos out of a person's list. **The consumer prefers this option
for comfort.**
- **(B) Exact-record union.** This covers the eight sitting records plus the
three T03 records, pinned by approval id and binding digest as today. It is
tighter. It needs a new version every time a sitting adds memos. It would
also need to accept T03's memo version 2, whereas the sitting rule pins
`memo_version == 1`.
Either option could ship as a new version of the served sitting package (v3),
which also keeps `read` and every act exactly as in v2. It could also ship as
a separate package, but then the consumer would need a second PDP pin, because
the runtime carries only one package pin today. The consumer prefers **v3 of
`informed-decision.compact-sitting`**.
## What informed-decision delivers on its side
- `list` in `policy.ACTIONS` and in the consumer contract document;
- an overview that asks `list`, shows only the fields above, and still asks
`read` on the review page;
- positive and negative fixtures for flex-auth: stale MFA allowed for `list`
but refused for `read`; no group refused; agent refused; and, under option
(B), an unlisted memo refused;
- after your package lands, the admission input is updated to the new
package, version and digest, and the rollout is recorded.
## Disclosure trade-off (for the owner to weigh)
With option (A), a person holding any AAL2 session in `net-kingdom-admins` can
see the questions and statuses of memos addressed to them, without a
15-minute-fresh MFA. Today that needs fresh MFA. Brief, packet and all binding
stay behind the strict bar.

View file

@ -443,3 +443,34 @@ description: >-
repository takes Staff either way and is not asking to be moved.
state_hub_intake_id: "01a0c23e-bd53-7ee0-9357-b223aa554842"
```
## INFD-IN-0008 — Admit a `list` action so decisions can be reviewed comfortably
```yaml
id: INFD-IN-0008
kind: intake
title: Admit a `list` action so decisions can be reviewed comfortably
status: open
origin: demand
origin_ref: INFD-WP-0004
priority: high
owner: flex-auth
repo: informed-decision
lane: blue
tags:
- cross-repo
- policy-request
created: '2026-09-21'
updated: '2026-09-21'
description: >-
The INFD-WP-0003 decision overview asks Flex Auth for `read` on each memo, and
the served compact-sitting v2 package refuses every row in production. Its
900-second MFA window is designed for binding, and KeyCape carries forward
earlier authentication timestamps (INFD-IN-0005). It also does not name the
three SECRETS-WP-0010-T03 memos. ASK: admit a `list` action with the same
identity bar minus freshness. It should cover memos from both admitted
packages, preferably as compact-sitting v3 with a resource-type-wide scope.
`read` and every act stay unchanged. Full request, disclosure limits and
fixtures: docs/flex-auth-request-list-action.md.
```

View file

@ -0,0 +1,100 @@
---
id: INFD-WP-0004
type: workplan
title: "Comfortable decision review — a `list` action for the overview"
domain: infotech
repo: informed-decision
status: active
owner: claude
topic_slug: netkingdom
created: "2026-09-21"
updated: "2026-09-21"
related:
- INFD-WP-0003
- INFD-IN-0005
- INFD-IN-0008
origin: demand
origin_ref: "founder 2026-09-21: 'We should be able to review comfortably though.'"
---
# Comfortable decision review
The `INFD-WP-0003` overview is live, but in production every row shows "The
permission service refused access", even after a fresh sign-in. Each row asks
Flex Auth for `read`. The served `informed-decision.compact-sitting` v2
package gates `read` with a bar designed for binding:
- The rule requires `assurance.at` to be at most 900 seconds old. KeyCape
carries earlier authentication timestamps forward (`INFD-IN-0005`), so a
browsing session rarely meets it.
- The package does not name the three `SECRETS-WP-0010-T03-*` memos at all.
The founder wants to be able to review decisions comfortably. The plan is to
split *seeing your decisions* from *reviewing one for binding*:
- Add a new consumer action, `list`, with limited disclosure. It has a
comfortable identity bar, and flex-auth admits it.
- `read` and every act keep their strict bar.
## Establish why today's rows are refused
```task
id: INFD-WP-0004-T01
status: wait
priority: high
```
Waiting on the operator's read-only query of the live `policy_observations`:
`auth_age_s`, groups, level and methods for the latest checks. If the age is
over 900, `INFD-IN-0005` is confirmed as the cause for the eight sitting memos.
If a group, level or method differs from the rule, that is a separate identity
regression and needs fixing regardless of `list`. Record the finding under
`docs/evidence/`.
## Request the `list` policy from flex-auth
```task
id: INFD-WP-0004-T02
status: progress
priority: high
```
The request is drafted in `docs/flex-auth-request-list-action.md` and recorded
as `INFD-IN-0008`, owned by flex-auth. Send it to the flex-auth inbox once the
founder approves the draft. Done when flex-auth publishes a package, version
and digest that answers `list`, with fixtures.
## Consumer side: `list` action and limited-disclosure overview
```task
id: INFD-WP-0004-T03
status: todo
priority: high
```
- Add `list` to `policy.ACTIONS` and to `docs/flex-auth-review-contract.md`.
- The overview asks `list` per row instead of `read`. It renders only the memo
id and version, the question, the live engine status, and the person's own
responses (verb, version, time and submission state; no notes).
- The review page keeps `read`, and every act keeps its own action.
- Tests: `list` allowed while `read` is denied still shows the rows, and
opening one is still refused; a `list` deny redacts the row; no brief,
packet or notes leak on the home page.
This task can be built and tested against fixtures before T02 lands, but it
must not be deployed before T02. The live v2 package denies `list`, so
deploying early would change nothing visible.
## Admit and roll out
```task
id: INFD-WP-0004-T04
status: wait
priority: high
```
After T02, update `deploy/sitting-admission.json` with the new package,
version and digest. The operator then applies the configuration and the image
built from T03. Verify that the overview shows all eleven memos without a fresh
MFA, that opening a memo still enforces the strict `read` rule, and record the
rollout in `docs/evidence/`.