Skip to content

Atlas hook injects boulder continuation into task-spawned worker subagents #18681

Closed as not planned

Description

@sjawhar

Bug

The atlas hook's resolveActiveBoulderSession() adopts task-spawned worker subagent sessions into the active boulder, causing them to receive BOULDER_CONTINUATION_PROMPT directives that override their single-task constraint.

Reproduction

  1. Start a boulder session with an orchestrator (Sisyphus/Atlas) and a multi-task plan
  2. Orchestrator spawns 3 worker subagents via task(), each assigned a single task
  3. Worker finishes its task → goes idle → session.idle fires
  4. Atlas hook calls resolveActiveBoulderSession() which:
    • Finds the session in subagentSessions (all task() sessions are tracked there)
    • Walks parent chain via isSessionInBoulderLineage() → parent is the orchestrator → returns true
    • Appends the worker to boulderState.session_ids
  5. BOULDER_CONTINUATION_PROMPT is injected: "Read the plan file NOW... mark checkboxes... do not stop until all tasks are complete"
  6. Worker obeys the system directive, reads the full plan, and starts executing all remaining tasks
  7. All 3 workers do this independently → they race through the entire plan in parallel, stepping on each other's file edits

Root Cause

resolveActiveBoulderSession() in src/hooks/atlas/resolve-active-boulder-session.ts (lines 30-46) doesn't distinguish between:

  • The orchestrator session (should receive boulder continuation)
  • Worker subagent sessions spawned by task() (should NOT — they have their own single-task scope)

Since all task()-spawned sessions are in subagentSessions AND have a parent in boulderState.session_ids, they always pass the lineage check.

Regression Timeline

Date Commit What
Mar 9 vmxzmltv "fix(atlas): append idle subagent sessions to active boulder" Introduced the bug — removed agent-mismatch guard, added blanket subagentSessions.has() + appendSessionId
Mar 13 kovyrtor "fix(atlas): restrict idle-event session append to boulder-owned subagent sessions only" Narrowed blast radius with lineage check, but worker subagents still pass it

Affected Files

  • src/hooks/atlas/resolve-active-boulder-session.ts — the lineage-based adoption logic
  • src/hooks/atlas/boulder-session-lineage.ts — parent chain walker
  • src/hooks/atlas/idle-event.ts — calls resolveActiveBoulderSession on session.idle

Suggested Fix

resolveActiveBoulderSession should not adopt sessions found via subagentSessions into the boulder. Sessions that should participate in the boulder are explicitly registered in boulderState.session_ids at creation time. The lineage walk was intended to restrict adoption to boulder-descended subagents, but all task()-spawned workers are boulder-descended by definition.

Simplest fix: remove the lineage-based adoption block (lines 30-46 of resolve-active-boulder-session.ts) and update the corresponding test in idle-event-lineage.test.ts.

Activity

  1. added
    coreAnything pertaining to core functionality of the application (opencode server stuff)
    on Mar 23, 2026
  2. removed
    coreAnything pertaining to core functionality of the application (opencode server stuff)
    on May 3, 2026
  3. github-actions commented on Jul 4, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions