diff --git a/.changeset/u8-review-pending-park-node.md b/.changeset/u8-review-pending-park-node.md new file mode 100644 index 0000000000..f740d0174d --- /dev/null +++ b/.changeset/u8-review-pending-park-node.md @@ -0,0 +1,7 @@ +--- +"@runfusion/fusion": patch +--- + +summary: Declare the pending-review park as a step in the Legacy coding workflow, so it is visible in the editor. +category: internal +dev: Adds a `review-handoff` seam node (`review-pending-handoff`) plus `execute --outcome:review-pending--> review-pending-handoff --success--> end` to BUILTIN_CODING_WORKFLOW_IR. Inert — no seam returns `review-pending` yet; the behavior move lands separately once the step-session chain can surface the exit. diff --git a/packages/core/src/builtin-coding-workflow-ir.ts b/packages/core/src/builtin-coding-workflow-ir.ts index ec1966c8f2..cd2448a46f 100644 --- a/packages/core/src/builtin-coding-workflow-ir.ts +++ b/packages/core/src/builtin-coding-workflow-ir.ts @@ -100,6 +100,29 @@ const RAW_BUILTIN_CODING_WORKFLOW_IR: WorkflowIr = { codeReviewRemediationNode("in-progress"), completionSummaryNode("in-review"), { id: "review", kind: "prompt", column: "in-review", config: builtinPromptConfig("review", "Review") }, + /* + FNXC:WorkflowExecutionOwnership 2026-07-29-09:20 (U8 / R4 — workflow-owned lifecycle): + THE PENDING-REVIEW PARK, as a graph node. + + An implementation session can end because a step is blocked on a pending review: the agent + cannot continue, and the card belongs in review rather than in an error bucket (marking it + failed deadlocks a row that is both `in-review` and `failed`). Until now the EXECUTOR + performed that transition inline, mid-session, and the graph found out afterwards — which is + why `handleGraphFailure` carries `alreadyFinalizedToReview`, a classifier whose only job is + recognising a move the graph did not make. + + Declaring it here makes the ending a routed outcome instead of a side effect. It is a + `review-handoff` seam (a pure lifecycle handoff, no reviewer invocation) and its only edge is + to `end`, which is what preserves today's semantics exactly: hand the card to review and STOP. + Routing to the ordinary `review` node instead would have been wrong in a way worth recording — + the run would continue into merge-gate and merge-attempt on work whose steps are incomplete. + */ + { + id: "review-pending-handoff", + kind: "prompt", + column: "in-review", + config: builtinPromptConfig("review-handoff", "Park for pending review"), + }, { id: "merge-gate", kind: "merge-gate", column: "in-review", config: { gate: "auto-merge" } }, { id: "merge-retry", kind: "retry-backoff", column: "in-review", config: { policy: "merge", maxAttempts: 3 } }, { id: "merge-manual-hold", kind: "manual-merge-hold", column: "in-review", config: { release: "manual" } }, @@ -149,6 +172,17 @@ const RAW_BUILTIN_CODING_WORKFLOW_IR: WorkflowIr = { { from: "planning", to: "end", condition: "failure" }, { from: "plan-review", to: "plan-replan", condition: "failure" }, { from: "plan-replan", to: "plan-review", condition: "success", kind: "rework" }, + /* + FNXC:WorkflowExecutionOwnership 2026-07-29-09:25 (U8 / R4): + `outcome:` edges are matched on the node's VALUE and take priority over the generic + success/failure edges (`shouldTraverseEdge` / `traverseChildren`), so this claims the + pending-review ending without disturbing the `failure -> end` edge below it for every other + failure value. A workflow that does NOT declare this edge falls through to that generic + failure edge — i.e. exactly the pre-existing behavior — which is what lets custom workflows + keep working unchanged while the built-in routes the ending properly. + */ + { from: "execute", to: "review-pending-handoff", condition: "outcome:review-pending" }, + { from: "review-pending-handoff", to: "end", condition: "success" }, { from: "execute", to: "end", condition: "failure" }, { from: "browser-verification", to: "browser-verification-remediation", condition: "failure" }, { from: "browser-verification-remediation", to: "browser-verification", condition: "success", kind: "rework" }, diff --git a/packages/core/src/builtin-workflows.ts b/packages/core/src/builtin-workflows.ts index 8f44dc79e0..d52c5e0107 100644 --- a/packages/core/src/builtin-workflows.ts +++ b/packages/core/src/builtin-workflows.ts @@ -490,6 +490,8 @@ export const BUILTIN_WORKFLOWS: WorkflowDefinition[] = [ "code-review-remediation": { x: 910, y: 320 }, "completion-summary": { x: 1080, y: 160 }, review: { x: 1250, y: 160 }, + /* U8: the pending-review park sits off the main line — it is an exit, not a stage. */ + "review-pending-handoff": { x: 570, y: 320 }, "merge-gate": { x: 1420, y: 160 }, "branch-group-member-integration": { x: 1590, y: 80 }, "branch-group-promotion": { x: 1760, y: 80 },