From 3e0d3d5ebfc40706cc2b846e9cab6b38739e2738 Mon Sep 17 00:00:00 2001 From: tegwick Date: Mon, 21 Sep 2026 22:12:27 +0200 Subject: [PATCH 1/3] Keep the home memo form when the decision overview fails The overview is orientation only; a store, policy or engine failure while listing now shows a notice instead of an error page, so the memo form and sign-out stay reachable. Co-Authored-By: Claude Opus 5 Assistant: claude-code Assistant-Model: opus Assistant-Process: 359683@bnt-lap001 Assistant-Session: eebdc939-7a9b-4e50-9d39-c8437e8a14ec --- informed_decision/web.py | 15 ++++++++++++++- tests/test_review_controller.py | 8 ++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/informed_decision/web.py b/informed_decision/web.py index 6730947..b3ea736 100644 --- a/informed_decision/web.py +++ b/informed_decision/web.py @@ -188,7 +188,7 @@ class App: if method == "GET" and path == "/": if session: content = (f"

Signed in as {html.escape(session.subject)}.

" - + (overview_section(self.review.overview(session)) if self.review is not None else '') + + (self._overview(session) if self.review is not None else '') + ('

Open a decision review

Enter the memo identifier supplied with your review request.

' '
' '
' if self.review is not None else @@ -201,6 +201,19 @@ class App: return 200, document("Informed Decision", content, session.subject if session else None), "text/html", [] return 404, "Not found.", "text/plain", [] + def _overview(self, session): + # The overview is orientation only. Its failure must never take the + # memo form, sign-out or an unresolved-entry recovery path with it. + try: + return overview_section(self.review.overview(session)) + except ReviewError as exc: + if exc.code == "session_expired": + raise + except (PolicyError, ApprovalEngineError, StoreError, sqlite3.Error, ValueError, KeyError, TypeError): + pass + return ('

Your decisions

Your decisions could not be ' + 'listed right now. You can still open a review by its memo identifier.
') + def _form(self, environ, session): if environ.get("HTTP_ORIGIN") != ORIGIN: raise ReviewError(403, "invalid_form") diff --git a/tests/test_review_controller.py b/tests/test_review_controller.py index eda21b9..f737cd7 100644 --- a/tests/test_review_controller.py +++ b/tests/test_review_controller.py @@ -407,3 +407,11 @@ def test_home_without_session_shows_sign_in_only(review): r=call(app,'/') assert 'Sign in with KeyCape' in r['body'] and 'Your decisions' not in r['body'] assert controller.store.policy_observations()==[] + + +def test_home_keeps_the_memo_form_when_the_overview_fails(review,monkeypatch): + controller,session,app,*_=review + def broken(subject):raise sqlite3.OperationalError('disk') + monkeypatch.setattr(controller.store,'memos_for',broken) + r=home(review) + assert r['status']==200 and 'could not be listed right now' in r['body'] and 'Open a decision review' in r['body'] From ac0a4e2fb0c30416535abbe704b354e75ff83e67 Mon Sep 17 00:00:00 2001 From: tegwick Date: Mon, 21 Sep 2026 22:16:02 +0200 Subject: [PATCH 2/3] Record the published decision-overview image (not yet rolled out) Co-Authored-By: Claude Opus 5 Assistant: claude-code Assistant-Model: opus Assistant-Process: 359683@bnt-lap001 Assistant-Session: eebdc939-7a9b-4e50-9d39-c8437e8a14ec --- docs/evidence/2026-09-21-decision-overview-image.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 docs/evidence/2026-09-21-decision-overview-image.json diff --git a/docs/evidence/2026-09-21-decision-overview-image.json b/docs/evidence/2026-09-21-decision-overview-image.json new file mode 100644 index 0000000..3d773a9 --- /dev/null +++ b/docs/evidence/2026-09-21-decision-overview-image.json @@ -0,0 +1,11 @@ +{ + "task": "INFD-WP-0003", + "source_commit": "3e0d3d5", + "change": "Signed-in home page lists the reviewer's decision memos grouped as needs attention, open, accepted, declined, returned, closed or not available, with fallback to the memo form if listing fails. UI_RELEASE unchanged (informed-decision@0.2.0); store schema unchanged (v2); no new write path.", + "validation": "433 tests passed with actual Approval Engine, Audit Core and Flex Auth; Chromium harness 13/13; container smoke 11/11; Trivy 0.74.0 HIGH/CRITICAL: 0 findings.", + "image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:971e88e3c7b68b370f4d7ef14824cc0e19c854b5aeb372e7ec7edbcf2c847b31", + "previous_live_image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:ef6fdd61209863654be3adba070661645a2714e86cb4b7f4e847540291b55f07", + "published": true, + "rolled_out": false, + "remaining": "Operator pre-rollout inspect/backup and rollout; agent production access was not granted." +} From 77792fa4f577a35c8b3b5b7ff1144c205898ec0b Mon Sep 17 00:00:00 2001 From: tegwick Date: Mon, 21 Sep 2026 22:32:19 +0200 Subject: [PATCH 3/3] Record the decision-overview rollout and pin its image in admission inputs Operator rolled out sha256:971e88e3 after a pre-rollout inspect (7 confirmed, no unresolved submissions) and an in-volume backup. README backup path now matches the deployment, which mounts no /backup volume. Co-Authored-By: Claude Opus 5 Assistant: claude-code Assistant-Model: opus Assistant-Process: 359683@bnt-lap001 Assistant-Session: eebdc939-7a9b-4e50-9d39-c8437e8a14ec --- deploy/README.md | 5 ++-- deploy/sitting-admission.json | 2 +- deploy/t03-admission.json | 2 +- .../2026-09-21-decision-overview-image.json | 23 +++++++++++++++++-- 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/deploy/README.md b/deploy/README.md index adf2061..2e169d0 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -164,11 +164,12 @@ The installed `informed-decision-admin` supports local custody operations only: ```sh informed-decision-admin inspect --db /data/private/review.sqlite -informed-decision-admin backup --db /data/private/review.sqlite --output /backup/private/review.sqlite +informed-decision-admin backup --db /data/private/review.sqlite --output /data/private/review-YYYYMMDD.sqlite ``` The backup parent must already be owned/private 0700; the destination must not -exist. Backup uses SQLite's consistent backup API while the service may be live. +exist. The deployment mounts no `/backup` volume; `/data/private` qualifies but +shares the PVC, so copy the file off-cluster (`kubectl cp`) for an independent copy. Backup uses SQLite's consistent backup API while the service may be live. Do not copy a running SQLite file while ignoring WAL. Inspection prints counts and schema version, not memo content or credentials. These are privileged operator custody commands, not browser endpoints. An independent backup copy, diff --git a/deploy/sitting-admission.json b/deploy/sitting-admission.json index c168ab7..d72b9a5 100644 --- a/deploy/sitting-admission.json +++ b/deploy/sitting-admission.json @@ -1,5 +1,5 @@ { - "image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:ef6fdd61209863654be3adba070661645a2714e86cb4b7f4e847540291b55f07", + "image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:971e88e3c7b68b370f4d7ef14824cc0e19c854b5aeb372e7ec7edbcf2c847b31", "policy": { "origin": "http://flex-auth-informed-decision-sitting.flex-auth.svc.cluster.local:8080", "package": "informed-decision.compact-sitting", diff --git a/deploy/t03-admission.json b/deploy/t03-admission.json index 0ae98f0..29a22ae 100644 --- a/deploy/t03-admission.json +++ b/deploy/t03-admission.json @@ -1,5 +1,5 @@ { - "image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:ef6fdd61209863654be3adba070661645a2714e86cb4b7f4e847540291b55f07", + "image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:971e88e3c7b68b370f4d7ef14824cc0e19c854b5aeb372e7ec7edbcf2c847b31", "policy": { "origin": "http://flex-auth-informed-decision-t03.flex-auth.svc.cluster.local:8080", "package": "informed-decision.t03-review", diff --git a/docs/evidence/2026-09-21-decision-overview-image.json b/docs/evidence/2026-09-21-decision-overview-image.json index 3d773a9..b92a7e2 100644 --- a/docs/evidence/2026-09-21-decision-overview-image.json +++ b/docs/evidence/2026-09-21-decision-overview-image.json @@ -6,6 +6,25 @@ "image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:971e88e3c7b68b370f4d7ef14824cc0e19c854b5aeb372e7ec7edbcf2c847b31", "previous_live_image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:ef6fdd61209863654be3adba070661645a2714e86cb4b7f4e847540291b55f07", "published": true, - "rolled_out": false, - "remaining": "Operator pre-rollout inspect/backup and rollout; agent production access was not granted." + "rolled_out": true, + "remaining": "Human sign-in view of the overview not yet observed by the agent.", + "rollout": { + "by": "operator", + "strategy": "Recreate via kubectl set image", + "pre_rollout_inspect": { + "schema_version": 2, + "outbox": { + "delivered": 50 + }, + "submissions": { + "confirmed": 7 + } + }, + "pre_rollout_backup": "/data/private/review-20260921-pre-overview.sqlite (same PVC; consistent_snapshot true)", + "post_rollout": { + "ready_replicas": 1, + "healthz": "ok", + "readyz": "ready" + } + } }