Skip to content

Releases: kryptobaseddev/cleo

v2026.4.154

28 Apr 20:52

Choose a tag to compare

Highlights

Comprehensive overnight orchestration campaign with 4 dispatch waves + 10-teammate domain audit + V1-V5 release validation. Net: 60+ commits across architecture cleanup, governance pumps, audit-driven fixes, and pre-release polish.

Key fixes

  • fix(memory): wire cleo memory sweep --rollback dispatch routing (T1496/P0-1)
  • fix(lifecycle): defensive guard for undefined gateName in passGate/failGate + 7 pipeline.integration tests fixed (T1497/P0-4)
  • feat(verification): per-session CLEO_OWNER_OVERRIDE cap + --shared-evidence flag for batch closes + ADR-059 (T1501+T1502/P0-5+P0-6)
  • feat(verification): raise default override cap 3→10 + worktree-context exemption (T1504)
  • feat(orchestrate): worktree leak auto-cleanup + cleo orchestrate prune CLI (T1462)
  • fix(paths): getProjectRoot rejects .cleo candidates lacking sibling .git (T1463)
  • feat(tasks): epic closure requires direct evidence or all children verified-done (T1404)
  • refactor(dispatch): 6 remaining fat handlers thinned to ≤5 LOC per ADR-058 (T1492 — T-THIN-WRAPPER feature-complete)
  • fix(reconciliation): sync:${providerId} colon broke validateLabels regex — silently swallowed all reconciliation actions (T1530 silent data-corruption fix)
  • fix(dispatch): migrate docs.ts to TypedDomainHandler per ADR-058 (T1529)
  • chore(orphans): scripted re-parent of 39 orphaned tasks (T1503)
  • chore(audit): 10-teammate domain audit + master synthesis (T1520)

Pre-release polish (T1562)

  • fix(readme): correct invalid scope example
  • chore(core): add runtime guard to ./internal barrel
  • fix(check): align config.schema.json with current config structure

Test suite

  • Pre-existing failures: 12 → 0
  • Test counts: 11507 → 11566 passing (708 test files)

Tooling

  • ADR-058 OpsFromCore adoption: 12/18 dispatch domains compliant (8 follow-up tasks filed in T1555)
  • Force-bypass governance pumps now LIVE (cap, shared-evidence, epic-closure-evidence)

v2026.4.153

28 Apr 18:21

Choose a tag to compare

Resolves the resource thrash and apparent memory leak observed when 10+ orchestrator-spawned worker subagents call cleo verify --evidence "tool:<name>" simultaneously across worktrees.

Fixed

  • Apparent memory leak under parallel verify load. validateTool previously accumulated the entire child stdout/stderr stream into JS strings on every 'data' event. A vitest run emitting 50–200 MB of progress output sat resident per spawn, multiplied by N parallel verifies. New TailBuffer in tool-cache.ts caps in-memory capture at 64 KB per stream per spawn. Cached evidence tail unchanged at 512 bytes. (T1534, ADR-061 §3)
  • @cleocode/core package-boundary violation. evidence.ts hardcoded a pnpm/biome/tsc TOOL_COMMANDS table, breaking the contract that core MUST be project-type agnostic. New tool-resolver.ts reads .cleo/project-context.json (testing.command, build.command) with per-primaryType fallbacks for node, python, rust, go, ruby, java, dotnet, bash, elixir, php, deno, bun. (T1534, ADR-061 §1)
  • coreTestRun (validate.tests.run) hardcoded to npx vitest run. Now routes through the same resolver — validate.tests.run works on Python/Rust/Go projects without modification. (T1534)

Added

  • Content-addressed result cache. Cache entries at .cleo/cache/evidence/<key>.json, keyed on (canonical, cmd, args, git HEAD, dirty-tree fingerprint). Sibling verifies against the same state coalesce to one execution. Edits and new commits invalidate automatically; no GC daemon required. (T1534, ADR-061 §2)
  • Cross-process global per-tool concurrency semaphore. Slot directories at ~/.local/share/cleo/locks/tool-<canonical>/ bound the total concurrent runs of a canonical tool across all worktrees and projects on the machine. Defaults: test/build = max(1, cpus/4); lint/typecheck/audit/security-scan = max(2, cpus/2). Override via CLEO_TOOL_CONCURRENCY_<TOOL>=<n> (set 0 to disable). Stale-process recovery via proper-lockfile 10-min stale window. (T1534, ADR-061 §4)
  • Six canonical tool names for tool:<name> evidence: test, build, lint, typecheck, audit, security-scan. Legacy aliases (pnpm-test, npm-test, cargo-test, pytest, vitest, jest, tsc, mypy, pyright, biome, eslint, prettier, ruff, clippy, pnpm-build, cargo-build, go-test, pnpm-audit, cargo-audit, …) continue to resolve and remain re-validatable.
  • ADR-061 — Project-Agnostic Evidence Tools + Cross-Process Result Cache.

Real-world load-test results (24-core / 64 GB box)

  • 10 worktrees, 2-slot semaphore, 5 MB stdout each: max 2 children, 24 MB heap growth, all tails bounded at 512 bytes.
  • 20 worktrees, default 6 slots, 10 MB each (400 MB streamed total): max 6 children, 67 MB heap growth.
  • 10 independent Node PIDs sharing CLEO_HOME: 4 perfect serialised waves of 3 — proves the cross-process bound holds across PIDs, not just in-process.
  • 20 same-repo parallel verifies: 1 spawn, 19 cache hits.

Backwards compatibility

  • EvidenceTool widened from union to string — strict superset of the old union, no caller breaks.
  • TOOL_COMMANDS retained as Object.freeze({}) for any destructure consumers; deprecated, new code MUST call resolveToolCommand.
  • All stored evidence atoms (including pre-T1534 audit trails) remain re-validatable via the alias map.

Tests

112/112 across 5 new/extended suites (resolver + cache + semaphore + evidence + injection-mvi-tiers); 1997/1997 in @cleocode/cleo downstream suite; full workspace build green; pnpm biome ci . clean.

v2026.4.152

28 Apr 01:17

Choose a tag to compare

The T-THIN-WRAPPER campaign + T-SDK-PUBLIC follow-up shipped 46 commits across two epics. Goal: turn @cleocode/cleo into a thin transport over @cleocode/core (the SDK) and @cleocode/contracts (canonical wire-format SSoT).

What shipped

T-THIN-WRAPPER (T1467) — 13 subtasks

  • Lint script L4 wildcard re-export shortcut fixed (T1469)
  • Core index namespace exports for check/session/playbook + sentient/gc/llm (T1470, T1483)
  • 17 type duplicates dedup'd from Core/cleo into contracts (T1471)
  • Canonical CLI tasks layer with alias normalization (T1472)
  • All 9 dispatch domains use OpsFromCore<typeof coreOps> inference (T1437/T1438/T1439/T1440/T1441/T1442/T1443/T1444/T1445)
  • Redundant per-op contract type aliases stripped (T1446 — pipeline.ts -244 LOC, tasks.ts -299 LOC)
  • ADR-058 dispatch-type-inference authored (T1447)
  • biome rule + regression test prevent inline type drift (T1448)
  • nexus.ts CLI decomposed (T1473 — 5366 → 4084 LOC, 9 new core/nexus files)
  • Engine type duplicates removed (T1482)
  • 57 dispatch handlers thinned via wrapCoreResult helper (T1484)
  • 79 more dispatch handlers thinned in tasks/playbook/nexus (T1487 — 61-70% body LOC reduction)
  • Nexus CLI bypass paths routed through dispatch (T1488)
  • Session dispatch param aliases sole-sourced via contracts (T1489)
  • add.ts CLI inference moved to Core inferTaskAddParams (T1490)

T-SDK-PUBLIC (T948) — 5 deliverables

  • @cleocode/core publish surface hardened (files allowlist excludes 13MB src)
  • @cleocode/contracts public type surface README documenting XOps pattern
  • @cleocode/core SDK README with runnable quickstart
  • TypeScript .d.ts declaration cleanliness verified (zero internal leaks)
  • forge-ts @example doctests on 10 public Core fns

Critical bug fixes after validation

  • build.mjs sharedExternals regression (introduced v2026.4.141): added openai/google-genai/anthropic-sdk to externals — fresh npm installs were crashing with "Dynamic require of stream" since v2026.4.148
  • conduit/ops.ts declare const type-only fixed (was crashing CLI at startup)
  • brain sleep-consolidation SQL e.observation_ide.id (matched vec0 schema)
  • TasksAPI.add() facade gained acceptance?: string[]
  • README quickstart corrected (addTask not tasksAddOp)
  • cleo update --note (singular) alias regression test added

Adapter migrations to public SDK (T948 prereqs)

  • MCP adapter (@cleocode/mcp-adapter) migrated from CLI subprocess to direct @cleocode/core + @cleocode/contracts (T1485)
  • cleo-os decoupled from @cleocode/cleo binary dep (T1486)

Quality gates

  • pnpm exec tsc -b: exit 0
  • pnpm biome ci .: exit 0 (1 pre-existing symlink warning)
  • pnpm run build: exit 0
  • pnpm run test: 11507 passing / 5 pre-existing failures (brain-stdp + sqlite-warning-suppress, unrelated to campaign)
  • node scripts/lint-contracts-core-ssot.mjs --exit-on-fail: exit 0
  • Validation matrix: V1 + V2-RERUN + V3 + V4 + V5 + FINAL re-run all GREEN
  • Sandbox: 3/7 ubuntu, 4/7 fedora, 0 new regressions vs v2026.4.151

Codex audit progression

  • Audit #1 (campaign start): NO/NO/PARTIAL on the 3 thin-wrapper questions
  • Audit #4 (post-campaign): PARTIAL/PARTIAL/TRUE — Core SDK is now solidly publishable

v2026.4.151

27 Apr 01:36

Choose a tag to compare

v2026.4.150 release tag pushed but CI Type Check failed on packages/cleo/src/dispatch/engines/lifecycle-engine.ts:207. The lifecycleStatus(epicId, projectRoot?) engine wrapper passed projectRoot?: string directly to getLifecycleStatus() which now requires projectRoot: string (per ADR-057 D1 in T1455). Fix mirrors the pattern used at line 195 (listRcsdEpics): projectRoot ?? process.cwd().

The release commit e950a57ad itself only touched package.json files and CHANGELOG.md; the type error was pre-existing on 5feda5140 (T1455 lifecycle callers fix-up) and slipped past local pnpm run build because tsc -b is the stricter CI gate.

This release re-ships the T1449 epic content under the v2026.4.151 tag with CI green.

Quality gates

  • pnpm exec tsc -b exit 0
  • pnpm biome ci . clean
  • pnpm run build exit 0
  • pnpm run test 11491 passing
  • node scripts/lint-contracts-core-ssot.mjs --exit-on-fail exit 0

v2026.4.150

27 Apr 01:19

Choose a tag to compare

T1449 epic shipped. 9 dispatch domains (admin, check, conduit, nexus, pipeline, playbook, sentient, session, tasks) refactored so every Core function follows the uniform (projectRoot: string, params: <Op>Params): Promise<<Op>Result> signature per ADR-057 D1. Contract aliases (parentId/parent, kind/role/type, note/notes, focus/startTask) removed; CLI flag aliasing moved to the command layer per D2. Drift is now structurally impossible: changing a contract type breaks the Core signature at compile time, and scripts/lint-contracts-core-ssot.mjs enforces L1 (signature uniformity), L2 (no aliases in contracts), L3 (no dispatch normalization), and L4 (Core fns referenced by dispatch are SDK-public) via pre-commit hook and CI workflow.

Per-domain commits

  • T1450 session: af49ffb18 (PROOF — 15 ops normalized) + a40abf979 (internal caller fix-up)
  • T1451 admin: shipped in pre-T1449 batched rollout; 12 Core fns annotated SSoT-EXEMPT:T1451-followup for next pass (token-service, snapshot, adrs sync/validate)
  • T1452 check: 36ad4fc54
  • T1453 conduit: 0f032cba5 (vitest alias resolution)
  • T1454 nexus: ceb30ed47 (with backward-compat positional overloads retained; clean removal in follow-up)
  • T1455 pipeline: ad6b49a9d + 5feda5140 (lifecycle caller fix-up)
  • T1456 playbook: 25b7b6628 (SSoT-EXEMPT for db-handle internals)
  • T1457 sentient: edfa04977 (WIP-recovered, complete)
  • T1458 tasks: 651d4d199 (Part A — Core ops.ts normalization) + 8bc7baa15 (Part B — parentId/kind/type alias removal)
  • T1459 ADR + lint gate: b8b96249a (ADR-057 published) + a901f5c15 (3 residual aliases resolved) + 0361abdf9 (pre-commit + CI workflow wire)

Architectural impact

Core becomes the SDK: external consumers (Studio, future MCP adapters, public SDK) can now import { sessionStart } from '@cleocode/core'; await sessionStart(projectRoot, params); against a uniform, stable surface. CLI becomes a thin transport: command files parse flags, normalize aliases, call Core — no business logic in the CLI layer. The lint gate catches drift at PR time rather than at runtime.

Quality gates

  • pnpm biome ci . — clean (1 pre-existing broken-symlink warning, not introduced this release)
  • pnpm run build — exit 0
  • pnpm run test — 11491 passing, zero new failures vs v2026.4.149 baseline
  • node scripts/lint-contracts-core-ssot.mjs --exit-on-fail — exit 0

Known follow-ups

  • T1451 admin completion: 12 SSoT-EXEMPT:T1451-followup annotations remain; a dedicated pass will finish normalization of token-service, snapshot, and adrs sync/validate Core fns
  • T1454 nexus positional overloads: backward-compat positional signatures retained on Core fns; remove after CLI and tests fully use named-params form
  • T1454 nexus dispatch form: handler uses TypedDomainHandler<NexusOps> (T1424 form) rather than OpsFromCore<typeof coreOps> (ADR-057 D3 form); both are valid per the ADR; migrate in a follow-up for full uniformity

Council verdict (2026-04-25)

5-advisor stress test (Contrarian, First Principles, Expansionist, Outsider, Executor) passed all rigor, evidence, and framing gates. Convergence: Core API uniformity is load-bearing infrastructure; the CI enforcement gate must come after per-domain audit, not before. Q1 (aliases policy) resolved as Option B — canonical SSoT in Contracts. Q2 (sequencing) resolved as normalize-first plus parallel execution across all 9 domains.

v2026.4.148

25 Apr 15:13

Choose a tag to compare

The v2026.4.147 push-CI failed on parity.test.ts > registry has the expected operation count because adding 3 new conduit topic ops bumped the total from 322 to 325 but the hardcoded assertion (expect(OPERATIONS.length).toBe(322)) still expected the old number. The Release workflow itself passed (npm publish succeeded for v2026.4.147), but the push-CI was red.

This release replaces the hardcoded count assertion with structural assertions that catch real regressions without manual maintenance:

  1. OPERATIONS.length >= 300 — catches mass-deletion / truncation
  2. queryCount >= 150 — catches gateway corruption
  3. mutateCount >= 100 — catches gateway corruption
  4. queryCount + mutateCount === OPERATIONS.length — no rogue gateway values
  5. count of (gateway !== 'query' && gateway !== 'mutate') === 0

The other tests in parity.test.ts already enforce per-op invariants (valid gateway, non-empty domain/operation, required-param consistency, no duplicates). The hardcoded count was carrying 30+ comment lines tracking historical bumps (Phase 1 / W7a / T535 / T549 / T554 / T624 / T646 / T647 / T781 / T797 / T811 / T798 / T820 / T889 / T935 / T997 / T1006 / T1003 / T1061 / T1013 / T1115 / T1116 / T1117 / T1137 / T1076 / T1262 / T1261 / T1147 / T1386 / T1411). It was friction without value.

Quality gates

  • pnpm exec tsc -b — 0 errors
  • pnpm biome ci . — 1942 files clean
  • pnpm run build — green
  • pnpm --filter @cleocode/cleo test -- --run parity — 1963 pass

v2026.4.147

25 Apr 14:51

Choose a tag to compare

User smoke-tested v2026.4.146 in production and discovered cleo conduit publish/subscribe/listen returned E_INVALID_OPERATION: Unknown operation: mutate:conduit.publish. The CLI commands were registered (visible in cleo conduit --help) and the dispatch handler implemented the methods at packages/cleo/src/dispatch/domains/conduit.ts:94,184,204, but the OPERATIONS_REGISTRY in packages/cleo/src/dispatch/registry.ts was missing the three corresponding entries. The CQRS validator rejected them as unknown ops before reaching the handler.

This hotfix adds the missing conduit.publish (mutate), conduit.subscribe (mutate), and conduit.listen (query) entries with their canonical param schemas. Verified end-to-end against a live publish→subscribe→listen flow:

$ cleo conduit publish --topic test-fix --payload '{"hello":"world"}'
{"success":true,"data":{"messageId":"278ed11b-...","from":"cleo-prime","topicName":"test-fix","transport":"local","publishedAt":"..."}}

$ cleo conduit listen --topic test-fix --agent cleo-prime --max 5
{"success":true,"data":{"topicName":"test-fix","messages":[{"id":"278ed11b-...","from":"cleo-prime","content":"{\"hello\":\"world\"}","conversationId":"test-fix","timestamp":"..."}],"listenedForMs":11}}

All three round-trip cleanly. The conduit-schema split (T1407-followup commit 7300e3eed) and migration-runner unification from v2026.4.145 are independently verified — only the dispatch routing was missing.

Quality gates (verified before release)

  • pnpm exec tsc -b — 0 errors
  • pnpm biome ci . — 1942 files, 2 pre-existing warnings, 1 info; no errors
  • pnpm run build — green
  • Live conduit topic publish/subscribe/listen flow against .cleo/conduit.db — green

v2026.4.146

25 Apr 08:15

Choose a tag to compare

Lands the registry-driven cleo reconcile release post-release invariants gate. ADR-056 (D5) promoted T1411's scope from a single-purpose archiveReason hook to a generic post-release invariant registry where archiveReason reconciliation is customer #1 — Council Expansionist's sharpest single point. The same mechanism retires the entire class of drift bugs that ADR-054's six migration-manager patches paid for ad-hoc.

Closed in this release

  • T1411 registry-driven cleo reconcile release post-release invariants gate (PROMOTED scope per ADR-056 D5).

What changed

  • packages/core/src/release/invariants/registry.ts (NEW, 209 LOC): RegisteredInvariant type, registerInvariant(spec), getInvariants(), and runInvariants(tag, options) — the registry API. Side-effect import of ./archive-reason-invariant.js from ./index.ts registers the first customer at module load.
  • packages/core/src/release/invariants/archive-reason-invariant.ts (NEW, 399 LOC): the first customer. Parses the tag annotation (git tag <tag> -l --format='%(contents)') plus every commit between the previous tag and the target tag for T\d+ task IDs (subject + body). For each found Txxx:
    • Pending task with verification_json populated and gates passing → stamps status=done, archive_reason=verified, release=<tag> in one transaction.
    • Pending task with verification_json=null → creates T-RECONCILE-FOLLOWUP-<tag>-<idx> child task linked to the unreconciled task ID.
    • Tombstone safety: NEVER writes completed-unverified (only the T1408 backfill migration may produce that value); attempting to do so throws ArchiveReasonTombstoneError.
  • packages/core/src/release/invariants/index.ts (NEW, 46 LOC): barrel export + side-effect registration.
  • packages/core/src/release/invariants/__tests__/archive-reason-invariant.test.ts (NEW, 447 LOC): 7 cases covering all-verified, mixed, no-T-IDs, dry-run, audit-log idempotency, tombstone rejection, and multi-tag delta parsing.
  • packages/cleo/src/cli/commands/reconcile.ts (NEW, 106 LOC): cleo reconcile release --tag <tag> [--dry-run] CLI subcommand. Emits LAFS-envelope output. Exit 0 on clean reconcile, 1 on errors, 2 on unreconciled tasks remaining (operator decides follow-up).
  • packages/cleo/src/cli/commands/__tests__/reconcile.test.ts (NEW, 228 LOC): integration tests against fixture repo with 3 tag scenarios (all-verified, mixed, all-unverified).
  • scripts/hooks/post-tag.sh (NEW, 56 LOC): git post-tag hook that invokes the CLI for every annotated tag push. Idempotent on re-run.
  • packages/core/src/release/index.ts: barrel updated to re-export the invariant registry surface.
  • packages/cleo/src/cli/index.ts: reconcile command registered.
  • CONTRIBUTING.md: post-tag hook installation instructions added alongside the T1410 commit-msg hook.
  • Audit log: every mutation appends one JSONL row to .cleo/audit/reconcile.jsonl as {tag, taskId, action, reason, timestamp}. Reconciliation is fully auditable.

Self-test artifact (pre-release)

The implementing worker dry-ran the reconciler against the previously-shipped v2026.4.145 tag: 20 task IDs found in the tag delta, 13 already-closed (no action), 7 unreconciled (would create follow-up tasks in non-dry-run mode). This is exactly the invariant gate's intended behavior — surfacing the unreconciled cohort instead of letting it silently drift.

Quality gates (verified before release)

  • pnpm exec tsc -b — exit 0 (zero TypeScript errors)
  • pnpm biome ci . — exit 0 (1942 files checked, 2 pre-existing warnings, 1 info; no errors)
  • pnpm run build — exit 0 (full dependency graph)
  • pnpm run test690 test files, 11482 tests pass, 17 skipped, 33 todo, ZERO failures

Cross-references

  • ADR-056 (this session): DB SSoT, naming convention, release-completion invariant — the canonical decision record for D1–D6.
  • T1407 (parent epic): self-enforcing release-completion invariant.
  • T1408: archive_reason TEXT → 6-value enum + CHECK constraint (DB layer).
  • T1409: ArchiveReason z.enum + tombstone subsystem in @cleocode/contracts (contract layer).
  • T1410: commit-msg lint requiring T-IDs in release commits (upstream convention this hook depends on).
  • Council 2026-04-24 verdict: .cleo/council-runs/20260425T033945Z-57a941ca/verdict.md — the canonical mandate this release closes out.

v2026.4.145

25 Apr 07:10

Choose a tag to compare

Closes the v2026.4.144 release-CI failure (104 TypeScript errors at the Type Check step) and integrates parallel-agent T1408/T1409 archive-reason work that landed mid-flight, restoring the full quality gate (pnpm exec tsc -b, pnpm biome ci, pnpm run build, pnpm exec vitest run) to green.

Closed in this release

  • T1434 Eliminate 104 TS errors + ship v2026.4.145 fully green (parent task — this release).

TypeScript error breakdown (104 → 0)

Per-domain dispatch handler error counts at start of session:

  • packages/cleo/src/dispatch/domains/nexus.ts: 44 errors — missing exports for NexusOps and 39 NexusXxxParams/Result types.
  • packages/cleo/src/dispatch/domains/check.ts: 23 errors — missing CheckOps export, 19 ValidateXxxParams types, 1 _projectRoot unused, 2 DispatchResponse shape mismatches, 1 missing 'test.coverage' op.
  • packages/cleo/src/dispatch/domains/conduit.ts: 19 errors — 9 missing ConduitXxxParams/Ops exports, 2 envelope-shape mismatches with LafsEnvelope, 7 'this' implicitly any (stray this.resolveCredential calls in standalone async functions), 1 unused _resolveCredential.
  • packages/cleo/src/dispatch/domains/sentient.ts: 13 errors — 11 missing SentientOps/AllowlistXxxParams/ProposeXxxParams exports, 2 LafsEnvelope generic mismatches.
  • packages/cleo/src/dispatch/domains/memory.ts: 2 errors — Record<string, SQLOutputValue>[] to EdgeRow[] ts2352 casts.
  • packages/cleo/src/dispatch/domains/admin.ts: 2 errors — missing AdminRuntimeParams import and LafsEnvelope discriminated-union narrowing.
  • packages/cleo/src/dispatch/engines/release-engine.ts: 1 error — id not on TaskQueryFilters.

What changed

  • packages/contracts/src/index.ts: re-exported 162+ operation types at top-level so dispatch handlers can import them from @cleocode/contracts without the ops.* namespace hop. Includes ALL of ConduitOps/NexusOps/SentientOps/CheckOps, every NexusXxxParams/Result, every ValidateXxxParams/Result, every Allowlist*/Propose* shape, plus AdminRuntimeParams/Result.
  • packages/contracts/src/operations/nexus-user-profile.ts: extended NexusProfileViewParams with includeSuperseded?: boolean to match the engine signature.
  • packages/cleo/src/dispatch/engines/nexus-engine.ts (nexusProfileUpsert): accept the dispatch wire-format Pick<UserProfileTrait, ...> and fill in engine-managed fields (firstObservedAt, lastReinforcedAt, reinforcementCount, supersededBy).
  • packages/cleo/src/dispatch/engines/release-engine.ts (releaseIvtrAutoSuggest): switched from queryTasks({ id }) (no id filter on TaskQueryFilters) to loadTasks([taskId]) — the accessor's by-id loader.
  • packages/cleo/src/dispatch/domains/admin.ts: imported AdminRuntimeParams; narrowed LafsEnvelope discriminated union via envelope.success before reading envelope.data (line 1278 — the adr.sync mode).
  • packages/cleo/src/dispatch/domains/conduit.ts: replaced 7 stray this.resolveCredential(agentId) calls (which would have crashed at runtime) with _resolveCredential(agentId); widened envelopeToEngineResult to accept LAFS code: string | number and stringify on the boundary.
  • packages/cleo/src/dispatch/domains/sentient.ts: same envelope shape fix as conduit.
  • packages/cleo/src/dispatch/domains/check.ts: dropped unused _projectRoot in chain.validate; added 'test.coverage' typed op (CheckOps declares it; legacy test op routed by params.format is preserved); used operation as keyof CheckOps & string instead of as any; normalized LAFS error code to DispatchError code.
  • packages/cleo/src/dispatch/domains/memory.ts: replaced ad-hoc as EdgeRow[] casts with the canonical typedAll<T> helper from @cleocode/core/store/typed-query.ts. Re-exported typedAll/typedGet from @cleocode/core/internal.

