Repository navigation
Agent Factory v3: tasks are shaped before code is written, code is checked before it is pushed, and one maintainer approval merges an agent's pull request. The v3 features were proven live on GCP (GKE); the merge gate's human path on AWS (EKS).
What v3 is
The Agent Factory turns a labelled issue into a reviewed pull request, built by agents in a gVisor sandbox under their own identity. It is a bundle of open-source tools: Maku (the factory controller, the rooms, the harness and bridge, the Slack app and the maku CLI), agentgateway, OpenHands, gVisor, octo-sts, RunLore, Kueue and others.
v3 aims for more accepted pull requests per dollar on the models each kind of work may use: public work on open-weight models, internal work on Claude. It works on the task, not the model: it shapes the task before any code is written, checks the code before the push, judges the result against the task's own acceptance checks, and reduces the human's part of a merge to one approval. The eval bench that would measure that aim is deferred.
- How it works: agents and the merge gate
- What is proven and what is left: status and roadmap
- Designs: v3 roadmap, merge gate human path, harness roles
Proven live
Every feature was proven offline first (unit, golden and container suites, rule tests, drift gates), then tested live on two clouds: GCP (GKE) and AWS (EKS).
GCP (GKE), Maku v0.24 to v0.30.3: the v3 features
| Feature | Evidence |
|---|---|
| Scoper: a bounded task, or one question to the author | Layer 1 |
Completion judge, including impossible (no false met) |
Layer 2 |
| Sandbox checks: a seeded defect fixed before the push, 0 fix runs | Layer 3 |
Test-first tester: a contract committed first; not_testable runs without one |
runbook 21 |
| Splitter: 3 parts in 8 min, with a merge order | runbook 17 |
| Slack intake: draft, edit, ✅, the thread follows the room | runbook 22 |
| The factory from Claude Code and OpenCode | runbook 19 |
RunLore agent to agent: alert → investigation → factory/publish → fix PR → merge → soak → resolved |
runbook 20 |
| Capability profiles: an internal run naming a public-only alias is refused at admission | runbook 14 |
| Kimi K3.1 Pro as reviewer and Mistral Medium as implementer, cost within 1% of the gateway | providers |
| Spend per identity matches the gateway per run | runbook 04 |
AWS (EKS), Maku v0.32.0 to v0.32.3: the merge gate's human path. Full record: AWS results.
| Proof | Result |
|---|---|
| Approve-to-merge (N6) | PASS on v0.32.3. The owner approved #271 at 32d1731b; the merger App merged it at that head 14 s later. Task Done / merged, mergedHow: approved, approvedBy: Smana, no armedAt (outside the caps), labels factory/merged:docs + factory/approved-merge. On v0.32.0 the merge was right but its record was lost (maku #302, fixed) |
| Approval, then a force-push (A7) | Safe: the stale approval was not counted; no merge |
| A hand-off names one action and writes a replayable decision record | PASS |
| Regression breaker and recovery (M1, N8) | A regression paused the class; three clean merges lifted it (recoverAfter: 3) |
| Follow-up detection (M2) | 1/1 follow-up labelled, 1/1 unrelated PR left alone |
| Shadow while paused (AM4) and under a cap (N7) | shadow_would_arm recorded with paused=true, and on cloud-native-ref#2700 with capped=true |
dead-links drill (L2) |
Agent PR cloud-native-ref#2697 auto-merged and verified by the oracle. factory/drill + factory/revert → one revert PR, #2698, which the merger merged unattended (maku#158). Tally merges=1 drill=1 bad=0. The next decision, on #2700, read paused=false: the drill was not counted. The class is back in shadow |
| Request changes, then approve (A5) | PARTIAL: the revision run started; the return on approval was not read |
Not run: N1 policy replay, N3 release age, #182 the AwaitingCI bound, A4 the next-day return, G1 the host docs-links lift.
Features by area
Tasks before code
- Scoper: a labelled issue becomes a bounded task with named acceptance checks, or one question to its author (
factory/needs-author). An inlineAcceptance:paragraph counts. The harness nudges it atscoper.nudgeAtand stops it atmaxToolCalls(budget_calls). - Splitter: an oversized issue is proposed as parts, each its own sub-issue and PR, in an explained merge order; a maintainer accepts with
/factory split.
Code before review
- Sandbox checks: the implementer runs the repository's checks before it pushes. CI stays the judge of record.
- Test-first tester (session switch): a failing test contract is committed first.
- Search for agents: a read-only, fresh-context search tool answers the implementer's questions.
- Completion judge:
met,not_yetorimpossibleagainst the scoper's checks; continuations are time-boxed; anot_yetwaiting only on pending checks waits withinStuckAfter. - Reviewer: runs after the PR exists, with the task's brief.
Merging: the human path (Maku v0.32.0; see agents and the merge gate)
merge.approveToMerge: a maintainer's approval of the current head merges an agent PR outside the caps (factory/approved-merge). Since v0.32.2 an approval binds to the head's push time.- A handed-off task returns to the gate on an approval, on the next UTC day, or when a pause lifts.
factory/drill, set beforefactory/revert, makes a revert a drill the breaker does not count.merge.breaker.recoverAfterresumes a paused class after N clean, mature merges.- Shadow decisions no longer stop at
class_pausedorauto_merge_cap. Every decision writes anagent-factory-decisionrecord;shadow-merge-tally.sh --replayre-reads it. - Metrics
maku_factory_class_pausedandmaku_factory_handoff_to_merge_seconds; a "Human path" dashboard row; theAgentFactoryClassPausedLongalert; runbook 12. - Classes:
docs-linksis live;dead-linkspassed one live drill and is back in shadow;deps-patchis in shadow;deps-minorobserves.
Harness roles (Maku v0.32.0, harness on AWS since crossplane-configuration v0.9.31)
- The judge waits for pending checks and quotes the failing log;
scriptshas a judge. - Run cost by role (
run_cost_usd{role}) and its panel; a timed-out model call is retried once; steering notes.
Intake
- Slack (
maku-slack): mention the factory, edit the draft in the thread; a maintainer's ✅ files the issue and starts the task. - Coding agents: Claude Code and OpenCode file, start, follow and check out work through
maku, its MCP server and thefactory-handoffskill (coding clients). - RunLore (session switch): an alert becomes an
investigatetask;factory/publishturns its proposal into a fix PR.
Models and spend
- Capability profiles: a model allow-list per role and data class, compiled into the gateway's rules; every run is pinned to one model.
- Moonshot (Kimi K3.1 Pro) and Mistral (Medium, Small), public data only, selected per class with
loops.<class>.models. - Spend per identity with a cost cross-check alert; cache-read alerts; the daily task cap refuses at intake (
429 daily_task_cap).
Rooms
- The approvals page, a status line per room, forking a room into an attended run.
- The room list refreshes on its own (10 s default, pausable) and the title counts rooms waiting on you. The run strip labels each fact and has a Next box with commands to copy.
Names and docs
- The component formerly named agent-platform is now Maku: images, charts, CLI, CRD group
maku.ogenki.io, metricsmaku_factory_*/maku_rooms_*. The product is the Agent Factory. - The docs are reorganised into use / how it works / tune, with old URLs aliased (#272–#276). The v3 clip says who merges (#276).
Bugs found live and fixed
| Fix | Release |
|---|---|
maku #297: the judge matches a named path whole (a path.md: proves line stalled a finished run) |
v0.32.1 |
maku #298: migrate-group retries a delete that races the controller (kind e2e flake) |
v0.32.1 |
| maku #301: an approval binds to the head it reviewed via the push time, not GraphQL's moving commit oid | v0.32.2 |
| maku #302: a merge's or revert's decision is written as soon as GitHub takes it (an approved merge had been recorded as a class auto-merge; the same race could open a second revert PR) | v0.32.2 |
maku #303: unread paused= / capped= print - |
v0.32.2 |
maku #306: an oracle class names its fallback (the CRD refused every dead-links Task) |
v0.32.3 |
| cloud-native-ref #2691: the host's from-git overlay test skips its tree half on a pre-release pin | host main |
Upgrading from v2.0.0
- CRD group (breaking).
Room,TaskandAgentRunare served undermaku.ogenki.ioonly. A cluster with live objects moves them withmaku-broker migrate-groupin a quiet window (migration); a fresh cluster needs nothing. Apply the chart's CRDs first: Helm does not upgradecrds/. Both live clusters were built fresh, so the migration is proven in kind e2e only. - Names (breaking). Images
ghcr.io/smana/maku-*, chartsoci://ghcr.io/smana/charts/{maku,maku-factory}; signatures come fromSmana/maku/.github/workflows/release.yaml. The CLI ismaku:maku setup <agent>replaces aroomctl mcpentry. - Metrics (breaking). Only
maku_factory_*andmaku_rooms_*are served; the dashboards and alerts here read them. - Deploy order. crossplane-configuration v0.9.31 (harness and bridge v0.32.3) reaches the cluster before the factory.
- Defaults. Everything new is off by default in Maku. This release turns on
merge.approveToMerge: trueandmerge.breaker.recoverAfter: 3for both repositories. Session switches (the tester, RunLore, providermodels,human.mcp.sessionStart) are on only for a live session. - Owner keys. Public runs need a funded Z.ai API wallet, separate from the coding plan (error 1113 stops every public run). Kimi, Mistral and Slack keys for those features.
- After an OpenBao restore, check that the policy-bot webhook secret matches the GitHub App's.
Known limits and open items
- The approval binding (maku #301) is proven by tests; the live force-push proof ran on v0.32.0, where policy-bot's dismissal kept it safe. Residuals in maku#304 (open).
- The room page's "Your move" still says to bypass when the move is to approve: fixed in maku#308, pending a later Maku release.
- Open: maku#279 (status cost freezes before the final settle), maku#280 (a budget-exhausted run's ledger misses its last spend).
- Built, not proven live: search's value, the tester's holds, the scoper's
budget_callschain, the judge's failing-log quote (harness egress to the Actions log host is not opened). - AWS ran public work only (GLM via Z.ai). Internal runs, Kimi and Mistral were proven on GCP only.
- More auto-merge classes need a full day's live proof. Mistral is not recommended as an implementer. Per-person caps are counted, not refused. The eval bench is deferred.
- Not in v3: public work on Claude, memory across tasks, parallel writers on one branch, switching models mid-run, approving from Slack or MCP (why).
Versions
| Component | Version |
|---|---|
| Maku: factory, broker, Slack app, chart, CRDs | v0.32.3 (#269) |
| maku-harness, maku-bridge | v0.32.3, via crossplane-configuration v0.9.31 (cloud-native-ref#2695) |
| RunLore | v0.18.0 (host pin; its link to the factory is a session switch) |
| Previous release | v2.0.0 |