Flow engine: fix loop routing, edge serialization, approval routing & permissions; add approvals inbox#397
Draft
esafwan wants to merge 1 commit into
Draft
Flow engine: fix loop routing, edge serialization, approval routing & permissions; add approvals inbox#397esafwan wants to merge 1 commit into
esafwan wants to merge 1 commit into
Conversation
…oval routing/permissions; add approvals inbox bell - Engine: honor loop executor next_node_id; reject decisions no longer follow approval-path edges; approval_type 'user'/'users' treated as synonyms in notifications, permission checks, and pending-approvals API - Validation: allow trigger.schedule and trigger.doc-event node types - Permissions: Huf Manager can create Flow Runs; approve endpoint requires read + approver identity; agent tool handlers enforce permissions and approver identity; webhook runs execute as flow owner instead of Guest - Builder: edge editor writes edgeType/condition keys the serializer reads, adds priority and approval-outcome (meta.outcome) controls; trigger types round-trip through the serializer - New ApprovalsBell in the unified header: pending-approvals inbox with badge, realtime + polled refresh, inline approve/reject, run deep link
This was referenced Jul 20, 2026
Contributor
Author
|
Rebased version of this PR is open as draft #408: your head commit cherry-picked cleanly onto current develop, plus two follow-ups identified during intake — |
4 tasks
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.
Summary
Fixes the highest-priority defects in the Flow system (engine routing, builder serialization, approval routing, permissions) and adds a pending-approvals inbox so human-in-the-loop steps are discoverable.
Engine (
huf/ai/flow_engine.py)next_node_id, soloop_node/done_nodeconfig was dead and loops never iterated. The dispatch now routes body-vs-done from the executor; a loop with nodone_nodecompletes the run gracefully.meta.outcome: rejectededge used to fall back to the success-edge path (the same path as approval). It now fails the run withApproval rejected by <user>[: comment]. The success-edge fallback applies only to approved decisions.approval_typespelling split fixed. Notifications matched only"users"while permission checks matched only"user", so UI-authored approvals got no notifications/inbox and API-authored ones got no enforcement. Both spellings are now accepted everywhere (notification fan-out,_verify_approval_permission,get_pending_approvals).Validation (
flow_definition.py)trigger.scheduleandtrigger.doc-eventadded toALLOWED_NODE_TYPES— these executors already exist and are advertised byget_node_schemas, but definitions using them could never be saved.Permissions (
flow_run.json,huf/ai/flow_api.py)createon Flow Run (previously only System Manager could start flows via the API).approve_flow_runnow requires read + approver identity instead of write, so a named approver with the Huf User role can actually approve.handle_run_flow,handle_get_flow_run,handle_resume_flow_run,handle_approve_flow_run) previously had no permission checks; they now mirror the REST endpoints, and the approve handler additionally verifies approver identity — an agent session can no longer self-approve unless its user is an authorized approver.Builder (
frontend/src)data.type/data.expressionwhile the serializer readdata.edgeType/data.condition, so every UI-saved edge silently becamealways— no expression edges, no failure routing. Keys are aligned, and the editor gains Priority and Approval Outcome (meta.outcome: approved/rejected) controls so approve/reject branching is authorable.context["status"] == "approved") instead of mustache syntax it rejects.trigger.schedule/trigger.doc-eventinstead of being flattened totrigger.webhook(and deserialize back correctly, with labels/icons).Approvals inbox (new)
ApprovalsBellcomponent mounted in the unified header on every page: shows a badge with the pending-approval count for the current user (first consumer of theget_pending_approvalsendpoint), refreshes onflow_paused/flow_completed/flow_errorrealtime events plus a 60-second poll, and offers inline Approve/Reject and an Open deep link to the run viewer.What to test
Loop
loop_node= a transform in the body,done_node= end) with a body→loop edge. Run it. Before: one pass then stop. Expect: 3 iterations then completion viadone_node.done_node: expect graceful Success after the last iteration.Edges
3. In the builder, set an edge to type
expressionwithcontext["x"] == 1, save, reload: type and condition must persist (before: reverted toalways).4. Add an
on_failureedge from a node that fails (e.g. bad HTTP request): the failure branch must be taken after save/reload.5. Set Priority on two competing edges and confirm the higher one wins.
Approvals
6. Flow with
human.approval(approval_type: user, a named approver): the approver must receive a notification and see the item in the bell inbox (before: neither).7. Author two outgoing edges with Approval Outcome
approvedandrejected; approve one run and reject another: each must follow its own branch.8. Reject a run that has only a plain edge after the approval: run must end Failed with "Approval rejected by …" (before: continued down the approve path as Success).
9. Bell: badge count updates when a run pauses (realtime) and after approve/reject from the popover; Open link lands on the run viewer.
10. As a Huf User who is the named approver: approving via API must succeed. As an agent whose session user is not an approver, the
approve_flow_runtool must be refused.Triggers
11. Save a flow whose entry is a schedule trigger, reload: it must save (no validation error) and stay a schedule trigger (before: unsavable; if forced, flattened to webhook).
Permissions / webhook
12. As Huf Manager, start a flow via the run API: must succeed (before: PermissionError).
13. Trigger a webhook flow containing an
agent.runnode: it must execute as the flow owner and the agent node must run (before: Guest → agent refused).Regression
14. Existing webhook-triggered flows, condition nodes, and the run viewer approve/reject buttons behave as before.
15.
cd frontend && npm run typecheckpasses; backend imports clean.