Repository navigation
Releases: motock/fagan
Release list
v0.8.0 - Agent-log scorecard, write-path guards, security fixes
Added
Agent tooling
restore_filegains an optionalfrom_basemode that restores a file
from origin's default branch, giving an agent a first-class way back when
its own commit captured a bad change (the destructive-git block refuses a
base-scoped checkout). The default path is unchanged, and the per-path cap
applies to both modes.scripts/agent_log_scorecard.py <worktree>/agent.log [--json]reports a
per-attempt scorecard from an agent log: step totals, per-tool counts, the
first mutating step, the productive-step ratio, guard trips by normalized
label, and the outcome with its done summary or parked reason. It slices
at the final[boot]line so a resumed run is scored on its last attempt,
and reads the same grammar the log writers emit.
PR review
- A warn-only
pr_title_mismatchnotification fires after a PR opens when
its title shares no 4+ letter word with the story summary or the changed
files. It fails open and never alters the PR, verdict, or merge path.
Scheduler
- The scheduler notifies when the running checkout trails upstream by
commits that touchpipeline/orapp/, since merged orchestration
changes are otherwise invisible until the daemon restarts. The notice
dedups on the upstream SHA and points atscripts/reload_pipeline_daemon.sh.
Changed
- Python 3.11 is now the floor everywhere — install check,
ruff
target-version, and a new 3.11 CI leg (3.11-3.14) — with a consistency
test so the three cannot drift. Python 3.10 is no longer supported. - Dependencies:
fastapi>=0.143.0,ruff==0.17.0. - The on-device dispatch tier is documented as not cleared for story
dispatch, including its measured first-pass-clean rates and the preflight
an operator must run to route it back.
Fixed
Security
- Acceptance fixture paths that are absolute or contain
..are rejected at
ingest and skipped with an operator notice at dispatch, so plan-authored
data can no longer write outside the worktree (security audit 2026-10-19). - Pipeline secrets (
PIPELINE_NOTIFY_EMAIL_PASSWORD,PLANE_API_KEY,
GH_TOKEN,GITHUB_TOKEN) are stripped from every agent subprocess
environment, including locally spawned agents that inherit the parent
environment.
Dispatch and merge
- A story re-dispatched while still
todono longer preserves a stale or
half-written acceptance fixture from a dead earlier attempt: the skip is
gated on the story's status, so a fixture-only oracle cannot go green with
no implementation (Mode 45). - A merge-gate CI-fail rework keeps any earlier review feedback instead of
replacing it with only the CI error, so the implementer cannot silently
re-break what the reviewer asked for. - An escalation whose resolved target equals the story's current
backend/model is skipped rather than resetting the rework budget and
inflating the first-pass-clean metric.
Local agent
- Every write path rejects a file whose last non-blank line is a trailing
omission marker (e.g.# ... (rest of file remains same)), so a
context-exhausted model cannot silently land a truncated file. replace_linescomputes dropped top-level symbols unconditionally, so a
renamed definition can no longer slip past the symbol-loss check.create_fileoverwrites of non-.pyfiles reject content that drops more
than ~10% (floor of two) of the original lines unlessconfirm_removals
is set, covering markdown and other text files the AST guard cannot see.
Review, chat and classification
- The review loop makes one final no-tools call for a verdict when it
exhausts without one, failing closed to the existing no-verdict path. - At the turn cap, chat strips
[TOOL_CALL]markup and answers in prose; a
near-cap nudge asks the model to do so before the budget runs out. - Legacy event-less sidecar notices map to the same reason names structured
events use, so escalations are no longer double-counted and benign topic
words no longer mark a clean story non-clean.
Scheduler, usage and notifications
- The staleness check receives the config fingerprint it compares, so the
trailing-checkout advisory actually fires in production. - Subscription usage percentages parse when the
resets ...suffix is
absent (e.g.Current session: 0% used), instead of falling back to the
request-count approximation and potentially pausing an available
subscription. - The review-gate deferral notice fires once per gated episode instead of
once per scheduler tick (one plan accumulated 159 identical records in
3.2 hours).
v0.7.0 - Detached test-author step, scheduler and review-gate fixes, local-agent guards, bench tooling
Added
Dispatch
- The test-author step now runs detached from
dispatch_storythrough
non-blocking start/collect primitives, with a decision step for when to
use it; the planner block moved intodispatch_phases(no behavior
change for that extraction). - A PR title is derived from the branch's Conventional Commits subject
.
Local-agent harness
view_filereturns a repeat advisory instead of re-emitting identical
bytes, and the one-sided-read latch guard keys reads by their own bound
so orientation in a large file is not a false-positive park.FULL_SUITE_DONE_BARis armed on the oracle harness, the oracle gets
the story summary in its env, and its auto-commit has a story-derived
subject.
Scheduler
- Health is written at startup before the first reconcile and refreshed
during long watchdog joins;SchedulerDaemon.start()'s reconcile is
bounded by the watchdog.
Benchmark tooling
- Every role is pinned per arm through
role_config, the grid refuses to
run when its pins cannot resolve, and a one-command published-matrix
driver records pinned provenance. - A Tier 3
inventory_paginationcross-module task, Claude dollars per
success in the scorecard, preserved dispatch cost logs, and Claude
cells skipped when credits or rate limits run out.
Changed
- The maintainer's home path is scrubbed from archived plans, specs and
retros, and the committed launchd files use a placeholder home
directory. - The exported overlord policy spec matches the live parked-story policy.
- A bare
pytestrun is clean on a fresh clone.
Fixed
Scheduler and merge
- A dispatch lease whose owner pid is dead is treated as not live.
- CI status queries run in the scoped plan repo, and an unreadable CI
status parks the story instead of being treated as no CI. - A trailing DONE line in
agent.logcounts asagent_donein the wedge
scan.
Review gate
ClaudeCliDriver.resource_statusacceptsmodel_tag, so the review
gate no longer crashes the scheduler.- Review is gated on the model it will actually run, the Claude usage
pause is re-derived from cached percentages, and consecutive
rate-limited review deferrals are bounded and then park.
Local agent
- A successful
create_fileresets its own repetition count.
v0.6.0 - Language-agnostic gates, global rules installer, security-audit tracking, file splits
Added
Language-agnostic gates (LAG)
- A repo can declare its test, lint and build commands, and its
test_globs, in a root.fagan.json; the scope gate treats declared
test globs as test files (#1037, #1039). - Build, test and lint command detection moved out of
build_detect.py
intoecosystem_detect.py, which now also detects Go and .NET and fails
visibly on any other unsupported ecosystem (#1036, #1038). - Maven and Gradle projects run
verify/checkthrough the project
wrapper when one is present, and their test failures are parsed so
acceptance runs scope to the failing JVM test classes (#1041, #1044). - One test-path classifier is shared by the scope gate, ingest and
plan_conflict_ruling, and the ingest sizing check recognises any
backticked relative source path (#1035, #1040).
Global rules bundle
- An opt-in installer (
scripts/install_global_rules.py, hinted by
install.sh) writes the engineering standards and the pipeline workflow
rules into each supported agent CLI's global instructions file inside a
managed block, honouringXDG_CONFIG_HOME; documented in the README
Quickstart and REFERENCE (#992-#1000, #1019, #1021).
Security audit tracking
- The
record_security_auditMCP tool and a per-repo audit record, with
due thresholds and a scheduler notice when a repo is due (#1009-#1012). - The security-engineer verdict is posted on the PR, and ingest warns when
a brief needs a security review the pipeline will not run (#1007, #1008).
Scheduler and harness diagnostics
- The scheduler warns at startup when the launchd plist and the MCP
server config disagree, by diffing the two environments rather than a
hand-maintained catalog; secret-like and non-PIPELINE_values are
masked (#1027, #1032, #1059). - Each dispatch attempt's log starts with a
[boot]line, and a watchdog
kill snapshots the end ofagent.loginto the plan dir (#1023, #1024). - A rejected story is re-reviewed when the reviewing logic has changed,
and a skipped re-review is notified once per SHA (#1049, #1052). - A two-tier CI gate enforces the 1000-line rule: blocking on production
Python, warn-only elsewhere (#1048). - The one-line installer finishes Claude Code setup, and the README leads
with a demo and the one-line install (#982, #987).
Changed
- A triage
mark_doneruling requires a merged PR before it marks a story
done, and a PR merged outside the pipeline is recorded asstory_merged
whenmark_story_donecloses it (#1033, #984). - Each automated rebrief cause has its own event name, and the rebrief
header detectors match an occurrence rather than a mention (#1050,
#1031). effective_env_config'seffectivefield is labelled as this-process
rather than resolved against code defaults (#1058).scripts/local_agent.py,scripts/local_agent_oracle.py,
app/dashboard.py,pipeline/dispatch.py,pipeline/story_status.py
andpipeline/worktree_patch.pywere each brought under 1000 lines.
No behavior change (#1051, #1053-#1057).- The retro backlog is capped so the pending-marker list stays drainable
(#1047).
Fixed
Dispatch & merge
-
Dispatch is refused when a plan's
repo_rootno longer exists, and a
story that is already done or has an open PR is not re-dispatched
(#1016). -
A story's registry model-name pin resolves to its tag, and the scope
gate treats nested and Rust test paths as test files (#1004, #1003). -
Every pipeline runtime marker is self-excluded in worktrees, and the
acceptance oracle is kept out of story commits (#1014, #1015). -
A dispatch attempt clears the previous attempt's done markers, and the
watchdog skips its SIGTERM when the stored pid belongs to a process
started after dispatch (#1025, #1026). -
Triage defers a transient overlord failure instead of parking the story,
and reports git evidence against the worktree-resolved base branch
(#981, #1042, #1043). -
Triage's sweep no longer writes back a stale whole-manifest snapshot: it
re-reads the manifest and applies only the sweep's own changes, so
writes made while a ruling was in flight survive (#1061).
Tests
- The smoke precondition test no longer depends on the operator's local
model registry (#1062).
Reporting accuracy
- The local-success report is filtered to a single repo and names its
cohort; the plan summary flags a reviewer-bounced story beside its
baseline verdict; ruling and sizing notices carry their story key
(#1030, #989, #983, #979).
Dashboard
- The toast message gets its own full-width line (#990).
v0.5.0 - Local-dispatch convergence, module splits, cold imports, reporting accuracy
Added
Local-dispatch convergence (LDC)
- A local agent that reaches its step cap now finishes as done when its
branch carries production changes against the default branch and the
full suite and lint pass, instead of burning a rework cycle on work that
already landed. A rework redispatch that produced no new commit starts
the next attempt from a fresh context seeded with a root-cause
diagnosis, and a thirdrestore_fileon the same path in one run is
refused (#932, #933, #937, #938). - The test-author phase is skipped for stories whose declared
filesare
all docs or config, and its prompt now carries a size budget and asks
for structural assertions rather than prose wording (#928, #934). - Each completed plan's summary, including a per-story first-pass-clean
verdict, is written to<plan>.report.mdinPLAN_DIR(#931, #936).
Changed
- Re-ingesting an already-ingested plan is rejected when any story lacks
an explicitkey. Such a re-ingest used to mint duplicate stories
that dispatched concurrently; give every story akeyto re-ingest
(#929). triage.py,service.pyandserver.pywere each brought under 1000
lines, extractingtriage_patch_acceptance,triage_story_actions,
service_decisions,service_role_configand
server_tools_lifecycleas their own modules. No behavior change
(#941-#944, #946).- Every
pipelinemodule now imports cold, in any order - the remaining
import-order dependencies onpipeline.serverwere removed and the
stale comments that described them corrected (#966-#969, #971-#974). - Improved the descriptions of the lowest-scoring MCP tools (#927).
Fixed
Dispatch & merge
- A story's bare registry model name now resolves to its tag instead of
silently falling back to the default local model (#930). - A worktree whose HEAD is detached is re-attached to the story branch
before the rebase, or the story is parked when re-attaching would
orphan commits (#965). - A rescoped story's PR title is refreshed when the PR already exists, so
the squash commit subject describes the final work (#945).
Local harness
- A capped
view_fileresult is cut on a line boundary and says the file
on disk is intact, so a weak executor no longer "repairs" a file that
only looked truncated; the scope gate's revert advice is now runnable on
the local harness (#958, #961).
Reporting accuracy
- The plan rollup no longer counts the synthetic uncorrelated bucket as a
story, collapses metric groups that share a story key, and counts
watchdog kills and reviewer send-backs as rework cycles (and a reviewer
send-back as a dirty first pass). Per-story metric, sizing-auto-route
and preflight-override notices carry their story key; step-cap and
give-up rebriefs emitbrief_patched; retry-cap notices render the cap
instead of an object address (#948-#951, #954-#957, #959, #960).
Dashboard
- A long multi-line notification toast now renders cleanly (#953).
Test determinism
v0.4.0 - MCP registry listings, systemd deployment, overlord autonomy, MCP tool surface hygiene
What's new in 0.4.0
Added
MCP registry listings
- Added
server.jsonfor the official MCP registry
(io.github.motock/fagan) and a Dockerfile for Glama's build/
introspection check, plus a Glama badge and dashboard screenshots in the
README (#811, #812).
Linux systemd deployment
- Added systemd user-unit templates for the advance-scheduler daemon and
the usage-poller, a service+timer pair, a logrotate template, a
scripts/generate_systemd_units.shgenerator, and README documentation
for the Linux setup path (#822, #824, #825, #831, #838).
Dashboard plan-ingest picker & Comms polish
- A new backend endpoint lists plans available to ingest, backing a
dynamic select in the ingest picker in place of free-text plan-name
entry; the Comms panel shows a typing indicator while a reply is
pending (#820, #821, #823, #828, #830).
Local-dispatch observability (LD90-W0)
- Every escalation, fallback, park and rework notice across
story_status,triage,escalation,review_orchestrator,
dispatchandadvancenow carriesevent,story_keyand
correlation_id. Afirst_pass_clean/disqualifying_eventsrollup and
a new purelocal_successclassifier feed alocal_success_reportCLI:
rolling first-pass-clean rate by dispatch tier, with a reason breakdown,
read from the plan notification sidecars (#850-#858, #865).
Reviewer & scheduler hardening (LD90-W5, MFR, SWH)
- The reviewer now recognizes and classifies transport failures (502/503/
504, timeouts) and defers the review like a rate limit instead of
charging them againstreview_inconclusive_count; a diff file-inventory
criterion was added to the review checklist. The reviewer's bash tool
and the notification-outbox drain phase are now bounded by a hard
timeout so a runaway command or a wedged drain can no longer hold a
scheduler tick open. The scheduler now publishes the checkout revision
it's actually running, and preflight reports it too (#861, #863,
#866-#873, #906, #907, #909).
Rework & done-bar correctness (FSU, TGE, SST, SU, HRG, ASB, RFW)
- A red full suite gets one retry before the done-gate rejects it.
Pre-existing baseline failures are now exempted from the tick-side
detached grade and both agent-side full-suite gates, with the baseline's
failing node ids recorded in the worktree for the agent to read. A
rework round that carries an acceptance block is graded on the same
done-bar the agent was originally held to; a rework transcript that
already claims done is never resumed; a reviewer-feedback rework round
can no longer be marked done on oracle-green alone. The agent scratchpad
is untracked before grading, and the planner/dispatch prompts now state
it must never be committed (#874-#885).
Overlord autonomy round 2 (OA2)
- Triage now recovers born-broken-oracle stories (
blocked_oracle),
resets its own attempt counter after a successful recovery, and skips
stories with an unresolved infra-transport failure instead of ruling on
them. Watchdog kills converge via a streak counter so repeated hangs
escalate.request_decisionfails open - parking the story for a human- when the overlord backend errors. Agent
give_upnow routes through
the existing rebrief diagnosis path instead of notify-only. Merge-park
re-adjudication was widened to the risk-threshold reasons the gate
actually emits, andPIPELINE_AUTO_TRIAGEnow ships enabled in the
shipped launchd template (#834, #886-#893).
- when the overlord backend errors. Agent
Resume-rebase remote sync (SRB)
- A resumed agent's story branch is force-pushed after the resume rebase
so the resumed agent's own push is a fast-forward, and the seed prompt
is now forbidden from pulling, merging, or rebasing the branch from
origin itself (#894, #895).
Post-LD90 priorities: file-size discipline & plan-conflict handling
(PLD90)
dispatch.py,story_status.pyandadvance.pywere each split to
bring their line counts under 1000, extractingdispatch_routing,
dispatch_attempt,dispatch_baseline,dispatch_worktree,
detached_gradeandadvance_mergeas their own modules. A new
plan-conflict classifier and overlord-ruling module distinguish a red
suite caused entirely by pre-existing, branch-untouched tests from a
real regression, routing the former to an overlord ruling instead of
burning a rework cycle. A scope gate sends a branch with out-of-scope
production changes back before review, naming the exact offending
paths.ingest_plangained an optionalfilesfield to scope and size
stories, with an ingest-time warning when a local/cloud-open-source
story's file scope exceeds the documented dispatch-sizing caps. The
reviewer prompt now receives the story's brief, sibling status and
Deferred lines (#833, #841, #896-#920).
MCP tool surface hygiene (MCPHYG)
- Prompted by an external tool-quality review:
check_story_statusis now
actually registered as an MCP tool - it was fully implemented and
documented but never decorated, making it unreachable via MCP.
mark_story_in_progressandmark_story_donenow serialize their
manifest writes under the same plan lock every other write path uses,
closing a race with the scheduler's tick. The duplicated
_VALID_STORY_STATUSESallowlist (each copy listing"done"twice) is
now a single source of truth. A newpatch_plantool edits plan-level
fields (currentlyrole_config) under the same locked, allowlisted
pattern aspatch_story.checkpointis renamed tocheckpoint_story
for naming consistency with the rest of the tool surface, with
checkpointkept as a working alias (#922-#926).
Changed
get_role_configremoved. It was a strict subset of
get_effective_config(5 roles vs. 9, fewer fields, same underlying
resolver) - useget_effective_config(plan_name=None)instead. This is
a breaking change for any external caller of the MCP tool surface
(#924).resource_statusnow uses a provider-aware default free-memory floor
(2048MB for MLX, 512MB generic default for Ollama/LM Studio), and local
model context sizing (num_ctx) is now driven by an empirically-tuned
per-model table and sized per parallel slot, in place of a single static
override (#818, #844-#846, #849).
Fixed
Merge & dispatch correctness
- Merge now pushes from the plan's own worktree instead of the pipeline's
REPO_ROOT; dirty worktree state is committed before the merge-gate
rebase instead of retrying the same unstaged-changes failure verbatim;
the merge gate persists its own fresh test result onto the story instead
of leavinglast_test_checkstale; the squash-merge commit gets an
explicit, stable title instead of trusting GitHub's single-commit
default, and no longer repeats the story key in the PR title; two
dispatch/decision-log bugs found while live-diagnosing a parked plan
were fixed (#819, #829, #835, #839, #840, #879).
Circular imports
- Broke a
pipeline.ci<->pipeline.build_detect<->pipeline.server
circular import that failed wheneverpipeline.ciwas imported first
(#843).
Scratchpad tracking
- A checkpoint commit no longer tracks
.agent_scratchpad.md, even if an
earlier commit already had (#836).
Rebrief & triage prompts
- The rework diagnosis prompt now receives the story's original brief so
it can't invent a fix that contradicts an already pre-authorized edit;
triage skips stories with an unresolved infra-transport failure instead
of misclassifying them, and keeps the real exception once the
escalation ladder is exhausted (#834, #837).
[no-new-tests] anchoring
- The opt-out token is now anchored to the start of the brief, so a
sentence elsewhere in the brief that merely mentions the token can no
longer accidentally trigger it (#833).
Dashboard/UI polish
- The Comms typing indicator now anchors after the thread with tighter
panel spacing, and the stale plan-board progress bar is hidden once the
executor signals completion (#830, #905).
Docs accuracy
- Fixed a stale
gpt-oss:20b32768num_ctxclaim and documented the
gpt-oss-20b-highoverride; documented the launchd install+reload
requirement and added a reload helper so a plist edit actually reaches
the running daemon; fixed the "Both routes" wording in the patch review
& apply section (#827, #846, #847).
v0.3.0 - Chat-driven patch apply, overlord autonomy, registry-authoritative routing
What's new in 0.3.0
Added
Chat-driven worktree patch apply (WAP)
- Chat can now propose and apply a patch directly against a stuck story's
worktree: origin-gated propose/apply routes distinguishing chat from UI
callers, unified-diff parsing with size/path/whole-file-replacement limits,
an in-memory patch-record store with a TTL and an HMAC token bound to the
patch id and diff hash, a plan-locked atomic apply engine restricted to
stuck stories, and every propose/apply journaled and notified with a
correlation id (never diff content). A dashboard UI renders the stored
diff and requests apply with a UI-origin header, and an end-to-end test
suite covers the full propose/review/apply path (#750, #752, #753,
#756-#761, #766, #768-#770, #772, #773).
Overlord parked-story autonomy
- The overlord can now rule on parked stories under a documented decision
matrix and autonomy-mode ladder, informed by a live git-state probe and a
fail-closed SPLIT payload parser. It executes its own rulings directly -
split_storycreates child stories in the manifest,mark_donecorrects
the story record from live evidence,patch_acceptancerewrites a
diagnosed-broken fixture through validation - and adjudicates high-risk
merges itself in full-autonomy mode, with every executed action recorded
in the decisions log alongside its prior state (#736-#738, #740,
#742-#745, #747).
Registry-authoritative provider/model routing
- An interactive picker (
scripts/choose_providers.py) lets an operator
choose each role's provider from the command line, and the
getting-started smoke now announces and runs on the actually-resolved
dispatch provider instead of refusing everything butclaude(#795-#800). resolve_roleis now the single source of truth for dispatch and
escalation backend resolution: registry roles outrank
PIPELINE_BACKEND_<ROLE>, which becomes an empty-state fallback rather
than an override, preflight reports the registry-aware resolution, and
the launchd templates stopped shipping routing env vars now that the
registry is authoritative (#801-#807).
Dashboard & Comms chat
- The Comms chat panel renders markdown (bold, lists, code) while keeping
the raw transcript export (#731, #734, #735), and dashboard plan lists
can be filtered to the active repository with an all-repos toggle,
backed byrepo_rooton plan summaries (#732, #733). A plan-ingest panel
was added to Comms so a plan can be ingested from the dashboard UI
without a chat-origin route, sinceingest_planis unreachable from
chat by design (#782-#784, #787, #788).
One-line install & public-readiness
scripts/remote-install.sh(curl -fsSL ... | bash) clones or updates a
fixed local checkout and runsinstall.sh; README/CLAUDE.md gained the
community-health files and fixes needed for public visibility; and the
launchd plist/template files and generator were renamed from
com.claude.pipeline.*tocom.fagan.pipeline.*end to end, including
runtime label references (#779-#781, #785, #786).
Fixed
Merge-park & CI-evidence correctness
- A story parked by the merge gate is no longer offered to triage as a
candidate, an unreadable or in-flight CI status is never presented to the
overlord as "no PR checks," a parked high-risk merge hold is
re-adjudicated when its recorded evidence changes, CI evidence gathering
now probes the story's real branch instead of a stale one, and high-risk
merge adjudication records name the story instead of leaving it implicit
(#751, #754, #755, #762-#765, #767, #771).
Scheduler reconcile resilience
- The scheduler process's per-call model budget is now clamped inside the
reconcile join deadline, and the abandon-restart escape hatch is driven
by whether the abandoned worker is actually still alive rather than a
resettable streak counter (#739, #741, #746).
Chat streaming
- Fixed a duplicate reply bubble on the server's reply+result frame pair,
stopped dropping the user's message and prior turns from the prompt
across tool round-trips, and widened stall detection to catch
attribute-style[TOOL_CALL name=...]openers (#774, #777, #778).
Getting-started smoke hardening
- The smoke now drives through the real
ingest_planpath against a
scratch repo with a real origin and a success bar scoped to
tests_passed, rejects a malformed acceptance entry at ingest instead of
crashing, resolves its announced dispatch backend throughresolve_role,
and its subprocess-spawning tests no longer leak the developer's real
.pipeline.envinto the child process (#791-#794, #808, #809).
Local dispatch reliability
- An in-flight local-backend story is no longer interrupted on local memory
pressure (#790).
Test infrastructure
v0.2.0 - Streaming chat, per-backend usage reporting, release tooling
What's new in 0.2.0
Added
Streaming chat
- Streaming chat over SSE:
POST /api/chat/streambacked by astream_turn
event generator, with the dashboard consuming the stream for incremental
tool activity (#685, #686, #689, #695, #707).
Per-backend usage reporting
- Per-backend usage reporting:
collect_backend_statussurfaces
resource_statusper configured role, served by the dashboard usage
endpoint and rendered as one row per backend in the usage banner
(#688, #693, #694).
Plan-completion notifications
- Plan-completion notifications: plan completion is detected exactly once and
emitted as aplan_completednotification, spooled to a per-plan outbox and
delivered over SMTP with credential handling and redaction; the scheduler
tick drains the outbox (#710, #713, #714, #715, #716, #717, #718).
Canonical agent.log grammar
- Canonical agent.log line grammar: a single
agent_log_formatmodule defines
the grammar,local_agentdelegates to it, and a Claude stream-json
translator feeds ClaudeCliDriver dispatch while raw NDJSON is kept in a
sidecar (#687, #690, #691, #692, #699).
Process
- Started an ADR practice:
docs/adr/with an index, a template and the first
four decision records (#682). - Introduced this CHANGELOG (#681).
Fixed
Plan-lock starvation
- Merge adjudication moved to the start of the tick (#704), and the plan lock
is now released arounddispatch_storyandreview_story, guarded by a
dispatch lease so a released lock cannot double-dispatch (#697, #698, #709,
#712); per-plan per-tick dispatch is capped (#708). - The
.agent_donemarker is claimed before its event is published and is
written as soon asfinish_if_greendecides the run is finished (#703,
#705). reconcile_fngained the same bounded join watchdogscan_fnalready has
(#700).- The daemon exits for a launchd restart after repeated abandoned watchdog
workers, since a leaked plan lock is only released by process death (#706).
Watchdog
- The stale-activity watchdog floors the activity age at the current
dispatch's elapsed time, so a redispatch into a reused worktree is not
killed at elapsed 0s (#711), and records the last agent.log line and the
branch commit count when it kills a dispatch (#702).
Done-bar
- The done-bar no longer narrows to a story's own new test file (cf48767),
guarded bytests/unit/test_done_bar_not_narrowed.py.
v0.1.0 — first public release
v0.1.0 - first public release
Spend tokens on judgment, not typing.
An autonomous SDLC pipeline that splits software engineering along the line
where model cost actually differs: a frontier model decomposes the work, plans
it, reviews the diff and adjudicates anything risky, while a local model writes
the implementation at no marginal cost. What makes the cheap half trustworthy
is inspection - the same finding Michael Fagan published at IBM in 1976.
In this release:
- MCP server, web dashboard and scheduler daemon
- Multi-provider dispatch (claude, ollama, lmstudio, mlx, litellm) with
per-role provider/model routing - TDD enforced before implementation; independent review gate;
acceptance-oracle grading - Risk-tiered overlord that stops for a human on anything irreversible
- Merge gate that re-runs the suite against the rebased branch
- CI green on Linux (3.12/3.13/3.14) and macOS
This is a single-maintainer research project, not a maintained product with an
SLA. Its failure modes are real and documented - see the README's
"Reliability & limitations" section before pointing it at anything you care
about.