Gitmoot v0.6.0
A large orchestration release. The Orchestra delegation engine gains an
engine-level verify rule, structured upstream-dependency context, a mid-run
human ask gate, and actionable preflight errors. The daemon gains an
off-by-default outbound event stream, a host-global memory-aware admission
budget, and discoverable same-repo parallel jobs. Runtimes now self-heal
dead Claude sessions and fail closed on implement-without-write. Plus
event-stream and home-resolution fixes found by a live end-to-end test.
What's new since v0.5.2
Orchestration engine — the delegations DAG
- feat(workflow): engine-level
verifysynthesis_rule + bounded verify→replan (#439) — a newverifysynthesis rule lets the engine itself derive a pass/fail verdict from a verification leg's children and, on failure, enqueue a bounded verify→replan corrective continuation instead of dead-ending. Bounded by a new[orchestrate].max_verify_replan_attemptscap (default 2); on exhaustion it routes to the graceful finalize continuation. The verify→replan loop is now enforced by the engine, not left to the coordinator. - feat(workflow): structured upstream-dependency context manifest (#438) —
deps[]dataflow now carries a structured manifest of upstream sibling results (decision, summary preview, changes count, PR link, artifact path, derived-from) into a child's prompt, instead of only inlined text — so a child can reference upstream outputs precisely. The manifest write is atomic (no torn reads under the parallel read-only fan-out). - feat(workflow): mid-run non-failure "ask" decision gate (#445) — a healthy
job can return
human_questions[]to pause the tree atawaiting_humanwithout failing a leg; a human answers on the PR with/gitmoot resume <job> answer "<id>: ..."and the answer is injected into the coordinator continuation. It reuses theescalate_humanpause + TTL machinery and is budget-neutral. (Theanswerresume verb sits alongside the existingretry/continue/abort.) - feat(workflow): actionable delegation preflight errors + corrective continuation (#451) —
a fan-out that names a runtime instead of a registered agent no longer
terminal-blocks the coordinator; it produces an actionable preflight error and a
corrective continuation so the coordinator can fix and proceed. A
delegation preflight failures: Nline is surfaced indaemon status.
Daemon
- feat(daemon): same-repo parallel jobs made discoverable (#444) — requesting
multiple workers now actually delivers parallelism.
--workers > 1with an unset scheduler auto-selects--scheduler pool(a behavior change only when you asked for multiple workers; the single-worker default is unchanged, and explicit--scheduler barrieralways forces the old per-tick behavior). A new--parallel Nconvenience flag sets workers + pool together.daemon statusreportsscheduler: <barrier|pool>, workers: <n>, and a preflight warning logs the exact relaunch command when ≥2 parallelizable jobs (distinct runtime sessions) meet a serializing config. A new "Run jobs in parallel on a repo" guide covers the two serialization layers (checkout lock +runtime:<runtime>:<ref>session lock). - feat(daemon): host-global, memory-aware admission budget (off by default) (#365) —
an opt-in
[admission]budget caps total in-flight agent sessions and the summed per-runtime RAM estimate across all repos in the daemon process, on top of--workers/scheduler and the per-repo locks. A job is admitted only if it fits both caps; one that doesn't is left queued and retried, never failed. Both caps default to 0 (disabled) — scheduling is byte-identical to no[admission]section.
Outbound events
- feat(events): off-by-default outbound event stream + EventSink seam (#446) —
a stable, versioned JSON event contract (
job.finished/job.failed/job.blocked/job.needs_attention) emitted over a webhook when[events].webhook_urlis set. Off by default, best-effort (a slow or dead consumer never blocks or fails a job), with secret + absolute-path redaction. Closes the "local-only, no remote control plane" gap — a Telegram/herdr bridge, dashboard, or future mobile monitor can subscribe without polling. (The ask-gate pause above rides this as ajob.needs_attentionevent.)
Runtimes & sessions
- feat(runtime): self-heal dead Claude
--resumesessions (#443) — a background agent pinned to a Claude conversation UUID that died on a runtime restart used to fail instantly, before any work, with an opaquedelivery failederror that read like broken auth. It now self-heals with a single bounded retry on a fresh session instead of dead-ending. - feat(cli,runtime): fail closed on implement without a write policy (#452) —
an agent (or ephemeral worker) carrying the
implementcapability while its autonomy policy grants no headless write (auto/empty orread-only) is now refused early with actionable guidance instead of running a whole job and silently writing nothing. The check fires atagent start,agent subscribe, implement-job dispatch, and ephemeral delegation specs. The docs now carry the full policy →--permission-modemapping.
Fixes
- fix(events): the event stream now actually fires (#458) — the daemon
double-resolved the
[events]config home (reading a phantom.gitmoot/.gitmoot/config.toml), so the stream silently never emitted even when configured. Now resolved robustly for both daemon home shapes, side-effect-free. Found by a live end-to-end test (the unit tests had mocked the sink and missed it). - fix(daemon): no more phantom
.gitmoot/.gitmoot(#459) — the registered-repo supervisor reused the resolved home for two raw---homehelpers (resolveEscalationTTLand the supervisor worker's policy read), whose initialization created a doubled home directory. The home convention is normalized andresolveEscalationTTLis now side-effect-free (reads config, never initializes).
Upgrade notes
Two opt-in behavior changes, and only when you've asked for them:
--workers > 1now auto-selects--scheduler pool(#444). If you run the daemon with multiple workers and rely onbarriersemantics, add an explicit--scheduler barrierto keep the old behavior.implement+ a non-write policy is now refused (#452) with actionable guidance. Use--policy danger-full-accessfor a full headless implement (file writes plusgo/git/ghvia Bash) or--policy workspace-writefor edits-only (note:workspace-writemaps to ClaudeacceptEdits, which does not unblock Bash).read-only/ask/reviewagents are unaffected.
Install / upgrade
- Existing install:
gitmoot update - Fresh install:
curl -fsSL https://gitmoot.io/install.sh | sh