T1408/T1409 archive-reason follow-through

Parallel-agent work landed mid-session: T1408 added a 6-value CHECK constraint to tasks.archive_reason ('verified'|'reconciled'|'superseded'|'shadowed'|'cancelled'|'completed-unverified'), and T1409 promoted the values into a typed Zod enum at the contracts layer (packages/contracts/src/tasks/archive.ts). T1408 didn't update runtime call-sites or test fixtures, breaking 14 tests. This release closes the gap:

  • Runtime: tasks-sqlite.ts archiveTask normalizes legacy reasons; migration-sqlite.ts replaces 'migrated' fallback with 'completed-unverified'; delete.ts maps deletes to 'cancelled'; archive.ts deriveArchiveReason maps verified-done to 'verified'; transfer.ts cross-project transfers map source tasks to 'superseded'.
  • Tests: 5 fixture files updated to use enum values ('completed'/'deleted'/'Manual cleanup' → enum). archive.test.ts expectation updated.
  • Contracts portability fix: isArchiveTombstoneAllowed() in contracts/tasks/archive.ts uses (globalThis as any)?.process?.env instead of bare process so the zero-runtime-deps contracts package remains portable across Node, browser, Deno, and edge runtimes.

Test deflakes

  • sqlite-warning-suppress.test.ts: bumped spawnSync timeout 5s → 30s. CLI cold bootstrap takes ~6s on Node 24+ which raced the prior timeout under parallel-test load and produced empty stdout (T1431 carve-out, now robust under parallel run).
  • performance-safety.test.ts: bumped bulk-50-creates threshold 20s → 45s. Observed runtime under parallel-test load (4+ vitest workers + post-T1408 CHECK eval per row) is ~26s; 45s leaves headroom while still catching real regressions.
  • backup-pack.test.ts (cleanup): added settle-grace + persistent-only assertion. Sibling vitest workers running packBundle concurrently can transiently leave cleo-pack-* dirs in os.tmpdir() between pre-snapshot and post-snapshot; we now re-scan after a 50ms grace and only fail on staging dirs that persist past their owner's call boundary.
  • reconstruct.test.ts: documented RECONSTRUCT_TIMEOUT_MS rationale (git log over full history takes ~40s baseline; under parallel test load, the 60s default testTimeout can race).

Lesson

Type Check is a hard CI gate — missing contract exports MUST be re-exported at the top level of @cleocode/contracts (not just under the ops.* namespace) when dispatch handlers depend on them. Future typed-narrowing waves (Wave D-style migrations) MUST run pnpm exec tsc -b --pretty false and pnpm biome ci . against the full repo before tagging — pre-tag verification at the per-package level misses cross-package symbol resolution.

v2026.4.144

25 Apr 05:57

Choose a tag to compare

Re-ships v2026.4.143 scope as a properly-tagged release. The v2026.4.143 tag was created on commit 6b66e7f14 before the CHANGELOG section landed, so the Release workflow's Verify CHANGELOG section step rejected it (CI failed at tag-push time). The fix-forward CHANGELOG commit (ff286f5e1) and the typed-narrowing TS error reduction (51ff74664) landed afterwards, and a manual workflow_dispatch Release on ff286f5e1 succeeded — but the v2026.4.143 git tag was never moved. Per project rule "Never reuse tags", v2026.4.144 supersedes v2026.4.143 with a tag that points at a fully-green commit.

Same scope as v2026.4.143

All closures listed under v2026.4.143 below are inherited by this release. No new functional changes; only a clean tag pointing at a green-CI commit.

Lesson