Skip to content

Lesson 29 — Bounded scheduler and parallel agents ​

Outcome ​

Run multiple eligible Tasks concurrently with configurable limits and independent worktrees.

Why this comes now ​

Parallelism is useful only after isolation, recovery, and readiness are trustworthy. Earlier would multiply failure modes.

Understand ​

The scheduler is a small local coordinator, not a distributed queue. It repeatedly reacts to meaningful state changes, selects eligible Tasks, and starts work up to configured capacity. Every Task keeps its own Worktree/Run/Operation identities.

Use bounded concurrency. Cancellation and shutdown flow through contexts. Avoid aggressive auto-parallelism that makes human supervision harder.

Build the real project ​

  1. Add configurable max_concurrent_agent_runs with conservative default.
  2. Implement scheduler service driven by state notifications/ticks as simply as reliability allows.
  3. Select eligible Tasks deterministically/fairly enough for first version.
  4. Start through existing application/Operation path—scheduler must not bypass domain rules.
  5. Add tests A+B independent, C depends on both.
  6. Add graceful shutdown test with active fake Runs.
  7. Surface active capacity and blocked Tasks in UI.

Completion gate ​

A and B run concurrently up to limit, C waits, reducing limit does not kill valid work unexpectedly, shutdown is controlled, no duplicate Run starts for one Task.

Pitfalls to avoid ​

Do not create one goroutine forever per backlog Task. Do not poll the database at millisecond frequency. Do not start dependent branches from unmerged sibling work as an early optimization.

References ​

Go concurrency patterns: https://go.dev/blog/pipelines ; OPERATIONS_AND_RECOVERY.md.

Checkpoint ​

M11 is complete when parallel fake/real work remains understandable, not merely technically concurrent.

Forge is local-first. The docs are part of the product engineering system.