🎉 Features
- Replace software-delivery with implement-tasks (#325)
- BREAKING: remove software-delivery; use implement-tasks without gate inputs.
- Parent and child sessions (#327)
🐛 Bug Fixes
- Preserve Loop template manifests across hydration (#317)
- Preserve ACP stream disconnect recovery (#319)
- Discover Cursor model catalog before sessions (#320)
- Keep managed skill loading on native seam (#323)
- Loop run bugs (#324)
- Enforce bundled agent and Loop ownership (#326)
🧪 Testing
- Guard ACP initialize protocol version (#318)
Release Notes
Breaking Changes
implement-tasks replaces the software-delivery Loop
The bundled dev-cycle Loop now does one job clearly: implement authored task files in dependency order. software-delivery is gone and implement-tasks takes its place, with a five-node graph — slug_input → load_tasks → implement → execute_task → collect — and only three inputs. The old second control layer for review, command verification, and human approval is removed from the bundled Loop; task-level validation, self-review, tracking updates, and optional per-task commits stay inside the implementation agent's own prompt. (#325)
- Inputs are now
slug,implementer, andauto_commit. Thereview,verify, andapprovenodes and their edges are deleted, along with the verification contract, stale hash fields, and target-branch handling. - The separate bundled
review-and-fixLoop is unchanged, and custom Loops can still declare their own command gates —verify_commandremains part of the generic Loop DSL. - The catalog, Loop overview, configuration examples, migration guide, web routes, and the official Compozy skill all name
implement-tasks.
Migration notes: this is a hard cut with no alias. Any config, CLI or API call, automation binding, or documentation link that says software-delivery must say implement-tasks, and the target_branch and verify_command inputs must be dropped from [loops.inputs.*].
# before
[loops.inputs.software-delivery]
target_branch = "main"
verify_command = "make gate"
auto_commit = false
# after
[loops.inputs.implement-tasks]
auto_commit = false
Features
Cursor models come from your account
Cursor used to look curated in Compozy but was not truthful to the account that was signed in: a small hand-written list stood in for the real catalog and, worse, acted as an allowlist that rejected valid model ids before Cursor ever saw them. Compozy now reads the account catalog from cursor-agent models before a session exists, and exact provider model ids are forwarded unchanged. (#320)
- The first catalog read bootstraps Cursor discovery once and persists the outcome; later reads serve the cache, and explicit refresh is the refresh boundary. In the QA account this surfaced 193 real models, including
composer-2.5. - Only
id - display namerows are parsed. Headings, tips, duplicates, and empty output can never become invented models. - Curated data is metadata again, not membership policy. Sessions and Loops accept ids like
cursor/composer-2.5, and an unknown provider still fails with a structuredunknown_providererror. providers.<id>.models.discoveryapplies live — no daemon restart. A provider outage records the failure and keeps the rows you already have; disabling discovery clears them and recordsdisabled.- In the web runtime selector, "Use an exact custom model ID…" now opens a dedicated field: empty input cannot be committed, typing turns the action into
Use "<id>", Enter and click both commit, and closing returns to normal catalog search. - Cursor keeps the operator
HOMEitsnative_clilogin contract expects.
Migration notes: the curated Cursor allowlist and its session preflight are deleted with no compatibility bridge. If a provider rejects an id, that provider's error is now the authority.
Fixes
A crashed agent no longer looks like a finished one
When an agent process disconnected mid-answer, the stream simply ended — and everything downstream read that silence as success. A CLI consumer reached end of file and exited zero, compozy__session_prompt returned a result, and the only evidence left behind was stderr with no exit code. Streams are now fail-closed: success requires an explicit completion event, and disconnect, terminal error, and process exit stay three distinct outcomes. (#315, #319)
- Chunks already received stay persisted and visible. Compozy never synthesizes a completion for them.
- A stream that ends after partial output without a completion event fails the CLI with a clear non-zero exit, and terminal error frames are forwarded before the error is returned so machine-readable diagnostics survive.
compozy__session_promptclassifies a subprocess exit astool_backend_failedwithbackend_deadinstead of reporting success; the partial events remain readable in the session transcript.- Crash evidence now carries the subprocess exit code and, where the operating system exposes it, the terminating signal.
- Fatal cleanup gives the process a bounded grace period to exit on its own before being stopped, so the real exit result is no longer lost to a race with forced teardown.
- Compozy does not replay a prompt automatically, because a prompt may already have caused external side effects. Sending the next prompt restarts the agent process and continues the same session and transcript.
Migration notes: crash bundles move to compozy.session_crash_bundle.v2 with structured exit_code and signal, with no v1 branch. Any consumer that treated a closed stream as success will now correctly see a failure unless a completion event was sent.
Dry-run proves the run you are about to submit
A Loop could validate, dry-run cleanly, and then fail at submission with executed definition template manifest changed. The compiler folded default values into the definition it stored, but compiled templates from the definition before those defaults — so a persisted run carried more template keys than its own snapshot, and hydration rightly refused it. Compilation now uses one canonical definition throughout, and dry-run exercises the exact snapshot boundary a real submission uses. (#313, #317)
- Defaults are folded once at the start of compilation and used for linting, contracts, nodes, watch events, graph metadata, and child Loops alike — so omitted child
modevalues no longer appear out of nowhere during hydration. - A snapshot must load through the production loader before its bytes or digest are returned; one that cannot round-trip can no longer reach storage.
compozy loop run --dry-runandcompozy__loop_runwithdry: truerun that same check, so a preview can no longer approve a definition that submission would reject.- A mismatch now names the manifest kind, the exact key, and its source instead of reporting a generic failure.
Migration notes: no storage, API, CLI, or configuration contract changed. Integrity checks were not relaxed — inconsistent definitions are still rejected, just earlier and with a readable reason.
Loop runs you can debug from the run page
A Loop run that failed used to be a dead end: every attempt died with "The agent output did not satisfy the action output schema", the node was quarantined, "Open quarantine entry" opened an empty sheet, "Open session" returned 404, the cell task sat in "Queued · attempt 1 of 10" forever, and Usage confidently reported 0 / ~$0.00. The agent had actually answered correctly every time — the daemon joined streamed text fragments with a newline, which landed inside a JSON string and corrupted a valid reply. That joiner is fixed, and so is every surface that made the failure impossible to read. (#324)
- The agent now sees the authored
output_schemain its prompt instead of prose that never said "JSON", extraction validates every candidate object newest-first (a quotedpackage.jsonno longer shadows the real answer), and the failure cause carries the underlying detail instead of one generic sentence. - Quarantine is routed to the node that actually failed. Parked consumers collapse into a single row — "execute task is quarantined — collect, review, verify and approve are parked behind it until it is requeued" — with one button that opens the producer's entry, and
node_attention_flaggedis finally emitted when a run parks. - Loop cells no longer stall in
readyafter a failed run: quarantine parks them as needs-attention and requeueing clears the park. The misleadingof 10attempt ceiling is gone, since the Loop owns the retry budget. - Daemon-claimed runs stop writing placeholder session ids, the real ACP session is bound to the lease under a claim token, and run detail exposes
generations[].outputs[].session_id— so "Open session" works from the hero and from every node row that has one. - The task list nests Loop cells under their coordinator with an escalation-first summary ("9 subtasks · 1 needs attention · 2 running") and readable identities like
g2.execute_taskinstead ofloop.lo. - When a provider reports no tokens, Usage now reads "not reported" and "—" instead of a confident zero; the cost estimate returns only when tokens exist.
Migration notes: adds the attention_producer_node_id column to loop_node_controls through migration 00055; run-detail payloads gain node_controls[].attention_producer_node_id and generations[].outputs[].session_id.
Skills load through the native seam inside managed sessions
Managed sessions load installed skills through the native compozy__skill_view tool only — including skills that are not listed in the prompt catalog. The earlier attempt to give managed agents a private CLI socket is removed rather than kept as a fallback: provider code runs as the daemon user, so environment values, headers, process ancestry, and file modes cannot tell those requests apart from an operator's. (#314, #323)
- If session policy denies the native tool, the agent reports the skill unavailable instead of shelling out or reading skill files directly.
- Every
compozy skillverb detects managed-session markers before doing any client, socket, registry, or filesystem work and points the caller atcompozy__skill_list,compozy__skill_search, andcompozy__skill_view. This is documented as a support guard, not an authorization boundary — same-user code can still clear those markers. - Hosted-MCP bind windows now start after ACP initialization and immediately before session negotiation. A cold provider launch that takes longer than the bind window no longer expires the tool seam before the agent can use it; a bind attempted before activation still fails closed.
Migration notes: the managed CLI transport is deleted — the socket, COMPOZY_AGENT_TRANSPORT_SOCKET, the managed identity headers, and the managed skill API scope. Operator CLI behavior from a normal shell is unchanged.
One owner per Loop run, and cancellation that sticks
Loop action runs now have exactly one daemon-owned worker, cancellation survives a restart, and a session that needs Compozy tools fails before the provider starts instead of running without them. Fresh Compozy homes also start with the bundled dev-cycle extension already enabled, while a home that has been booted before keeps whatever you chose. (#321, #322, #326)
- Coordinators and ordinary task-role sessions can no longer activate or bootstrap a run that the dedicated
loop-actionexecutor already owns. - When the effective agent or lineage policy requires concrete tools and hosted MCP cannot provide them, session startup fails closed with
ErrHostedMCPUnavailablebefore the provider process is launched. - Loop cancellation is durable: delivery state is persisted, delivery is idempotent, the run advances to draining once acknowledged, and anything still pending is retried from daemon boot and from scheduler sweeps — no restart required to converge.
- Resuming a stopped session discards the stopped ledger projection first and restores it if provider startup or the clear rolls back, so forensic projections stop conflicting and the full history is rematerialized on the next stop.
- Enablement of a bundled extension is a fresh-home default, not an override: generic local and marketplace installs stay disabled by default, and stored state survives restart and update.
Contribution data is temporarily unavailable.
23 files published by the GitHub release workflow.
Browse downloads
- checksums.txt2.0 KB · 5 downloads
- checksums.txt.sigstore.json9.6 KB · 4 downloads
- compozy-0.3.0-beta.6.tar.gz184 MB · 2 downloads
- compozy-0.3.0-beta.6.tar.gz.sbom.json676 KB · 2 downloads
- compozy-0.3.0.beta.6-1.aarch64.rpm39 MB · 2 downloads
- compozy-0.3.0.beta.6-1.aarch64.rpm.sbom.json2.7 KB · 2 downloads
- compozy-0.3.0.beta.6-1.x86_64.rpm42 MB · 2 downloads
- compozy-0.3.0.beta.6-1.x86_64.rpm.sbom.json2.7 KB · 2 downloads
- compozy_0.3.0.beta.6_amd64.deb42 MB · 2 downloads
- compozy_0.3.0.beta.6_amd64.deb.sbom.json2.6 KB · 2 downloads
- compozy_0.3.0.beta.6_arm64.deb39 MB · 2 downloads
- compozy_0.3.0.beta.6_arm64.deb.sbom.json2.6 KB · 2 downloads
- compozy_darwin_arm64.tar.gz41 MB · 5 downloads
- compozy_darwin_arm64.tar.gz.sbom.json277 KB · 2 downloads
- compozy_darwin_x86_64.tar.gz43 MB · 2 downloads
- compozy_darwin_x86_64.tar.gz.sbom.json277 KB · 2 downloads
- compozy_linux_arm64.tar.gz39 MB · 4 downloads
- compozy_linux_arm64.tar.gz.sbom.json275 KB · 2 downloads
- compozy_linux_x86_64.tar.gz42 MB · 11 downloads
- compozy_linux_x86_64.tar.gz.sbom.json275 KB · 2 downloads
- compozy_windows_x86_64.zip43 MB · 2 downloads
- compozy_windows_x86_64.zip.sbom.json283 KB · 2 downloads
- install.sh7.9 KB · 2 downloads
- Source code (tar.gz)
- Source code (zip)