Skip to content
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
68ebe94
feat: add loop domain types, events, and interfaces
Mar 20, 2026
f3ddf09
feat: add loop migration v10 and repository implementation
Mar 20, 2026
b0c4e9a
feat: add loop manager service and shared format utility
Mar 20, 2026
73d62ed
style: fix biome formatting in loop repository and manager
Mar 20, 2026
9e46377
feat: add loop handler — event-driven iteration engine
Mar 20, 2026
7929328
feat: wire loop handler into handler setup and bootstrap
Mar 21, 2026
237c2b9
style: fix biome formatting in loop handler and wiring
Mar 21, 2026
67fc893
feat: add CreateLoop, LoopStatus, ListLoops, CancelLoop MCP tools
Mar 21, 2026
22b5b38
feat: add loop CLI commands and routing
Mar 21, 2026
1265426
feat: add prompt preview to task list views
Mar 21, 2026
a744a2a
style: fix biome formatting in MCP adapter and CLI
Mar 21, 2026
b751f5a
fix: address self-review issues
Mar 21, 2026
1f22d5a
docs: add loop feature documentation and roadmap updates
Mar 21, 2026
c8d3d61
test: add unit tests for loop repository, manager, and handler
Mar 21, 2026
9a9bca1
test: add integration test for task loop lifecycle
Mar 21, 2026
b58fbd2
style: fix biome formatting in loop feature test files
Mar 21, 2026
c062013
fix: align loop timestamps with codebase convention (Date → epoch num…
Mar 21, 2026
dfada8a
fix: make LoopIteration.taskId optional for ON DELETE SET NULL safety
Mar 21, 2026
9549dea
refactor: extract recordAndContinue helper to reduce loop handler dup…
Mar 21, 2026
867606a
refactor: remove unused _taskId parameter from handleIterationResult
Mar 21, 2026
1c24316
feat: add cleanupOldLoops to RecoveryManager for loop lifecycle cleanup
Mar 21, 2026
41f4398
style: fix biome formatting in loop cleanup code
Mar 21, 2026
d2b0a10
fix: address review batch-1 issues for v0.7.0 release
Mar 21, 2026
52ffd3a
fix(loops): guard undefined taskId in cancelLoop and bound evalTimeout
Mar 21, 2026
4ce078b
style: consolidate evalTimeout validation guards
Mar 21, 2026
130f582
refactor(loops): convert evaluateExitCondition to async exec and wrap…
Mar 21, 2026
4fac921
refactor: extract parseLoopCreateArgs as pure testable function
Mar 21, 2026
8ce1b49
test: add MCP adapter tests for loop tool handlers
Mar 21, 2026
3470e1e
fix: normalize LoopRepository return types to null for consistency
Mar 21, 2026
765faad
refactor: move toOptimizeDirection and toMissedRunPolicy to utils/format
Mar 21, 2026
15b215f
fix(loops): save task synchronously in transaction before recording i…
Mar 21, 2026
2c0d765
fix(loops): handle pipeline intermediate task failures to prevent stu…
Mar 21, 2026
7ec12aa
refactor(loops): extract ExitConditionEvaluator for dependency injection
Mar 21, 2026
f1c9232
refactor(loops): flatten recoverStuckLoops into early-return style
Mar 21, 2026
55870dd
docs(loops): document strict score comparison design rationale
Mar 21, 2026
8aa31c1
fix: update loop-repository tests to expect null instead of undefined
Mar 21, 2026
37ead72
style: simplify and clean up PR review fixes
Mar 21, 2026
8f80dd1
style: fix biome formatting in test files
Mar 21, 2026
d3c8d7c
fix(loops): close 3 crash-window atomicity issues in loop-handler
Mar 21, 2026
c37c285
test(loops): add CLI loop command tests and integration failure/optim…
Mar 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ npm run test:coverage # With coverage
- `PersistenceHandler` → database operations
- `ScheduleHandler` → schedule lifecycle (create, pause, resume, cancel)
- `ScheduleExecutor` → cron/one-time execution engine (note: has direct repo writes, architectural exception to event-driven pattern)
- `LoopHandler` → loop iteration engine (retry/optimize strategies, exit condition evaluation)

See `docs/architecture/` for implementation details.

Expand Down Expand Up @@ -125,6 +126,8 @@ See `docs/TASK-DEPENDENCIES.md` for usage patterns.
- `workers` table: active worker registrations with ownerPid for crash detection (migration v9)
- `schedules` table: schedule definitions, cron/one-time config, status, timezone
- `schedule_executions` table: execution history and audit trail
- `loops` table: loop definitions, strategy, exit condition, iteration state (migration v10)
- `loop_iterations` table: per-iteration execution records with scores and results (migration v10)

### Dependencies

Expand All @@ -135,7 +138,7 @@ When adding task dependencies:

### MCP Tools

All tools use PascalCase: `DelegateTask`, `TaskStatus`, `TaskLogs`, `CancelTask`, `ScheduleTask`, `ListSchedules`, `GetSchedule`, `CancelSchedule`, `PauseSchedule`, `ResumeSchedule`, `CreatePipeline`, `SchedulePipeline`
All tools use PascalCase: `DelegateTask`, `TaskStatus`, `TaskLogs`, `CancelTask`, `ScheduleTask`, `ListSchedules`, `GetSchedule`, `CancelSchedule`, `PauseSchedule`, `ResumeSchedule`, `CreatePipeline`, `SchedulePipeline`, `CreateLoop`, `LoopStatus`, `ListLoops`, `CancelLoop`

## File Locations

Expand All @@ -158,6 +161,9 @@ Quick reference for common operations:
| Schedule executor | `src/services/schedule-executor.ts` |
| Schedule manager | `src/services/schedule-manager.ts` |
| Cron utilities | `src/utils/cron.ts` |
| Loop repository | `src/implementations/loop-repository.ts` |
| Loop handler | `src/services/handlers/loop-handler.ts` |
| Loop manager | `src/services/loop-manager.ts` |

## Documentation Structure

Expand Down
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ Once configured, use these MCP tools:
| **ResumeTask** | Resume a failed/completed task with checkpoint context | `ResumeTask({ taskId, additionalContext? })` |
| **CreatePipeline** | Create sequential task pipelines | `CreatePipeline({ steps: [...] })` |
| **SchedulePipeline** | Create recurring/one-time scheduled pipelines | `SchedulePipeline({ steps: [...], cronExpression: "0 9 * * *" })` |
| **CreateLoop** | Create iterative loops (retry or optimize strategy) | `CreateLoop({ prompt: "...", strategy: "retry", exitCondition: "npm test" })` |
| **LoopStatus** | Get loop details and iteration history | `LoopStatus({ loopId })` |
| **ListLoops** | List loops with optional status filter | `ListLoops({ status: "running" })` |
| **CancelLoop** | Cancel an active loop (optionally cancel in-flight tasks) | `CancelLoop({ loopId, cancelTasks: true })` |

### CLI Commands

Expand All @@ -106,6 +110,11 @@ Once configured, use these MCP tools:
| `beat schedule resume <id>` | Resume a paused schedule |
| `beat schedule cancel <id>` | Cancel a schedule |
| `beat pipeline <prompt> ...` | Create chained one-time schedules |
| `beat loop <prompt> --until <cmd>` | Create a retry loop (run until condition passes) |
| `beat loop <prompt> --eval <cmd>` | Create an optimize loop (score-based) |
| `beat loop list` | List loops with optional status filter |
| `beat loop get <loop-id>` | Get loop details and iteration history |
| `beat loop cancel <loop-id>` | Cancel a loop |
| `beat config show\|set\|reset\|path` | Manage configuration |
| `beat help` | Show help |

Expand Down Expand Up @@ -319,7 +328,7 @@ backbeat/
- [x] v0.4.0 - Task scheduling and task resumption
- [x] v0.5.0 - Multi-agent support (Claude, Codex, Gemini)
- [x] v0.6.0 - Architectural simplification + scheduled pipelines
- [ ] v0.7.0 - Task/pipeline loops
- [x] v0.7.0 - Task/pipeline loops

See **[ROADMAP.md](./docs/ROADMAP.md)** for detailed plans and timelines.

Expand Down
73 changes: 70 additions & 3 deletions docs/FEATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This document lists all features that are **currently implemented and working** in Backbeat.

Last Updated: March 2026
Last Updated: March 2026 (v0.7.0)

## ✅ Core Task Delegation

Expand Down Expand Up @@ -154,8 +154,8 @@ Last Updated: March 2026

### Design Patterns (v0.6.0 Hybrid Event Model)
- **Hybrid Event-Driven Architecture**: Commands (state changes) flow through EventBus; queries use direct repository access
- **Event Handlers**: Specialized handlers (Persistence, Queue, Worker, Dependency, Schedule, Checkpoint)
- **Singleton EventBus**: Shared event bus across all system components (25 events)
- **Event Handlers**: Specialized handlers (Persistence, Queue, Worker, Dependency, Schedule, Checkpoint, Loop)
- **Singleton EventBus**: Shared event bus across all system components (29 events)
- **Dependency Injection**: Container-based DI with Result types
- **Result Pattern**: No exceptions in business logic
- **Immutable Domain**: Readonly data structures
Expand Down Expand Up @@ -288,6 +288,51 @@ Last Updated: March 2026
- **Dependency Failure Cascade**: Failed/cancelled upstream tasks now cascade cancellation to dependents (was incorrectly unblocking them)
- **Queue Handler Race Condition**: Fast-path check prevents blocked tasks from being prematurely enqueued

## ✅ Task/Pipeline Loops (v0.7.0)

### MCP Tools
- **CreateLoop**: Create an iterative loop that runs a task repeatedly until an exit condition is met (retry or optimize strategy)
- **LoopStatus**: Get loop details including optional iteration history
- **ListLoops**: List loops with optional status filter and pagination
- **CancelLoop**: Cancel an active loop, optionally cancelling in-flight iteration tasks

### Loop Strategies
- **Retry**: Run a task until an exit condition passes — shell command returning exit code 0 ends the loop
- **Optimize**: Run a task, score output with eval script, keep improvements — seek the best score across iterations (minimize or maximize direction)

### Single Task Loops
- **Task Prompt**: Each iteration runs the same prompt (or enriched with checkpoint context if `freshContext` is false)
- **Exit Condition**: Shell command evaluated after each iteration to determine pass/fail or score

### Pipeline Loops
- **Multi-Step Iterations**: Repeat a full pipeline (2–20 steps) per iteration instead of a single task
- **Linear Dependencies**: Each pipeline step depends on the previous step within the iteration
- **Same Exit Condition**: Evaluated after all pipeline steps complete

### Configuration
- **Max Iterations**: Safety cap on iteration count (0 = unlimited, default: 10)
- **Max Consecutive Failures**: Stop after N consecutive failures (default: 3)
- **Cooldown**: Delay between iterations in milliseconds (default: 0)
- **Eval Timeout**: Timeout for exit condition evaluation (default: 60s, minimum: 1s)
- **Fresh Context**: Each iteration gets a fresh agent context (default: true) or continues from previous checkpoint

### CLI Commands (v0.7.0)
- `beat loop <prompt> --until <cmd>`: Create a retry loop (run until shell command exits 0)
- `beat loop <prompt> --eval <cmd> --direction minimize|maximize`: Create an optimize loop (score-based)
- `beat loop --pipeline --step "..." --step "..." --until <cmd>`: Create a pipeline loop
- `beat loop list [--status <status>]`: List loops with optional status filter
- `beat loop get <loop-id> [--history]`: Get loop details and iteration history
- `beat loop cancel <loop-id> [--cancel-tasks] [reason]`: Cancel a loop with optional task cancellation

### Event-Driven Integration
- **LoopCreated**: Emitted when a new loop is created
- **LoopIterationCompleted**: Emitted when an iteration finishes with its result (pass/fail/keep/discard/crash)
- **LoopCompleted**: Emitted when the loop reaches its exit condition or max iterations
- **LoopCancelled**: Emitted when a loop is cancelled

### Database Schema
- **Migration 10**: `loops` table for loop definitions and state, `loop_iterations` table for per-iteration execution records

## ❌ NOT Implemented (Despite Some Documentation Claims)
- **Distributed Processing**: Single-server only
- **Web UI**: No dashboard interface
Expand All @@ -299,6 +344,28 @@ Last Updated: March 2026

---

## 🆕 What's New in v0.7.0

### Task/Pipeline Loops
- **`CreateLoop` MCP Tool**: Create retry or optimize loops for single tasks or pipelines (2–20 steps)
- **Retry Strategy**: Run a task until an exit condition shell command returns exit code 0
- **Optimize Strategy**: Score iterations with an eval script, keep improvements (minimize or maximize)
- **Pipeline Loops**: Repeat a multi-step pipeline per iteration with linear task dependencies
- **Fresh Context**: Each iteration gets a clean agent context by default, or continues from previous checkpoint
- **Safety Controls**: Max iterations (0 = unlimited), max consecutive failures, cooldown between iterations
- **Configurable Eval Timeout**: Exit condition evaluation timeout (default: 60s)
- **CLI**: `beat loop`, `beat loop list`, `beat loop get`, `beat loop cancel` commands
- **4 MCP Tools**: `CreateLoop`, `LoopStatus`, `ListLoops`, `CancelLoop`

### Event System
- **4 New Events**: `LoopCreated`, `LoopIterationCompleted`, `LoopCompleted`, `LoopCancelled`
- **Loop Handler**: Event-driven iteration engine manages loop lifecycle

### Database
- **Migration 10**: `loops` and `loop_iterations` tables

---

## 🆕 What's New in v0.6.0

### Scheduled Pipelines
Expand Down
40 changes: 21 additions & 19 deletions docs/ROADMAP.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Backbeat Development Roadmap

## Current Status: v0.6.0 ✅
## Current Status: v0.7.0 ✅

**Status**: Released (2026-03-20)
**Status**: Released (2026-03-21)

Backbeat v0.6.0 delivers architectural simplification (hybrid event model, SQLite worker coordination, ReadOnlyContext), scheduled pipelines, bug fixes, and tech debt cleanup. See [FEATURES.md](./FEATURES.md) for complete list of current capabilities.
Backbeat v0.7.0 adds task/pipeline loops — condition-driven iteration with retry and optimize strategies. See [FEATURES.md](./FEATURES.md) for complete list of current capabilities.

---

Expand Down Expand Up @@ -85,24 +85,22 @@ See [RELEASE_NOTES_v0.6.0.md](./releases/RELEASE_NOTES_v0.6.0.md) for full detai

---

### v0.7.0 - Task/Pipeline Loops
**Goal**: Condition-driven iteration
**Priority**: High — completes the orchestration story
### v0.7.0 - Task/Pipeline Loops ✅
**Status**: **RELEASED** (2026-03-21)
**Issue**: [#79](https://github.com/dean0x/backbeat/issues/79)

#### Task/Pipeline Loops (#79)
Repeat a task or pipeline until an exit condition is met — the [Ralph Wiggum Loop](https://ghuntley.com/loop/) pattern.
Condition-driven iteration — repeat a task or pipeline until an exit condition is met. The [Ralph Wiggum Loop](https://ghuntley.com/loop/) pattern.

```bash
beat loop "implement next item from spec.md" \
--until "npm test && npm run build" \
--max-iterations 10
```

- Exit condition: shell command returning exit code 0
- Max iterations: required safety cap
- Fresh context per iteration (Ralph pattern) or continue from checkpoint
- Composable with schedules: "every night, loop until spec is done"
#### Features
- Task/Pipeline Loops — `CreateLoop` MCP tool, `beat loop` CLI, retry and optimize strategies (#79)
- Retry strategy: shell command exit code 0 ends the loop
- Optimize strategy: eval script returns a score, loop seeks best (minimize or maximize)
- Pipeline loops: repeat a multi-step pipeline (2–20 steps) per iteration
- Fresh context per iteration (default) or continue from checkpoint
- Safety controls: max iterations, max consecutive failures, cooldown, eval timeout
- 4 MCP tools: `CreateLoop`, `LoopStatus`, `ListLoops`, `CancelLoop`
- 4 CLI commands: `beat loop`, `beat loop list`, `beat loop get`, `beat loop cancel`
- 4 events: `LoopCreated`, `LoopIterationCompleted`, `LoopCompleted`, `LoopCancelled`

#### Builds On
- v0.4.0 schedules (cron/one-time), checkpoints, `continueFrom`
Expand All @@ -123,10 +121,14 @@ beat loop "implement next item from spec.md" \
- **Smart Routing**: Route tasks based on complexity, cost, or agent strengths
- **Usage Tracking**: Track per-agent usage to predict limit exhaustion
- **Cooldown Management**: Track rate limit windows, re-enable agents when limits reset
- **Git Integration for Loops**: Loop-aware git state management (branch per iteration, diff tracking)
- **Loop + Schedule Composition**: "Every night, loop until spec is done" — composable loops with cron/one-time schedules
- **Loop Pause/Resume**: Pause an active loop and resume it later

#### Builds On
- v0.4.0 checkpoint/resumption system (`continueFrom`)
- v0.5.0 agent registry and adapters
- v0.7.0 task/pipeline loops

---

Expand Down Expand Up @@ -240,7 +242,7 @@ beat recipe create my-workflow # interactive recipe builder
| v0.4.0 | ✅ Released | Scheduling, Resumption, Rename to Backbeat |
| v0.5.0 | ✅ Released | Multi-Agent Support |
| v0.6.0 | ✅ Released | Architectural Simplification + Bug Fixes |
| v0.7.0 | 📋 Planned | Task/Pipeline Loops |
| v0.7.0 | ✅ Released | Task/Pipeline Loops |
| v0.8.0 | 📋 Planned | Agent Failover + Smart Routing |
| v0.9.0 | 📋 Planned | Workflow Recipes & Templates |
| v0.10.0 | 💭 Research | Monitoring + REST API + Dashboard |
Expand Down
64 changes: 43 additions & 21 deletions docs/releases/RELEASE_NOTES_v0.7.0.md
Original file line number Diff line number Diff line change
@@ -1,48 +1,70 @@
# Backbeat v0.7.0 — SQLite Worker Coordination
# Backbeat v0.7.0 — Task/Pipeline Loops

Cross-process worker coordination via SQLite `workers` table, replacing in-memory-only tracking. Enables multi-process Backbeat deployments with PID-based crash detection and duplicate-spawn prevention.
Iterative task execution with retry and optimize strategies. Run a task (or full pipeline) in a loop until an exit condition is met, with configurable safety controls and score-based optimization.

---

## New Features

### Cross-Process Worker Coordination (PR #94)
### Task Loops

Workers are now registered in SQLite with their owner PID. This enables:
Create loops that repeat a task until a shell-based exit condition passes:

- **Crash detection**: On startup, recovery checks if each worker's owner process is alive
- **Duplicate prevention**: `UNIQUE(taskId)` constraint prevents two processes from spawning workers for the same task
- **Stale cleanup**: Dead worker registrations are cleaned automatically during recovery
- **Retry Strategy**: Run a task until a shell command returns exit code 0 (e.g., `npm test`)
- **Optimize Strategy**: Score each iteration with an eval script, keep the best result (minimize or maximize direction)
- **Exit Condition Evaluation**: Configurable eval timeout (default: 60s, minimum: 1s)
- **Fresh Context**: Each iteration gets a clean agent context by default, or continues from previous checkpoint

### PID-Based Recovery
### Pipeline Loops

Replaces the 30-minute staleness heuristic with definitive PID-based detection:
Repeat a multi-step pipeline (2-20 steps) per iteration instead of a single task:

- If a worker's owner PID is alive → task is genuinely running, leave it alone
- If owner PID is dead → task definitively crashed, mark FAILED immediately
- No false positives from short tasks, no 30-minute wait for crashed tasks
- **Linear Dependencies**: Each pipeline step depends on the previous step within the iteration
- **Same Exit Condition**: Evaluated after all pipeline steps complete
- **Tail-Task Tracking**: Only the last pipeline task triggers iteration evaluation

---
### Safety Controls

## Breaking Changes
- **Max Iterations**: Safety cap on iteration count (0 = unlimited, default: 10)
- **Max Consecutive Failures**: Stop after N consecutive failures (default: 3)
- **Cooldown**: Configurable delay between iterations in milliseconds (default: 0)

### MCP Tools

- **CreateLoop**: Create an iterative loop with retry or optimize strategy
- **LoopStatus**: Get loop details including optional iteration history
- **ListLoops**: List loops with optional status filter and pagination
- **CancelLoop**: Cancel an active loop, optionally cancelling in-flight iteration tasks

### RUNNING Tasks Marked FAILED on Upgrade
### CLI Commands

**Before (v0.6.x):** RUNNING tasks without a worker registration were left in RUNNING state or recovered via a staleness heuristic.
- `beat loop <prompt> --until <cmd>`: Create a retry loop
- `beat loop <prompt> --eval <cmd> --direction minimize|maximize`: Create an optimize loop
- `beat loop --pipeline --step "..." --step "..." --until <cmd>`: Create a pipeline loop
- `beat loop list [--status <status>]`: List loops with optional status filter
- `beat loop get <loop-id> [--history]`: Get loop details and iteration history
- `beat loop cancel <loop-id> [--cancel-tasks] [reason]`: Cancel a loop

**After (v0.7.0+):** On first startup after upgrade, migration 9 creates an empty `workers` table. Any RUNNING tasks from v0.6.x have no corresponding worker row, so recovery marks them FAILED immediately (exit code -1).
### Event System

**Mitigation:** Wait for all running tasks to complete before upgrading. If tasks are marked FAILED unexpectedly after upgrade, re-delegate them.
4 new events (29 total):

### Required Constructor Dependencies
- **LoopCreated**: Emitted when a new loop is created
- **LoopIterationCompleted**: Emitted when an iteration finishes with its result (pass/fail/keep/discard/crash)
- **LoopCompleted**: Emitted when the loop reaches its exit condition or max iterations
- **LoopCancelled**: Emitted when a loop is cancelled

---

## Breaking Changes

`WorkerRepository` and `OutputRepository` are now required constructor parameters for `EventDrivenWorkerPool`. This affects custom integrations that instantiate the worker pool directly. MCP and CLI users are unaffected (bootstrap wires dependencies automatically).
None. This release is fully additive.

---

## Database

- **Migration 9**: Adds `workers` table with columns `workerId`, `taskId` (UNIQUE), `pid`, `ownerPid`, `agent`, `startedAt`. Used for cross-process coordination and crash detection.
- **Migration 10**: Adds `loops` table for loop definitions and state, and `loop_iterations` table for per-iteration execution records with scores, exit codes, and error messages.

---

Expand Down
Loading
Loading