Repository navigation
Releases: Bellows-AI/factory
Release list
v0.0.7
Highlights
Batch execution. Plan an epic as ordered stages of parallel tasks, each one an ordinary task thread with its own PR, and let the board run it overnight.
- Persisted, validated stage plans with API contracts; durable parallel scheduling under a concurrency cap; lifecycle API (import, validate, update, start, cancel, accept, retry, report).
- Two merge policies per batch or stage:
human(people merge; the board observes and continues) andautomerge(the board merges once GitHub's requirements pass, serialized per target, then verifies the target's checks before the next stage). - Bounded recovery: infrastructure retries and repairs with their own budgets; gates the environment failed (vitest worker timeouts, exits 124/125/137) are retried as infrastructure, a failing assertion or a conflicting PR is repaired by a follow-up in the same session; a time limit and a morning report.
- Durable PR observation (checks and mergeability); a conflicted rebase is handed to the agent to resolve rather than failing the run.
- Executor selection by scope (
user/org), refused at validate when missing. - Web planning, monitoring and stage controls; the
batch-controlskill for driving a batch from a local session. - Finished batches report
completed/cancelled/expiredand close their task threads; a person can force-close one task.
CLI. factory batch … commands; durable mutation idempotency and replay keys; job retry, reopen and queued-command editing; question inspection and answers; file/stdin prompt input; request deadlines, interruption and bounded read retries; logical-task listing with cursors; full artifacts, activity and investigation; identity/configuration diagnostics and preflight.
Gates. on_demand gates the agent runs ad hoc (skipped by the end-of-run pass); the UI gate and its runner image are gone (the UI suite runs as a .bellows.yaml gate). Gate pods/containers are sized on their own with GATE_CPU_REQUEST, GATE_MEMORY_REQUEST, GATE_CPU_LIMIT, GATE_MEMORY_LIMIT (chart: runner.gateResources, default requests 2 CPU / 2Gi), falling back to the RUNNER_* values (#507).
Fixes
- Repair prompts now name each failed gate with its exit code and output tail (#687).
- An
automergetask whose PR the board can still merge readsnext: wait, not a person'smerge, and no longer parks the batch, sobatch waitstops exiting 6 while the board is acting (#688); the web batch page reads the same report and shows "Board merging" instead of "Waiting for you" (#693). - Behavior change: a follow-up on a thread that still has an unfinished job is refused with
409 NOT_FINISHED, like a retry, instead of queuing a second follow-up; an idempotent replay with the same key still answers the original (#698). - CI now runs the database suite (
test-db) on every pull request; six DB tests that had drifted from their code are corrected (#694). - A credential lookup the database cannot answer is a 503, which the CLI retries, not a 500 (#682).
- Runner git guard reads heredoc bodies as data —
git commit -F - <<'EOF'and multi-line messages are no longer denied — while HEAD-moving commands stay denied (#504); routine commands (sed -i,grep,/tmpwrites,cdinto the worktree) no longer prompt (#505). NPM_CONFIG_UPDATE_NOTIFIER=falseby default in runner and gate environments, so npm notices no longer bury the test summary (#511).- The claude bridge forwards TERM/INT from before it spawns the CLI, so an early
docker stopreaches claude (#506). - opencode exits 0 after a stop, like claude: the entrypoint maps opencode's "Aborted" exit to 0 only when the stop and its successful abort are both recorded; any other failure keeps its code (#697).
- The
test:jobsexecutor harness passes again against today's board contract (#697). It stays out of CI: 9 of its checks need host networking that ubuntu runners' docker does not give. - Driver: names why a runner never started; deterministic startup-sync refusals and executor refusals are reported as configuration; refuses
RUNNER_NETWORK=bridge/hostwhen services are on (#665); reaps gate environments no live attempt holds (#667); stages around.factory/without failing publish; servesfailureCausebesidefailureKind. - Runner: a denied compound command is not a refusal of its parts; the bridge keeps stdin open for subagents; runner git can push with the claim's
GITHUB_TOKEN. - Task detail: activity pulse and a Task statistics modal.
Upgrade notes
- Migrations 058–068 run on boot (job idempotency columns, the batch tables,
failure_causegainsenvironment). All are additive; verified against a v0.0.6 database with data. - Chart: new
runner.gateResourcesvalues. Gate pods now request 2 CPU / 2Gi by default — size the node pool, or set it back to the runner's values. - The UI gate's runner image is no longer built or referenced.
- API clients that queued a follow-up onto a busy thread now get
409 NOT_FINISHED; wait for the thread to settle (waitFor=terminal) and follow up then.
Validation
Batch execution was exercised live on kind and the docker executor: human gate, automerge, stage verification hold/advance, bounded repair, budget exhaustion, infra retry, board force-kill mid-run, concurrency cap, idempotent accept/cancel, cancel, time-limit expiry, unanswered question on Kubernetes, org executor scope, and conflict repair (a second PR conflicting after the first merged, repaired by the agent and automerged).
On the release commit: typecheck, lint, npm test (5857), test:db (814), test:k8s, test:jobs (136/136) and verify:ui (98) pass; the migration upgrade from a seeded v0.0.6 database applies cleanly; a smoke batch ran on kind built from the release commit.
Known limits
- A batch runs one target on its default branch; multi-repository (#657) and non-default-branch (#702) plans are refused at start (
BATCH_UNSUPPORTED) — next release. - Not yet exercised live: two board replicas, duplicate webhook deliveries, real branch protection.
- The runner refuses read-only pipelines that include tools outside its allowlist (e.g.
awk), which can push an agent to work around them by hand (#703).