Skip to content

Minions spawn other minions instead of executing scope (claude-opus-4-7 violates RULES.md no-nested-fanout rule) #138

@chubes4

Description

@chubes4

Observation

Spawned a minion via `kimaki send` for a focused implementation task (extrachill-community#27 forum draft autosave client). The minion received the full prompt, decided to dispatch another minion via `kimaki send` instead of executing the work itself.

Concrete trace:

  • Parent dispatch: `extra-chill-bot` orchestrator → `kimaki send --channel 1476075959806590989 --user '532385681268408341' --prompt '...' --name 'feat: community Gutenberg forum draft autosave (Disable Claude Code auto memory during setup #27)'` at ~03:29 UTC
  • Parent session: `ses_1a7f86ee9ffeCfPWQQ9CgQaVnk` (thread 1507948551630618776) — running model `claude-opus-4-7`
  • Parent's first move: wrote the prompt to `/tmp/minion-prompt.md` (9774 bytes) then dispatched another `kimaki send` to create a child thread
  • Child session: `ses_1a7f79f16ffelaZVo8o0ajZ6E3` (thread 1507948773563957320) named "ec-community#27 BE drafts autosave"
  • The child did the actual investigation work and correctly stopped without writing code when it discovered the premise was wrong

The work eventually completed correctly (the child stopped at the right moment, posted findings to the issue, and surfaced action buttons). But the parent violated RULES.md "Cooking minions" → "Channel/thread targeting" which explicitly states:

Minions must not spawn more minions by default. The root/controller thread owns fan-out. Worker threads execute their assigned scope, report blockers/results, and stop. If a worker genuinely needs sub-fan-out, it asks the orchestrator instead of spawning.

Why this matters

  1. Context wastes. The parent reads the full prompt, builds context, then throws it away by handing to a child that re-builds the same context from a re-issued prompt. Double the token spend for zero gain.
  2. Attribution drift. `kimaki session list` shows two sessions for the same work. PR/issue audit trails point at the child, not the parent — but the parent is the one the orchestrator dispatched. Hard to reason about which worker is doing what.
  3. Cost. Two opus sessions instead of one. Today ~$opus per session.
  4. Anti-pattern propagation. If this is a model behavior pattern (vs. a one-off), every minion dispatch produces 2+ sessions. At fleet scale (5+ minions in one orchestrator turn → potentially 10+ sessions) this compounds.

Hypotheses for root cause

Not sure which — needs investigation:

  1. Prompt shape. My prompts begin with section headers like "## Worktree" and "## The work" and use verb-first language ("Implement the full..."). Opus may be reading these as orchestrator/dispatch prompts rather than worker prompts. Prompts that are too "polished" may pattern-match to "this is something I should hand off, not do myself."
  2. Model bias. `claude-opus-4-7` may have a stronger delegation bias than `claude-sonnet-4-5`. Worth comparing what sonnet does with the same prompt.
  3. System prompt missing the rule. The wp-coding-agents AGENTS.md surface (injected into every session via `.claude/CLAUDE.local.md` + `AGENTS.md` + `.datamachine/AGENTS.md.source` at worktree bootstrap) needs a check: does the "minions must not spawn more minions" rule actually reach the spawned session's system prompt, or only the orchestrator's?
  4. Worker doesn't know it's a worker. Spawned sessions get the SAME AGENTS.md as the orchestrator. There's no "you are a worker, not an orchestrator" signal in the spawned context. The session thinks it has full orchestrator authority because nothing tells it otherwise.

Hypothesis 4 is the strongest — and the easiest to fix. Spawned sessions need a system-prompt-level marker indicating they're in worker mode.

Suggested investigation paths

  1. Reproduce with sonnet. Send the same prompt to a sonnet-backed session, check whether it does the work directly or spawns a child. If sonnet doesn't do this, the bug is model-specific.
  2. Audit AGENTS.md propagation. Confirm what context the spawned session actually receives. If the no-nested-fanout rule isn't in the injected context, that's the fix surface.
  3. Add a worker-mode marker. When `kimaki send` creates a new thread, inject a "YOU ARE A WORKER. Do not spawn other minions. Execute your scope or report blockers and stop." preamble into the session's system prompt. This is a behavioral fix, not a config fix.
  4. Mechanical guard. `kimaki send` could check whether the calling session is itself a kimaki-spawned session, and refuse to spawn (or require an `--allow-nested-spawn` flag). Hard cap on the anti-pattern at the substrate level.

Repro session IDs

Out of scope

  • Fixing the underlying agent model behavior (Anthropic problem)
  • Forking opus (no)
  • Disabling opus (no — opus is the right model for this work shape, just needs to know it's a worker)

Definition of done

  • Spawned minion sessions reliably execute their assigned scope OR report blockers and stop. They do not dispatch additional minions.
  • Verified by: dispatching a representative implementation task to a fresh opus session and confirming it writes code directly rather than calling `kimaki send`.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions