factory 0.3.0
Changelog
0.3.0 — 2026-09-08
Compared against 0.2.0 (f9122cd). Installed fleet-wide through District at 9478e9d.
Manager stage (inert until [manager].command is configured)
factory manage: resolves untouchedready-for-humanescalation packets with a closed, code-applied decision menu —RETRY,REWRITE,SPLIT,ROUTE,HUMAN. Malformed output isHUMAN. Amanageevent is recorded before any GitHub mutation; a failed mutation leaves the ticket with the human, records a lifecyclemechanism_failure, and is never replayed. (#13)[manager]config table:command,rounds,review = "escalated" | "all"; legacy string commands are parsed withshlex.factory doctorreports the manager only when configured. (#12)- Manager notes:
.factory/manager/notes.mdread into every manager prompt, with write-back and consolidation. (#14) factory learnruns through the manager when configured and opens achorePR carrying only.factory-lessons.md; unchanged without[manager]. (#16)CURATEdecision, accepted only fromfactory learn: proposesAGENTS.md/.omp/skills/**/CONTRIBUTING.mdchanges as achorePR; verification paths are never touched. (#18)[defaults.manager]caps (max_active_cap,budget_min_cap) for District's fleet-level manager pass. (#21)- Structured escalation packets written by
escalate()to.factory/escalations/<n>.md: reason, attempt table, gate/review evidence, kept worktree. (#11)
Review stage
- Reviewer contract grounds every blocking finding in an acceptance criterion, a documented rule with its source, or a concrete correctness/security defect with trigger and impact. Required fixes are separated from optional suggestions;
REVISEonly while required fixes remain. Net-new abstractions beyond the brief need justification; missing justification alone does not block. A passing gate does not excuse a defect it did not detect. (#36) - Reviewer defaults to
ompwithanthropic/claude-fable-5-1.
Merge stage
- Fix:
refresh_pr_brancherased a PR whoseagent/<n>branch had no local copy — it started the branch frommain, gated an empty tree, and force-pushed it; GitHub then auto-closed the PR. Refresh now starts fromorigin/agent/<n>, refuses to push a head with nothing ahead ofmain, and pulls such a PR from merge candidacy so it escalates once rather than starving the queue. (#49) - Fix: upstream-sync PRs were squashed once upstream moved past the PR's tip, dropping the ancestry the sync exists to preserve. Merge method is now judged by the PR's merge-base with upstream, not upstream's current tip; sync PRs merge
mainin rather than rebase. (#41)
Workers
[workers.<name>].whenrules route tickets by label/state;ci-fixandconflictdefault profiles. (#20)- Per-ticket brief at claim time:
.factory/brief-<n>.mdfromgit log -S/grep of ticket nouns, recent PRs touching those files, the triage brief, and matching lessons — deterministic, token-capped, appended to the worker prompt. (#17)
Runtime evidence and observability
- F01: authoritative execution lifecycle journal —
enter/exit, child processes, handoffs, outcomes and reasons — per stage, in.factory/events.jsonl. (#26) - F02: known waits and evidenced lock ownership;
ticket_lock_contended,merge_lock_contended,ci_pendingand similar are recorded, not inferred. (#27) - F03:
factory dashboard --runtime-json— bounded schema 1 runtime projection from local read-only evidence only; partial source failures stay structured. (#28) - Bounded read-only FM evidence interface with a Pi consumer; grounded full decision briefings and contextual FM questions. (#25, #38)
- Runtime quality graded independently of history-window completeness; journal read once per full snapshot. (#43)
Stats and dashboard
- Human-touch metrics: escalation count, resolver attribution (human/factory/unknown), minutes in
ready-for-human, re-queues;escalations_per_weekandhuman_resolved_pctin--jsonand the dashboard KPI row. (#10) - Per-label pass rates in
factory stats. (#19) - Dashboard and site adopt the mikeroySoft design system; sage product theme.
Install and onboarding
factory installruns triage before dispatch in the unit, jitters timers, and serialises triage on the host lock; restarts only units that existed and changed.factory initwrites.github/workflows/ci.ymlwhen the repo has no workflow;doctorwarns on a missing or placeholder workflow.- Repository adopted under District;
agent-factoryrenamed tofactory.
Known limitations
- The manager stage runs an arbitrary configured executable; configure the agent CLI in read-only/no-tools mode. Factory instructs it not to edit files but does not sandbox it.
- A stale local
agent/<n>(behind the remote after another host advanced it) can still win inensure_worktree;--force-with-leasedoes not protect because the refresh fetches first. Only relevant with a second dispatcher host. Tracked on #49. cargohas no minimum-release-age control; crates.io installs are unguarded by District's package-age policy.