Skip to content

'Worker said:' empty in early no-progress exit alerts — supervisor lacks signal for early intervention #540

@HenryLach

Description

@HenryLach

Summary

When a worker requests exit_intercepted with no progress, the alert delivered to the supervisor includes a Worker said: field meant to convey the worker's stated reason for wanting to exit. In production observation, this field is empty ("") on the early no-progress iterations — the supervisor has no signal about why the worker is stuck and cannot make an informed steering decision until the worker has already cycled through multiple iterations.

By the time the field has content, the worker has typically already burned through 2–3 iterations and is closer to the orch's no-progress kill-threshold than to a clean recovery.

Reproduction

  1. Induce any worker confusion (most reliably via the workflow gap in issue Worker spins indefinitely when code review returns REVISE on a step already marked complete in STATUS #537: cause review_step to return REVISE on a step the worker has already marked complete in STATUS).

  2. Worker enters its first no-progress iteration. Supervisor receives:

    🔄 Worker on lane 1 wants to exit with no progress.
      Task: ...
      Current step: ...
      Iteration: 4, No-progress count: 1
      Unchecked items: ...
      Worker said: ""
    
  3. The supervisor has no information about what the worker tried, what it found confusing, or what state it observed. To make a steering decision, the supervisor must:

    • Read the worktree's events.jsonl
    • Inspect recent commits
    • Read STATUS.md
    • Read the most recent .reviews/ files
    • Check git status / git diff

    This is 5+ tool calls just to get back to the same context the worker presumably had, before the supervisor can write a useful steering message.

Concrete evidence

Production batch 20260506T105850 — 4 of 5 "wants to exit" alerts had empty Worker said: "":

Alert Iteration No-progress count Worker said
1 4 1 ""
2 4 1 "" (replay)
3 5 2 ""
4 4 1 "" (replay)
5 6 3 "The supervisor told me Step 2 is complete (do not redo) — focus on Step 3. Let me look at the DemoForm."

Note that the only message with content (#5) was from a prior iteration — it was the worker echoing the steering message the supervisor had sent earlier, not a fresh articulation of why it now wanted to exit. By the time it surfaced, the orch was about to kill the lane.

Why this matters

Effective supervisor intervention requires understanding the worker's confusion. With an empty payload, the supervisor's first instinct is "tell the worker to keep trying" — which is exactly the wrong move when the worker is genuinely stuck on a structural protocol issue (issue #537). The supervisor either gives up too early (skip / let it fail) or steers blindly (often with the same "keep going" message), neither of which addresses the root cause.

A non-empty Worker said: field would let the supervisor diagnose and steer in one or two messages. Empty payloads force a multi-tool-call diagnostic dance.

Root cause hypothesis

Looking at the worker prompt's exit-handling logic, the worker is expected to articulate a reason string when calling whatever internal "request_exit_with_no_progress" mechanism exists. Either:

  • The base prompt doesn't strongly encourage articulating the reason (so the worker omits it most of the time), or
  • The mechanism allows empty reasons by default, or
  • The orch surfaces the field only when populated and shows "" otherwise (instead of the actual most recent assistant_message event).

Fix proposals

A. Require non-empty reason

Worker prompt: when requesting exit-with-no-progress, the worker MUST include a one-sentence reason. Examples:

  • "Step 2 STATUS is marked complete but R006 wants revision — protocol unclear"
  • "Spec says do X but file already has it; Y might also be needed"
  • "All targeted tests pass but I can't see how to make further progress on this checkbox"

Tool-level: refuse to accept an empty reason; ask the worker to provide one.

B. Surface the most recent assistant message as fallback

If the reason field is empty, the orch should surface the most recent assistant_message event from the worker's events.jsonl in the alert payload. This gives the supervisor the worker's recent thinking even when explicit articulation is missing.

C. Surface recent observed state alongside the reason

Beyond the reason string, include in the alert:

  • The last 2–3 tool-call summaries (e.g., read STATUS.md, bash git diff, read .reviews/R006-code-step2.md)
  • Whether any uncommitted changes exist in the worktree
  • The most recent review verdict if any

This gives the supervisor instant situational awareness without needing the diagnostic dance.

Recommendation

A + C. A makes the worker articulate; C gives the supervisor the receipts. B is the cheap fallback if A doesn't get implemented.

Acceptance criteria

Related

Affected version: taskplane@0.28.4. Full alert payloads from the production failure available on request.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions