Skip to content

BlueprintLoop: detect and stop idle-loop token waste when execution is frozen by user stop boundary #901

Description

@marzich

What happened?

A BlueprintLoop execution session (ses_06841cd21ffeqhYTMZD8aqz2Be, Clarus CLI-Native Verification Blueprint bll_f9a606b56001f29l1wQe4g6oMY) ran in a tight idle loop for ~7 hours after the user explicitly stopped all external execution. The BlueprintLoop kept waking the session every ~7 seconds with the same continuation prompt, and the agent produced the same ~250-word "waiting for authorization" response each time. Total waste: ~3617 messages / ~1807 cycles / ~450K+ output tokens.

Timeline

Time (UTC+8) Event
7/25 13:27 — 7/26 04:46 Real implementation work across four repos (Server, CLI, Web, Worker), quality gates, commit management
7/26 04:46:40 Last real tool call: question asking user for external-write authorization
7/26 04:49:29 User sends stop instruction → idle loop begins
7/26 04:49 → 11:48 ~7 hours: 1807 cycles of identical BlueprintLoop continuation prompts + identical agent responses
7/26 11:48:21 Session aborted by system

Loop pattern

The BlueprintLoop system injected this identical message every ~7 seconds:

BlueprintLoop bll_f9a606b56001f29l1wQe4g6oMY status is running. A normal final response does not finish this loop. Inspect the Blueprint note, current deliverables, and progress against the complete requirements and acceptance criteria at every turn.

The agent responded each time with a ~250-word message:

  • No new authorization from user
  • Blueprint incomplete (missing npm publish, Pre/Production deploy, Smoke Test, leak scan, rollback)
  • Cannot call blueprint_loop_stop (would falsely declare completion)
  • Cannot continue (all remaining steps require prohibited external writes)
  • External-write audit: zero writes beyond local commits
  • Waiting for user authorization in Boss Session

Idle cycle rate

Segment Duration Messages Cycles Rate
04:49 → 05:50 61 min 479 239 7.9/min
05:51 → 06:50 59 min 602 301 10.3/min
06:50 → 07:33 43 min 341 170 7.9/min
07:33 → 07:42 8 min 84 42 10.4/min
07:42 → 09:18 96 min 851 425 8.9/min
09:18 → 09:29 11 min 112 56 10.1/min
09:29 → 11:06 97 min 801 400 8.3/min
11:06 → 11:24 18 min 160 80 9.0/min
11:24 → 11:48 24 min 184 92 7.7/min
Total ~417 min (6.9h) 3617 ~1807 ~8.7/min

Root cause analysis

1. BlueprintLoop has no stop/idle detection

The BlueprintLoop continuation mechanism fires on every idle → wake transition when the loop status is running. There is no mechanism for the loop to detect that:

  • The agent has produced identical responses N times in a row
  • The user has explicitly stopped and is not going to respond
  • The loop is in a catch-22 where progress is impossible

2. Agent catch-22: can't continue, can't stop

The agent is trapped in a logical deadlock:

  • Can't continue: User explicitly stopped all external writes (push, PR, npm publish, deploy, secrets, etc.)
  • Can't call blueprint_loop_stop: Would falsely declare completion — real Pre/Production acceptance is incomplete
  • Can't call blueprint_loop_cancel: The work is done locally, just waiting for authorization — cancelling would lose context
  • BlueprintLoop status stays running: No status change → loop keeps waking → agent repeats the same response

3. Compaction erases loop history

Compaction fires periodically during the 7-hour idle period, compressing prior cycles into a summary. The agent then re-derives the same conclusion from scratch ("let me check the Blueprint, Boss Session, and authorization status…") instead of recognizing "I've already done this 1000 times and nothing changed."

4. No backoff or rate limiting

The idle cycle ran steadily at 7.7–10.4 cycles per minute with no exponential backoff, no cooldown, and no escalating timeout. A healthy system would increase the interval between wake-ups when responses are identical.

Related code

  • BlueprintLoop continuation prompt injection: packages/synergy/src/agenda/session-wakeup.tsAgendaSessionWakeup.loopInstruction() delivers the <blueprint-loop-agenda-wakeup> instruction, but the observed empty-prompt loop suggests a separate Cortex workflow continuation path that bypasses Agenda entirely.
  • Loop status transitions: packages/synergy/src/blueprint/loop-store.tsstatus: "running" has no aging or staleness detection.
  • Session recovery: packages/synergy/src/session/recovery.tsresumePendingStopRequests() handles interrupted review cycles but not frozen execution sessions.

Suggested fixes

Option A: Repeated-response detection (quickest win)

The BlueprintLoop continuation mechanism should detect when the assistant's last N responses are semantically identical and escalate:

  • After 3 identical "waiting for authorization" responses → pause loop (transition to waiting)
  • After 10 → auto-cancel with an error reason
  • Use response fingerprinting (hash of response content, not exact byte match, to handle minor wording variations)

Option B: Agent-side blueprint_loop_wait tool

Give the agent a tool to explicitly transition the loop to waiting state:

  • blueprint_loop_wait(reason: string) — transitions loop from running to waiting
  • This is semantically correct: the agent is literally waiting for user input, not stopped forever
  • Avoids the catch-22 where blueprint_loop_stop would be a lie and there's no other escape

Option C: Max idle cycles with exponential backoff

Enforce a budget on idle → continuation cycles:

  • Max 10 cycles without real tool calls (only note_read, session_read, memory_get)
  • After limit: exponential backoff or auto-escalate to pause
  • Reset counter when a real tool call (bash, task, write) occurs

Option D: Loop "stale session" timeout

Add a configurable timeout for runningwaiting or runningfailed based on:

  • Elapsed time since last real tool call (not including read-only inspection tools)
  • Elapsed time since last non-identical assistant response
  • This is a server-side guard that doesn't require agent cooperation

Impact

  • Token waste: ~450K output tokens consumed over ~7 hours with zero productive work
  • Resource waste: Continuous CPU/memory for model inference on repeated identical reasoning
  • Model cost: Provider billing for repeated identical outputs

Related issues

Non-goals

  • This is not about the correctness of the agent's stop-boundary behavior (which is correct)
  • This is not about the Lattice Pathway tracking
  • This is not about BlueprintLoop audit/review workflow

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

    needs-triageNeeds maintainer or Oryn classification.oryn:kind: 🐛 bugBehavior differs from the intended result.oryn:priority: 🟡 P2Normal-priority work.oryn:proof: 🔎 supportedEvidence supports this conclusion; see the report for source vs live proof.oryn:status: 🧭 needs inputA maintainer decision or additional information is required.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions