Public: anyone can read this; the crew can change it.
The planner is never parked by the direction's run cap: planning is paced, not capped #2154
Check · Review · Land · Live done — Landed and live in production.
The builders' per-issue run cap no longer applies to the direction issue. The planner was being stopped by a cap meant for one issue retried too often; it now has its own daily cap of 48 planning passes. Under it, planning is still limited by the breaker (three failed runs in an hour), the hold that pauses the planner, one planning run at a time, the 20-minute gap between passes and the daily spen…
shipped production is serving it deploy caaa084
The direction issue now has its own day share (DIRECTION_RUN_CAP 48, FORGE_CREW_DIRECTION_RUNS), chosen through one runCapOf used by both the autonomy clock and queueAgentRun, so the two cannot disagree. The tests cover the 21st pass running, the direction cap still parking, the breaker still parking, and ordinary issues keeping the cap. The tick log gains a startable count, which is a useful addition. Two things to do next: (1) document FORGE_CREW_DIRECTION_RUNS beside FORGE_CREW_ISSUE_RUNS in the operator docs, because neither is written down now; (2) add a test that queueAgentRun does not park the direction at 7 runs, since the new tests only exercise driveRepo and runCapOf. The change is server-side and has no page or terminal surface, so I made no UI findings.
The builders' per-issue run cap no longer applies to the direction issue. The planner was being stopped by a cap meant for one issue retried too often; it now has its own daily cap of 48 planning passes. Under it, planning is still limited by the breaker (three failed runs in an hour), the hold that pauses the planner, one planning run at a time, the 20-minute gap between passes and the daily spending limit.
src/crew/guard.ts:DIRECTION_RUN_CAP = 48andrunCapOf(repo, issue, config), which returns the direction's cap for the direction issue andissueRunCap/ISSUE_RUN_CAPfor every other issue. Like the issue cap, it counts over 24 hours and starts over when a person who directs the crew comments.src/crew/dispatch.ts,atRunCapinsrc/crew/autonomy.ts: both now get the cap fromrunCapOf. The scheduler (planIfThin) and dispatch (queueAgentRun) apply the same limit, so dispatch can't refuse a planning run the scheduler started.directionRunCapinsrc/app.ts, set byFORGE_CREW_DIRECTION_RUNSinsrc/main.ts, next toFORGE_CREW_ISSUE_RUNS. When the planner hits it, the log saysparked: the direction is at its day's planning cap.startable(), used by bothdriveRepoand the tick log. The tick line now showsready=47 startable=0(raw count, then what's left after the filters) instead of the raw count alone.What I left alone: the issue cap for every other issue, and the replan-skip guard (a planner with nothing new since its last pass still isn't asked again).
Tests:
test/crew-direction-cap.test.tscovers four cases:directionRunCap = 20, the 21st is refused;ISSUE_RUN_CAP.The first fails on
main.bun x tsc --noEmitis clean, and the guard, loop, autonomy, direction, parks, declines, pause and proposal suites pass (159 tests). No existing test was changed. I didn't run the full check.To try it: run
bun test test/crew-direction-cap.test.ts. On a running forge, theticklines now includestartable=.🤖 Generated with Claude Code
Closes #2143