Skip to content

feat: loop primitive for autonomous multi-step iteration #44

@electronicBlacksmith

Description

@electronicBlacksmith

Summary

Proposing a phantom_loop MCP tool that enables autonomous multi-step iteration with fresh agent sessions per tick, bounded budgets, Slack progress reporting, mid-loop critique, and post-loop evolution.

Use Case

When the agent needs to complete a multi-step goal autonomously (refactoring a module, investigating a bug across files, running a migration), a single session often runs out of context or loses focus. The loop primitive solves this by:

  • Starting a fresh agent session per "tick" with a clean context window
  • Using a state file (YAML frontmatter + markdown) as the only contract between ticks
  • Enforcing hard budget limits (iterations + cost in USD)
  • Providing Slack progress bars, reaction ladders, and a stop button for observability
  • Running optional mid-loop Sonnet critique at configurable checkpoint intervals
  • Triggering post-loop evolution and memory consolidation after completion

Architecture

phantom_loop start (goal, workspace, budget)
  -> LoopRunner creates state file, SQLite row, Slack status message
  -> tick():
       lock -> pre-checks -> read state -> build prompt -> fresh session
       -> agent works -> record cost -> parse frontmatter -> success command
       -> critique checkpoint -> Slack update -> schedule next tick
  -> finalize():
       fire-and-forget evolution + memory consolidation

Key design decisions:

  • State file as contract: YAML frontmatter (loop_id, status, iteration) + markdown body (Goal, Progress, Next Action, Notes). The agent reads and writes this file each tick.
  • Fresh sessions: Each tick gets a new conversation ID ({loopId}:{iteration}), preventing context window exhaustion
  • Memory context: Cached once at loop start from vector memory, injected into every tick as "RECALLED MEMORIES"
  • Bounded execution: Hard ceilings of 200 iterations / $50 USD, configurable down per loop

Files

All new files in src/loop/ (runner, tool, prompt, critique, post-loop, notifications, state-file, store, types) plus:

  • src/agent/slack-context.ts - AsyncLocalStorage for Slack context propagation to in-process MCP tools
  • src/db/schema.ts - loops table migration
  • src/channels/slack-actions.ts - loop stop button handler
  • src/index.ts - wiring
  • docs/loop.md - comprehensive documentation
  • 7 test files with full coverage

Dependencies

This feature depends on the Slack message handling improvements in #43 (shared modifications to slack.ts and index.ts).

Questions for Maintainers

  1. Does this feature align with the project roadmap?
  2. Any concerns about the architecture (state file contract, fresh sessions per tick)?
  3. Preferred PR size - one cohesive PR or split differently?

Metadata

Metadata

Assignees

No one assigned

    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