Skip to content

v2026.10.26

Choose a tag to compare

@github-actions github-actions released this 28 Oct 03:33
· 345 commits to main since this release
3084e01

Update now: run cleo self-update.

Highlights

  • cleo done --plan is ready exactly when cleo complete would accept. The plan now reports a gate-not-derivable blocker for a required gate it cannot prove and a dependency-unresolved blocker for each open dependency, and stops refusing with no-change-set once every required gate stands. A recorded gate that no longer holds is judged by complete's own checks, and cleo show warns W_GATE_STALE for it (T14036, T14037).
  • One evidence-tree resolver. Typed gates and change-set binding both resolve their checkout through resolveEvidenceTree, so they never split across two trees; the invocation's own worktree of the declared repository wins, and cleo verify reports the chosen evidenceRoot. cleo done --plan also accepts a clean checkout detached at the task branch tip (T14058, T14059).
  • More test reports count as evidence. test-run: reads Playwright --reporter=json reports, and the test-run: atoms of one write cover a change together (unit plus e2e). Typed minCount gates count node --test --test-reporter=tap runs, and a refused report is named with its first failing field (T14031, T14051, T14060).
  • Docs-only tasks are classified correctly. A task with no declared files is documentation when its PR or commit changes only documents, or its criteria name only documents; any code path keeps it code. cleo done --plan and cleo complete agree, and the refusal names the fix (cleo update <id> --files <doc paths> or --add-labels docs) (#2473; T14048, T14065).
  • Admission waits explain their holders. Wait reports, refusals and cleo doctor tool-locks show each holder's liveness and why it still counts; a dead holder no longer keeps its charge through a reused process-group id, while a dead runner's live child keeps it. A node script that hosts a compiler or test runner is charged its build plan, then its measured peak, and cleo run prints the charge with its derivation (T14066, T13046, T14050).
  • Affected scope ignores nested checkouts. Files inside a nested worktree or repository no longer make a change workspace-wide, and ! exclusions in pnpm-workspace.yaml and package.json#workspaces are applied (T14052, T14047).
  • Node 26 store migration fixed. On Node 26 (SQLite 3.54) the legacy-store migration no longer aborts on DEFAULT CURRENT_TIMESTAMP, which left cleo.db empty and failed writes with E_EXODUS_ABORT_WRITE_UNSAFE; SQL function names are compared case-insensitively (T14068, T14067).
  • Kills are reported as kills, not failing tests. An OOM or signal kill on tool:, affected-tests and cleo done runs is E_EVIDENCE_TOOL_KILLED with the memory ceiling and heap advice. Kill markers are found anywhere in the output (including jest worker crashes and, on Linux, a masked OOM in the run's systemd scope), and waiters on a killed key report the kill instead of rerunning into it (T13011, T13012, T13013, T13014).
  • Runner-cancelled CI is not blamed on the PR. ci:<pr> treats a job that ended only in GitHub's cancellation as cancelled, lets a later green main run stand in for a merge-commit job that only crashed a vitest worker with no failed test, judges a run with incomplete app/workflow identity as pending, and leads its refusal with the failing check and the next step (T14049, T13017, T14042, T14074).
  • Spawn options. cleo orchestrate spawn-execute --base <ref> branches from a ref and refuses on a bad base; cleo orchestrate spawn --include-deps starts the task branch from a merge of its dependencies' branches; spawn auto-complete honours CLEO_NO_AUTO_WORKTREE_COMPLETE (T14046, T14057, T14045).
  • CI and refactors. CI runs Type Check and the Linux unit shards on Node 26 beside the 24.16.0 floor, fails when committed packages/contracts/schemas differ from the generated output, and the packed-install smoke checks resolved dependencies against the lockfile (T14055, T14064, T14062). Core creates, removes, prunes and unlocks agent worktrees through the @cleocode/worktree facade, with branch integration in its own module and regression tests pinning the spawn path (T10858-T10864, T10866-T10868, T10870-T10877).

Added

  • orchestrate spawn --include-deps starts the task branch from a merge of its dependencies' branches (provenance: T14045)

Changed

  • Branch integration (merge, fetch, landed-detection, the merge decision) moves out of the branch-lock lifecycle module (provenance: T10862, T10863, T10864)
  • CI runs Type Check and the Linux unit shards on Node 26 beside the 24.16.0 floor (provenance: T14055)
  • CI fails when committed packages/contracts/schemas differ from the generated output (provenance: T14064)
  • Core prune and force-unlock call the @cleocode/worktree facade; the forensic bypass policy is written down (provenance: T10867, T10868)
  • Core creates and removes agent worktrees through the @cleocode/worktree facade (provenance: T10858, T10859, T10860, T10861)
  • Remove core's unused copy of detectPartialWorktree; the @cleocode/worktree facade owns partial-worktree detection (provenance: T10870)
  • The packed-install smoke compares resolved contracts/core dependencies with the lockfile and parses schema fixtures through the installed contracts (provenance: T14062)
  • Branch-lock no longer re-exports the facade's getGitRoot; worktree lifecycle ownership is documented (provenance: T10875, T10876, T10877)
  • Regression tests pin the spawn path to the @cleocode/worktree facade and the canonical XDG worktree path (provenance: T10872, T10873, T10874)
  • Worktree completion reads the task's worktree through one typed lifecycle state (provenance: T10871)
  • Core's worktree list reads the registry through a light @cleocode/worktree/worktree-locate.js subpath (provenance: T10866)

Fixed

  • Affected-package scope ignores files inside nested worktrees and repos, and applies workspace ! exclusions (provenance: T14052, T14047)
  • ci: evidence treats a runner-cancelled job as cancelled, judges a run with incomplete app/workflow identity as pending, and leads its refusal with the decisive reason (provenance: T14049, T13017, T14042)
  • ci: evidence stands a later green main run in for a merge-commit job that only crashed a vitest worker, with no failed test (provenance: T14074)
  • The post-merge testsPassed refusal and cleo doctor name the evidence.ciSatisfies block a project with GitHub workflows should add (provenance: T13096)
  • cleo complete waiting on merged CI says so first, with the re-run step, before the CI detail (provenance: T14042)
  • cleo done --plan lists each changed path once for a merge commit (provenance: T14040)
  • cleo done --plan accepts a clean checkout detached at the task branch tip (checkout-required false positive) (provenance: T14059)
  • cleo done --plan is ready exactly when cleo complete would accept, and show flags recorded gates that no longer stand (provenance: T14036, T14037)
  • cleo done accepts --shared-evidence, the remedy its shared-atom warning names (provenance: T14072)
  • Typed gates and change-set binding resolve the evidence tree through one resolver; the invocation's worktree of the declared repo wins (provenance: T14058)
  • --field on a declared optional field the record omits prints [] or null and succeeds (provenance: T14043)
  • A files: path the cited PR deleted is refused by name instead of as an unfetched merge (provenance: T14030)
  • A value beginning with -- passed to a string or positional flag is no longer parsed as an unknown flag (provenance: T14044)
  • cleo run no longer charges a node script that hosts a compiler or test runner as a light 1 GiB run; it is charged its plan, then its measured peak, and the charge is printed with its derivation (provenance: T14050)
  • tool: runs are judged against the task's implemented commits like test-run reports, and a rebased copy of a commit counts (provenance: T13003)
  • an evidence run's resource kill is detected anywhere in its output, from jest's worker-crash messages, and on Linux from an OOM kill in its systemd scope that pnpm reports as exit 1 (provenance: T13012, T13011)
  • evidence tool runs queued on a key whose run was just killed for resources report that kill instead of rerunning into it at the same limits (provenance: T13014)
  • an OOM or signal kill on the affected-tests and cleo done paths is reported as E_EVIDENCE_TOOL_KILLED with the memory ceiling and accurate heap advice, not as failing tests (provenance: T13013)
  • admission wait reports say why each holder still counts; dead holders stop holding the budget through reused group ids, and a dead runner's live child keeps its charge (provenance: T14066, T13046)
  • Typed test gates count node:test TAP runs and name why a found report was refused (provenance: T14051, T14060)
  • On Node 26, opening a store with legacy databases no longer aborts the exodus migration on CURRENT_TIMESTAMP (provenance: T14068, T14067)
  • test-run evidence reads Playwright JSON reports, and the reports of one write cover a change together (provenance: T14031)
  • cleo run names each project setting its heavy-run overlay overrides (vitest maxWorkers, pnpm workspace-concurrency) on stderr and in the run envelope (provenance: T14038)
  • Provisioned-worktree check compares realpaths, so a row recorded through a symlink still counts (provenance: T14054)
  • verify --run-typed refuses a write whose typed gate rewrote the test-run report it cites (provenance: T14056)
  • satisfies alias drift compares parsed atom ids exactly, so #AC1 no longer matches a prior #AC10 binding (provenance: T14029)
  • A tool command with a shell operator is a config error (E_EVIDENCE_INVALID) naming the operator and a package script (provenance: T14039)
  • an interrupted command that ran a tool lets pending best-effort memory drains finish before it dies by the signal (provenance: T13018)
  • orchestrate spawn-execute takes --base and refuses on a bad base; its auto-complete honours CLEO_NO_AUTO_WORKTREE_COMPLETE (provenance: T14046, T14057)
  • the brain writer worker finishes its scheduled embeddings before it is terminated, so stopping it never aborts the host process (provenance: T14069)