Propose INFD-WP-0003: my-decisions overview on the review home page
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:
parent
40654505c4
commit
2d6d338154
1 changed files with 115 additions and 0 deletions
115
workplans/INFD-WP-0003-my-decisions-overview.md
Normal file
115
workplans/INFD-WP-0003-my-decisions-overview.md
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
---
|
||||
id: INFD-WP-0003
|
||||
type: workplan
|
||||
title: "My decisions overview — pending memos and the outcome of past dispositions"
|
||||
domain: infotech
|
||||
repo: informed-decision
|
||||
status: proposed
|
||||
owner: claude
|
||||
topic_slug: netkingdom
|
||||
created: "2026-09-21"
|
||||
updated: "2026-09-21"
|
||||
related:
|
||||
- INFD-WP-0001
|
||||
- INFD-WP-0002
|
||||
origin: demand
|
||||
origin_ref: "founder request 2026-09-21: review decisions taken, whether they were accepted, and which are still open"
|
||||
---
|
||||
|
||||
# My decisions overview
|
||||
|
||||
Founder request 2026-09-21: in the informed-decision UI, see (a) the
|
||||
decisions I have taken and whether they were accepted, and (b) the decisions
|
||||
still open for me to take.
|
||||
|
||||
Today the signed-in home page offers only a free-text memo-identifier box
|
||||
(`informed_decision/web.py`, `GET /`). A person has to already know each memo
|
||||
id, and nothing shows the outcome of a past disposition unless that exact
|
||||
review is reopened.
|
||||
|
||||
## Why this does not breach the Stage 1 boundaries
|
||||
|
||||
- **Not an approval-engine inbox.** The list is built from memos that
|
||||
informed-decision itself holds, addressed to the signed-in subject
|
||||
(`memo.binding.principal.id`). approval-engine is still called get-by-id
|
||||
only, for approval ids those memos already carry. It never polls for work.
|
||||
- **Not owned approval state.** Engine status is read live on each render and
|
||||
never stored. Local state is limited to our own evidence: the disposition and
|
||||
the submission correlation (`submissions.state`, `approved_at`).
|
||||
- **Not a decision point.** The overview decides nothing. Every row goes
|
||||
through the same fresh PDP `read` check that `ReviewController.open` uses
|
||||
before any memo content is rendered. If that check is denied or unavailable,
|
||||
the row shows the memo id and "not available" and nothing else (fail closed).
|
||||
- **Not a binding view.** The overview creates no presentation record.
|
||||
Binding still happens only on the existing review page.
|
||||
|
||||
## Row classification (latest memo version, addressed to me)
|
||||
|
||||
| Group | Condition |
|
||||
|---|---|
|
||||
| **Needs attention** | submission `in_flight` / `unresolved`: outcome unconfirmed, operator recovery |
|
||||
| **Open for you** | no accept/decline by me on the latest version, no submission, engine status `requested`/`approved` |
|
||||
| **Decided — accepted** | submission `confirmed` (show `approved_at`) plus live engine status (`approved`, `consumed`, …) |
|
||||
| **Decided — declined** | decline disposition on the latest version |
|
||||
| **Returned / discussion** | return/discuss on the latest version with no newer version yet (awaiting revision) |
|
||||
| **Closed without you** | engine status `expired`/`revoked`/`superseded` and no disposition by me |
|
||||
|
||||
Each row links to the existing review (`/review?memo_id=…`), which already
|
||||
recovers the original presentation when an intent exists. The earlier
|
||||
dispositions on older memo versions appear as a short history under the row.
|
||||
|
||||
## Store listing for the signed-in subject
|
||||
|
||||
```task
|
||||
id: INFD-WP-0003-T01
|
||||
status: todo
|
||||
priority: high
|
||||
```
|
||||
|
||||
Add `Store.memos_for(subject)`, which returns the latest version of every memo
|
||||
whose binding principal is `subject` (a `person`). Add
|
||||
`Store.dispositions_by(subject, memo_id)`, which returns that subject's
|
||||
dispositions across all versions, together with any submission row. This is
|
||||
read-only. Tests go in `tests/test_durable_store.py`.
|
||||
|
||||
## Controller overview with per-row PDP read and live engine status
|
||||
|
||||
```task
|
||||
id: INFD-WP-0003-T02
|
||||
status: todo
|
||||
priority: high
|
||||
```
|
||||
|
||||
Add `ReviewController.overview(session)`, which returns classified rows. Each
|
||||
row gets its own `_authorize(session, memo, "read")` and `get_approval`. A row
|
||||
whose PDP check fails is redacted to its id only. A failure of the approval
|
||||
engine on one row only degrades that row's status to "status unavailable". It
|
||||
never degrades the whole page. The overview never creates a presentation. Tests
|
||||
go in `tests/test_review_controller.py`, using the existing fakes: allow, deny,
|
||||
policy unavailable, engine down, and each classification.
|
||||
|
||||
## Home page rendering
|
||||
|
||||
```task
|
||||
id: INFD-WP-0003-T03
|
||||
status: todo
|
||||
priority: high
|
||||
```
|
||||
|
||||
When a review is configured and the person is signed in, `GET /` renders the
|
||||
overview grouped as above, with open items first. The manual memo-id form stays
|
||||
below the overview as a fallback. This is server-rendered only: no scripts, the
|
||||
same CSP, all text escaped. Tests: a WSGI test in `tests/test_browser_auth.py`
|
||||
or `test_review_component.py`, plus one Chromium check in
|
||||
`tests/browser_review.mjs` if that harness is cheap to extend.
|
||||
|
||||
## Docs and scope
|
||||
|
||||
```task
|
||||
id: INFD-WP-0003-T04
|
||||
status: todo
|
||||
priority: medium
|
||||
```
|
||||
|
||||
Update `docs/protected-browser-review.md` and `SCOPE.md` with the overview and
|
||||
the boundary argument above.
|
||||
Loading…
Add table
Add a link
Reference in a new issue