Skip to content

fix(dag): extend must resume a paused workflow instead of stranding new nodes #381

Description

@LeXwDeX

Problem

workflow extend accepts new nodes on a paused workflow but neither resumes it nor produces a wake/resume instruction. The adjacent control replan path already detects pause, resumes automatically, and emits a pause note. Because paused workflows admit no nodes, a successful extend currently reports N nodes added and then leaves those nodes silently stranded.

User Impact

The natural “pause, inject corrective work, continue” journey deadlocks without an obvious recovery action. Users receive a success response while the workflow remains indefinitely idle. This is especially costly for autonomous/low-cost agents that trust the tool response and wait for a wake event that cannot occur.

Evidence

  • packages/opencode/src/tool/workflow.ts:676-703 on origin/main: extend has no paused-state handling.
  • packages/opencode/src/tool/workflow.ts:736-752: replan already implements resumedFromPause and pauseNote.
  • packages/opencode/src/dag/dag.ts:712-787: _extend rejects terminal workflows but preserves paused state and accepts the added nodes.
  • packages/core/src/dag/core/scheduling.ts:156: paused workflows admit no ready nodes.
  • packages/opencode/src/dag/runtime/loop.ts:1232-1235,1417: wake/MUST-act surfaces do not provide a resume path for this state.
  • packages/core/src/dag/store.ts:143-149: wake eligibility does not rescue newly added nodes in a paused workflow.

Product Decision

A successful extend on a paused workflow must auto-resume, matching the established replan behavior. This is preferred over leaving the workflow paused with a prompt because it preserves the meaning of successful executable graph mutation and removes an extra state-dependent instruction from agents.

Fix Requirements

  1. After a successful dag.extend, detect whether the workflow was paused and mirror the replan branch: resume it and emit the same pauseNote pattern.
  2. Match replan race tolerance: log a warning and return advisory text if resume loses a race; do not turn a successful extend into a fatal error.
  3. Add a regression test for pause → extend → automatic resume → new node becomes schedulable, including the pause note.
  4. Keep running and terminal workflow extend behavior unchanged.

Non-goals

  • Do not change _extend terminal rejection/reopen semantics.
  • Do not alter wake predicates, projector transitions, or unrelated control actions.
  • Do not introduce a second alternative behavior that leaves the product decision to the implementer.

Acceptance Criteria

  • Extending a paused workflow leaves it resumed.
  • Newly added nodes become schedulable without a separate control(resume) call.
  • The tool response includes the established pause/resume note.
  • Resume races are non-fatal and produce the same warning/advisory behavior as replan.
  • Running and terminal workflow cases remain unchanged.

Likely Code Locations

  • packages/opencode/src/tool/workflow.ts
  • packages/opencode/test/dag/

Verification

cd packages/opencode && bun test test/dag/ && bun typecheck

Metadata

Metadata

Assignees

No one assigned

    Labels

    ready-for-agentFully specified and ready for an agent

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions