Skip to content

exclude_labels not re-checked between continuation turns — blocked issues re-dispatched up to max_turns #1

Open

Description

@cbeaulieu-gt

Summary

When a tracked issue receives a label listed in tracker.exclude_labels mid-run (i.e. the agent applies the label during a turn rather than it being present at poll time), Baton continues to re-dispatch that issue as continuation turns up to agent.max_turns. The newly-applied exclude label does not stop the in-flight run. In practice an issue that the agent blocks on its first turn still costs ~max_turns agent invocations.

Environment

  • Baton (symphony) installed editable from main (pip install -e ".[dev]"), early June 2026.
  • Agent command: claude (Claude Code CLI), permission_mode: bypassPermissions.
  • Python 3.11, Linux.
  • Relevant WORKFLOW.md config:
    tracker:
      labels: ["agent-ready"]
      exclude_labels: ["blocked"]
    agent:
      max_turns: 3

Observed vs. expected

Observed: An issue is dispatched (carries agent-ready, not blocked). During turn 1 the agent decides it cannot proceed, posts a clarifying comment, and applies the blocked label, then stops. Baton then runs turn 2 and turn 3 (continuation turns) for the same issue, even though blocked is now present and blocked ∈ exclude_labels. The run only ends because max_turns is reached.

Expected: Once an issue carries a label in exclude_labels, it should no longer be eligible for further work. A mid-run block should stop the continuation loop, so a blocked issue costs ~1 agent invocation, not ~max_turns.

Reproduction

  1. Configure WORKFLOW.md as above: a dispatch label (agent-ready), exclude_labels: ["blocked"], and max_turns: 3.
  2. Create an issue and apply the dispatch label so Baton picks it up.
  3. Make the agent apply the blocked label during turn 1 and stop (e.g. include a prompt instruction: "if any acceptance criterion is ambiguous, post a comment, add the blocked label, and stop"). An issue with a genuinely ambiguous requirement reliably triggers this.
  4. Watch Baton's run for that issue.

Result: Baton dispatches continuation turns 2 and 3 for the issue after blocked was applied in turn 1 — three agent invocations total for an issue that blocked immediately.

Diagnostic observations (no fix proposed)

These are external observations from the run, shared to narrow down the behavior — not a prescription:

  • exclude_labels appears to be evaluated at poll/dispatch time (when selecting which issues to start), and does not appear to be re-checked between continuation turns of an already-started run. A label that becomes true mid-run is therefore not seen until (at best) the next poll, by which point the continuation loop for the current run has already spent its turns.
  • The continuation loop runs up to max_turns regardless of label state changes that occur during the run.
  • The cost is bounded by max_turns: with max_turns: 3, a turn-1 block consumed three agent invocations.

I'm happy to provide full run logs or test against a specific commit if that helps narrow it down.

🤖 Generated by Claude Code on behalf of @cbeaulieu-gt

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