Skip to content

fix(dag): pause must stop already-queued nodes from spawning #379

Description

@LeXwDeX

Problem

The documented pause contract says pause prevents new nodes from spawning, but the spawn fiber does not re-check workflow pause state after a node has already been queued. The only pause gate is scheduler admission, so a queued node can still claim adoption and create a child session while the workflow reports paused.

User Impact

Pausing an out-of-control or expensive workflow does not reliably stop new work. Nodes admitted just before pause can continue creating sessions and consuming quota, contradicting the control response and user expectation.

Evidence

  • packages/opencode/src/dag/runtime/spawn.ts:385-431: permit acquisition flows to tryClaimAdoption and sessions.create without a pause check.
  • packages/core/src/dag/core/scheduling.ts:155-156: getReadyNodes is the only pause admission gate.
  • packages/core/src/dag/store.ts:215-224: queued adoption is allowed while the workflow can be paused.
  • packages/core/src/dag/projector.ts:29-46: queued to running remains a legal projected transition.
  • packages/opencode/src/dag/dag.ts:327-338: guardNode checks terminal/transition legality, not pause state.
  • packages/opencode/src/tool/workflow.ts:768 and packages/core/src/plugin/command/orchestration-policy.md:333: user-facing contract says pause prevents new node spawning.

Fix Requirements

  1. In the spawn fiber, re-read/revalidate workflow pause state after permit acquisition and before tryClaimAdoption or sessions.create. Follow the existing spawn-admission isolation pattern near spawn.ts:410-420.
  2. If paused, release the permit and return without terminalizing the node; it must remain queued.
  3. Preserve the current contract that already-running nodes continue until completion.
  4. Preserve resume behavior: queued nodes must become eligible and spawn after control(resume).
  5. Add a runtime regression test under packages/opencode/test/dag/, using dag-wake-integration.test.ts fixtures where useful.

Non-goals

  • Do not alter tryClaimAdoption state sets, scheduler admission, projector transitions, state-machine vocabulary, or pause copy.
  • Do not change the TUI.

Acceptance Criteria

  • Given a paused workflow with a persisted queued node, the spawn fiber does not call sessions.create.
  • The skipped node remains queued and is not failed/cancelled.
  • After resume, that node spawns and can complete.
  • Existing DAG runtime behavior and tests remain green.

Likely Code Locations

  • packages/opencode/src/dag/runtime/spawn.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