Skip to content

Releases: Bellows-AI/factory

Release list

v0.0.7

Choose a tag to compare

@AndrewGrachov AndrewGrachov released this 14 Oct 05:03

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) and automerge (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-control skill for driving a batch from a local session.
  • Finished batches report completed / cancelled / expired and 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 automerge task whose PR the board can still merge reads next: wait, not a person's merge, and no longer parks the batch, so batch wait stops 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, /tmp writes, cd into the worktree) no longer prompt (#505).
  • NPM_CONFIG_UPDATE_NOTIFIER=false by 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 stop reaches 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:jobs executor 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/host when services are on (#665); reaps gate environments no live attempt holds (#667); stages around .factory/ without failing publish; serves failureCause beside failureKind.
  • 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_cause gains environment). All are additive; verified against a v0.0.6 database with data.
  • Chart: new runner.gateResources values. 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).