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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions