Releases: mikeroySoft/factory
Releases · mikeroySoft/factory
Release list
factory 0.3.8
Immutable
release. Only release title and notes can be modified.
Compared against 0.3.5 (e3abd2b). Released channel stable points at v0.3.8. Versions 0.3.6 and 0.3.7 were not released.
- Idle dispatcher passes write no lifecycle rows for parked tickets (#130): a
manage/landingcheck that changes nothing no longer journals its enter/lock/handoff/exit trail; passes that act keep the full trail. (PR #133) - Bound the dashboard snapshot's executions list (#134): Ops no longer loads hundreds of MB on long-lived repositories.
- Roadmap stops reporting
runtime_unavailablefor closed or runtime-known tickets (#137). - Dashboard docked ticket drawer: desktop docks the detail drawer beside the queue; narrow screens keep the modal overlay with focus trap, Escape and reduced motion. (PR #143)
- Upstream sync lands the newest conflict-free upstream prefix instead of parking the whole backlog behind one conflicting commit. (PR #117)
- Split-aware eval promotion contract (#126):
docs/eval-promotion-contract.mdandfactory learn --promotion claim.json; keep only when the held-out split improves. (PR #128) - Experiment evidence in a fresh FM session (#99); reviewer-calibration corpus grown to 11 cases with confirmed oracles and adjudication rows (#34, PRs #144–#148).
- Repository gate runs
uv run --frozen --no-managed-python, so declared dependencies are installed anduv.lockis never rewritten (PRs #127, #129); the interpreter-escaping test fixture is portable to relocatable Python builds (PR #135). - Journal rotation (#131):
.factory/events.jsonlrolls into gzip segmentsevents.jsonl.N.gzunder the journal flock once it passes[journal] max_mb(default 64;retentionsegments, default 8). Open-executionlifecyclerows stay live; every outcome row stays readable vialifecycle.read_events, which now includes segments. Only closed-executionlifecyclerows of expired segments are dropped; the oldest kept segment grows with carried outcome rows. - Host-owned worker argv prefix (#3):
[defaults.worker_wrap]/[repo."owner/name".worker_wrap]commandis prepended to every worker launch (all labels); a committed[worker_wrap]fails to load.doctorchecks its executable on PATH. A launch prefix, not sandboxing. - Bounded worker boot/resume context (#89):
factory dispatch's worker prompt gets a## Resume contextsection, built only from the latest retained accepted result (#88) and the local plan-bound journal (#57), when a ticket has prior retained history. It reports the prior accepted head/result and whether the admitted scope has since moved (unchanged/changed/unavailable); never a worker log, prompt, or transcript, never a scope rewrite, and no widened context budgets. - O1 bounded observation producer (#97): stdlib-only
experiments/o1-observation/observer.py(start/status/stop/report) with frozenprotocol.json. Opens.factory/events.jsonlO_RDONLY, freezes a chunk-digested byte range (256 MiB cap, suffix + explicit coverage beyond it) before classifying the latest 12 recordedmerged/escalateticket executions by exact structured reason codes only. Runs land in exclusive, never-overwritten directories under the main root's.factory/experiments/o1-observation/, capped at 10 minutes, 64 MiB output and three iterations per lineage; no subprocess, network or model calls. Disposition startspending. - Experiment-informed roadmap next actions (#100): each roadmap/initiative plan (CLI
evidence investigate, FMfm_investigate, dashboard Roadmap) gainsexperiments— the latest retained run of every experiment whoseprotocol.jsonnames that initiative asroadmap, with its decision link, latest result, per-run recorded disposition and accepted/rejected/deferred/pending grouping, markedinformed_byand never a blocker — andnext: the next action (implementordecide) with a cited explanation from acceptedNOW/NEXT/THEN/LATERPlan tiers, eligibility and realBlocked byedges, plus separate current-priority decisions, runnable, blocked, in-flight, later-held and displaced work and unresolved evidence. Read-only.
factory 0.3.5
Immutable
release. Only release title and notes can be modified.
Compared against 0.3.0 (289cac5). Released channel stable points at v0.3.5.
- Retain independently accepted worker handoffs outside worktrees (#88): exact-head provenance and integrity, 90-day content/365-day metadata, 256 KiB artifact/1 MiB bundle/256 MiB repository limits, explicit incomplete/privacy/expiry states, and fail-closed cleanup when retention fails. Add local paged
kind: resultevidence reads and console/briefing consumption without widening context budgets, transcript ingestion, or execution authority. (PR #113) - External pull-request review lane (#5–#9): discover open, non-draft PRs opted in by
needs-reviewor a review request, preserve that opt-in after viability verdicts, publish cited reviews bound to the recorded head, re-review changed heads within bounded rounds, record fail-closed required-CI readiness, and surface the six-state Ops queue plus actionable Inbox rows. The lane never edits or pushes contributor branches and never merges their PRs. Viability replay remains keyed to the label-add event, not the PR head. - Bundle Cyberpunk, GPUFlo, District, Factory, ROCm, Porcelain, Sandstone, Slate and Forest dashboard themes with a persistent browser-local picker, preserving configured repository CSS as the default. Keep the title/status row above the consistent navigation row in a shared sticky header. Open Ops at the root without automatic FM briefing requests; explicit Inbox and existing deep links remain available. (PR #110)
- Add dashboard Settings for exactly five repository controls: concurrent tickets, time limit per ticket, worker/gate attempts, reviewer revision rounds, and Factory Manager model. Show effective values and sources, require an explicit reviewed save, reject stale writes, preserve unrelated TOML comments, and keep changes local and uncommitted. TOMLKit is the sole required Python dependency on current
main; it is loaded only by settings write helpers. (PR #111) - Shared roadmap and owner attention (#58): dashboard and read-only FM consume the same initiative/routing/drift producers. Owner/team filters select questions without changing canonical plans or granting authority; source failures, unknown ownership, missing baselines and assigned-but-non-runnable human takeover stay explicit. C1 adds roadmap, initiative and retained-drift reads with citations; declared stage and implementation closure never prove owner-confirmed delivery. Complete-content revision identity and historical accepted evidence remain intact. No publication, intake release, deployment or live two-human acceptance is implied.
- Immutable initiative bindings (#57): linked tickets carry a schema-1 baseline of the complete initiative's normalized Outcome, Boundaries, Plan, and Success evidence; admission pins the full human-approved ticket snapshot for every retry and fails closed on malformed, changed, incomplete, or unavailable sources while legacy unlinked tickets remain unchanged. Read-only
factory plan baselineandfactory plan driftexpose proposals and accepted-versus-live drift without mutation or inferred attribution. ManagerREWRITEpreserves the exact accepted binding, andSPLITpreflights the live source and every child before creating intake-ready work; models cannot rebaseline. - Correct routed-handoff integration (#56): neutralize incidental mentions in explanations while preserving validated destinations; journal manager
CLOSEcomment receipts on the correct PR/issue timeline; attempt terminal handoffs even when an earlier manager phase fails without hiding that error or allowing new scheduling. Refresh the architecture atlas with the handoff phase and current manager/dispatch citations. - Preserve human takeover after a failed escalation comment: without the current escalation's recorded comment, the manager fails closed and leaves routing to the human handoff pass. Later handoff receipts cannot authorize recovery or hide human unassignments. (#56)
- Routed human handoffs (#56): once automatic recovery for an escalation is terminal (manager
HUMAN, manager command failure as an explicit unable-to-diagnose,manager.roundsexhausted, no manager, or an escalation the loop can never act on again: unapplied decision, missing packet, unreceipted escalation comment),factory managepublishes one public-safe request per escalation generation with the question, bounded evidence links, proposed next step and thefactory plan routeowner/candidates and rationale; mentions only on the initial handoff and on an actual owner change, never assigning anyone. Intent and comment id are journaled (handoff,commentrows); a crash or failedghbetween them is reconciled from the timeline before any retry, a failed lookup posts nothing, and--dry-runjournals nothing. Human-takeover checks now trust only recorded comment ids (escalation, manager and handoff comments), never text prefixes; an edited recorded comment is human activity. Upgrade note: the first pass publishes a request for every openready-for-humanticket whose escalation is already terminal, including pre-#56 escalations (their comments carry no receipt, so the manager no longer runs on them). - Manager PR frontier (#15):
factory manageobserves every factory-ownedagent/<n>PR through the schema-1 feedback producer (#79) and escalates once on red CI, undelivered current-head feedback, ormanager.stale_daysinactivity; late feedback is delivered at most once per(evidence_id, source_revision)and never from partial coverage or unverified ownership. New managerCLOSEdecision closes the PR and proposeswontfix-proposalon a human issue (closes a factory-created child);wontfix-proposalis now a provisioned label.manager.review = "all"is implemented: thefactory-approvedlabel waits for a managerAPPROVEbound to the exact head, never re-bound across a refresh.pr-openedjournal rows carry the PR number;SPLITrecordsissue-created. - The
initiativelabel is now an unconditional execution guard, read fresh at each owning boundary: triage refuses before any model call,factory dispatch(including--ticket) refuses to claim, the manager refuses viability and escalation handling, and the merge stage refuses anagent/<n>PR whose ticket is an initiative. Refusals are logged, visible in--dry-run, and mutate nothing. Ordinary tickets are unchanged. (#55) - Initiative issue template (
.github/ISSUE_TEMPLATE/initiative.md, labelinitiativeonly) installed byfactory init; theinitiativelabel is provisioned with the others. Read-onlyfactory plan list/factory plan inspect Nemit schema 1 JSON: declared status/owner, sections, implementation links and linked-issue state, with partial/malformed results explicit. Reading an initiative grants no execution authority; #55 now enforces the initiative execution guard at every owning boundary. (#53) factory plan route N --reason <requirements|implementation|ci|unknown> [--path P]... --jsonand the optional[collaboration]section (fallback,reasons.<reason>,components."<exact path prefix>") resolve the human decision owner of a ticket read-only, with status (selected/candidates/unassigned/invalid), source revision and step-by-step provenance. A**Decision owner**ticket section is a human override;@org/teamis rejected on user-owned repositories; no section means unchanged behaviour. (#54)- Distinguish missing optional routing owners from invalid declarations, bound overrides to their own sections, retain rejected mixed-destination provenance without selecting a survivor, and reject dead reason mappings and duplicate normalized component prefixes. Preserve coverage notices on invalid invocations. (#54)
- Add
factory chat: a supported, read-only Factory Manager console over the pinned upstream Pi runtime (console/app) and the schema-1 evidence interface. Seven bounded evidence tools, no shell/edit/write/dispatch, isolated console-owned settings and provider auth, and an explicit provider/model disclosure gate before any inference. Every start and--continueresume reobserves fresh evidence rather than trusting stale conversation. Node/Pi stays an optional console dependency (npm ci --ignore-scripts --prefix console/app); ordinary Factory execution never needs it. (#86) - Add dashboard
/chat: the selected three-column Factory Manager layout with live repository-wide/case/run evidence, citation inspection, truthful request activity, Motion-powered reflowing context panels, and browser-local conversation history. The page remains read-only and uses the existing bounded/api/asktransport. - Add schema-1 source-versioned PR feedback at full dashboard
tickets[].pr.feedback, shared by Review, Inbox and briefing. Retain simultaneous native review/thread/check evidence and provenance-backed Factory reviews with deterministic identities, explicit unknown/partial coverage, fixed 100-item/two-page/20 KB-body/32-error/30-second bounds, and head-race handling. Reviews carry the provider's ownupdatedAt, so an edited review revises its source revision. Detail reads run only for open PRs; closed and merged PRs keep the schema-1 envelope withnot_collectedsources, which is unknown rather than empty or unsupported. Read-only: no feedback delivery, readiness or merge authority; runtime JSON is unchanged. (#79) - Add optional Codebase history: stable commit-timeline maps, baseline comparisons, confidence-aware relationships, pinned source citations, and bounded background refresh through
factory[atlas]. (#67) - Add opt-in direction viability to
factory manage:needs-reviewPRs beforeneeds-viabilityissues, evidence-cited BUILD/DONT_BUILD/DEFER comments, and label-event replay protection. Only issue BUILD entersneeds-triage; PRs remain recommendation-only, with no review or handoff mechanics. - Fix manager prompt transport to use files, including
factory learn; validate manage...
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.