Repository navigation
Conversation
Allowlist Flow's /api/save-approvals routes (list, signed task detail, exact screenshot, decision) behind /api/portal/save-approvals with the same session, origin and CSRF checks as attended decisions. Desktop forwards the phone's answer verbatim and adds no authority. Contract documented in docs/DECISION_PORTAL.md for the portal UI work to build on.
… into feat/phone-save-approval
This was referenced Oct 18, 2026
Member
Author
|
Closing: superseded by #212, merged. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Do not merge yet. Richard reviews the look first. Stacked on #208 (phone decision card) and #207 (save-approval relay, merged in). It targets
mainso CI runs, which means the diff also shows those two PRs. Merge them first; then this diff is only the save-approval screens. Depends on Flow's save-approval console routes in OpenAdaptAI/OpenAdapt#1234 (merge freeze). Against an older console the save routes return 404, and the phone treats that as "no saves".What changes
The approvals design is final: a workflow is admitted once, by a person or by a delegated agent under a policy a person signed, and after that runs stop only on problems. Approving every save stays as the strictest setting. This PR lets the paired phone answer that save with one tap, using the same card as a paused run.
risk_class, Save this form?, the workflow's step name, the exact screenshot ("Exactly what will be saved", zoomable), what happens next, then the answers.action,task_digest,task_signature, plusdecline_reasonon a decline. Flow forbids extra fields, and the payload matches them.request_not_waiting,request_unknownandalready_answeredshow "This save is no longer waiting".task_changedshows "This save changed" and offers to look again. Expired requests open as expired. Offline sends nothing.Fail-closed rules are unchanged: only signed allowed actions are offered, the digest and signature are echoed, Flow writes the answer once and the run re-reads the form before saving, expiry is enforced, nothing is queued offline, and no PHI goes into notifications. No contract fields were added.
Screens
The generator now renders save approvals as real shell states, not previews: request, cannot be undone, no picture, decline reasons, sending, approved, declined, no longer waiting, changed, not accepted, and connection lost, each in light and dark. The docs set adds
save-approvalandsave-approvedin both schemes. Business decision is still the only preview.Tests
src/portalShell.test.ts: 12 new tests (one-tap payload, decline reasons closed and filtered, no picture means no approve, irreversible means no emphasis, gone, changed, expired, offline, wrongtask_kind, older runner without save routes)tests/test_portal/test_phone_captures.py: the save fixtures match Flow's task, and save screens are shell states rather than previewspytest tests/1399 passed, 1 skipped ·npm run test:ui371 passed ·npm run buildok ·ruff checkclean