Skip to content

All versions since 12.19.0

12.19.0

Jun 29, 2026

Per-Class Install Lifecycle

catalyst install, uninstall, and reinstall now work per node class — worker nodes get broker/exec-core/monitor daemons, developer and monitor nodes get the updater agent, and the distinction is enforced. Each run is a fully observable OTEL trace with phase-by-phase telemetry, automatic backup before any overwrite, and rollback to a known-good state if provisioning fails mid-flight. Use --dry-run to print the resolved plan for your node class before touching anything.

PRs

  • dev: CTL-1369 (3/n) — catalyst install|uninstall|reinstall per node class (#2452) (35339bb)
  • dev: CTL-1374 — PWA self-recovers stale lazy chunks after a redeploy (cache-control + preloadError reload) (#2447) (416ecb9)
  • dev: CTL-1375 — private-repo favicons re-probe past the cached org avatar + token-scope doctor check (#2445) (01b5208)
  • dev: CTL-1378 — board replica-title edges (parked fallback, queue payload, CATALYST_DIR) (#2449) (bb772a5)

12.20.0

Jun 30, 2026

Linear Replica & SDK Executor Hardening

This release wires up the full infrastructure for agents to read Linear from a local Catalyst Cloud replica instead of hitting the rate-limited API directly — including the new catalyst-linear CLI that reads the replica first and falls back to linearis, and a supervised per-node replica writer that keeps the local DB fresh on every node class. The SDK executor path gets two security and correctness fixes (token scrubbing on rejection, same-tick slot budget), plus a daemon launcher fix that ensures the OAuth token survives non-login restarts so executor=sdk no longer silently falls back to bg. Run catalyst install --executor sdk to provision the executor lever and cloud-sync writer together without regression.

PRs

  • dev: CTL-1369 (4/n) — class-aware doctor install verification + phase_duration_ms promotion (#2469) (99e3231)
  • dev: CTL-1383 — uniform -h/—help + bare-usage on user-facing catalyst-* CLIs (#2459) (0b137a8)
  • dev: CTL-1387 — consolidated catalyst CLI reference page + cannot-drift guard (#2468) (d989dc0)
  • dev: CTL-1391 — catalyst-linear, the replica-first Linear read CLI (linearis fallback) (#2477) (f1746ad)
  • dev: CTL-1392 — agents read the Catalyst Cloud replica first (evidence-based fallback) (#2474) (5599fe9)
  • dev: CTL-1393 — cluster nodes auto-detect + refresh rotated SOPS secrets (loudly) (#2478) (bc652ee)
  • dev: CTL-1394 — per-node supervised CatalystReplica writer (unblock mini/mini-2 Linear rate limits) (#2481) (5cca4c5)
  • dev: CTL-1395 (1/n) — catalyst-cloud-sync heartbeat + freshness → Loki (uptime tile + OTL-40 signal) (#2488) (dbd79d6)
  • dev: CTL-1396 — make the SDK-executor rollout verifiable (doctor running-daemon check + phase-turns telemetry) (#2484) (59ac079)
  • dev: CTL-1401 — catalyst install/reinstall provisions the cloud-sync + executor levers (no reinstall regression) (#2492) (e964afe)
  • dev: CTL-1367 — close the 2 final pre-canary SDK-executor gates (token-scrub on rejection path + same-tick SDK slot budget) (#2475) (160df09)
  • dev: CTL-1372 — serve orch-monitor as a production React build (root-cause leak fix) (#2453) (0df476b)
  • dev: CTL-1382 — thin-launcher catalyst CLIs resolve their symlink before locating their driver (#2465) (3e8d78c)
  • dev: CTL-1385 — board rows use wrong design tokens (bright dividers + selected-state bg) (#2462) (0e223b7)
  • dev: CTL-1398 — daemon launcher sources claude-accounts.env so executor=sdk survives non-login restarts on every host (#2487) (bf5087e)

12.21.0

Jul 01, 2026

Linear Replica Board Discovery

All Linear reads in dispatched agents now route through the local Catalyst Cloud replica via catalyst-linear, eliminating the rate-limit burns and board freezes that were stalling the fleet. Discovery now gates on the writer heartbeat lock rather than WAL mtime, so quiet feeds stay replica-served instead of falling through to the API. Two telemetry gaps are also fixed: phase-turns events were wired to the wrong parameter and never reached the event log, and SDK workers were missing their Claude Code OTel metrics because the daemon env lacked the OTLP endpoint.

PRs

  • dev: CTL-1397 — replica-backed board-list discovery (board-freeze unstick) (#2502) (5392229)
  • dev: CTL-1397 — route remaining skill-prose Linear reads through catalyst-linear (#2511) (00ec028)
  • dev: CTL-1397 (1/n) — mandate Linear reads via catalyst-linear (linearis skill + research agents) (#2496) (27ab1fe)
  • dev: CTL-1397 (2/n) — route per-dispatch Linear reads through the replica (catalyst-linear) (#2501) (8a3e336)
  • dev: CTL-1397 (3/n) — trust the seed-complete replica-empty (durable board-freeze unstick) (#2509) (36482e7)
  • dev: CTL-1397 (4/n) — gate replica discovery on the writer heartbeat lock (close the quiet-feed linearis fallback) (#2512) (edd4b58)
  • dev: CTL-1406 — SDK phase workers emit session.context (dashboard panels 50/51) (#2508) (2ab5f57)
  • dev: CTL-1404 — SDK phase-agent workers emit claude_code_* OTel again (daemon env lacked the OTLP endpoint) (#2504) (1b726bb)
  • dev: CTL-1405 — sdkDispatch passes emitEvent in the wrong param → phase-turns telemetry never reached the event log (#2500) (6795089)
  • dev: CTL-1407 — provision the per-account rate-limit usage sampler on every host (#2507) (58f040e)

12.22.0

Jul 02, 2026

SDK Worker Registry & Fleet Resilience

This release introduces a unified in-process SDK worker registry that tracks live workers with heartbeats, sticky abort semantics, and disk projections — closing the liveness blind spots that left the scheduler, delegate queue, and worktree refresh timer unable to see workers running outside the bg executor. Alongside that, a Linear quota storm can no longer freeze fleet admission: when the circuit breaker is open, a provably-real replica-empty is now trusted directly instead of looping into a failing linearis reconfirm. Agent reads also move off the catalyst-linear CLI to direct SQLite queries against the local replica, giving agents full join support and a single, well-defined freshness rule; catalyst-linear is now a deprecated shim.

PRs

  • dev: CTL-1157 — Self-Healing Delegate wave 1 (board-health sees + acts on stuck work; shadow-gated, dark merge) (#2503) (32d2218)
  • dev: CTL-1397 — pivot agent Linear reads to direct SQLite; deprecate catalyst-linear CLI (#2514) (249c9d6)
  • dev: CTL-1402 — bump @catalyst-cloud/sdk → ^0.3.1 + telemetry:true (replica apply-failures observable) (#2517) (0e2883f)
  • dev: CTL-1410 (Phase A) — in-band terminal signal flips for event-only phases + SDK success safety net (#2524) (ba06b66)
  • dev: CTL-1410 (Phase B) — unified in-process SDK worker registry + liveness re-points (#2529) (89fd452)
  • dev: CTL-1421 — doctor asserts the worker plugin path is a fresh pristine plugin-source (#2537) (e1c48f3)
  • dev: catalyst-cloud#127 — bump @catalyst-cloud/sdk → ^0.4.0 (forward-compat filter + auto-reseed backfill) (#2525) (3d4bc40)
  • dev: CTL-1416 — bash-3.2-safe emit-complete session-end + hermetic thoughts fixture for its tests (#2535) (aaeba1e)
  • dev: CTL-1416 — make phase-agent-emit-complete bash-3.2-safe (aaeba1e)
  • dev: CTL-1418 — quiet catalyst-agent’s pino-unavailable shim notice (#2533) (7aa8af4)
  • dev: CTL-1420 — unfreeze fleet admission during a Linear quota storm (#2538) (b2955e1)

12.23.0

Jul 02, 2026

Warm Resume & Replica-First Reads

A daemon restart now continues in-flight SDK work from its existing transcript instead of cold-restarting — making fleet-wide stop/restart-all a routine, low-cost operation. Alongside that, replica-first Linear reads are now a standard reflex across every agent path: enforced in core context, phase-worker preambles, and a new PreToolUse hook that can catch and block bare linearis issues read calls before they hit the rate-limited API key.

PRs

  • dev: CTL-1397 enforcement — replica-first Linear reads as a standard prerequisite reflex (#2543) (98dfbac)
  • dev: CTL-1422 — warm resume: a daemon restart continues in-flight SDK work (#2544) (cca2892)

12.23.1

Jul 03, 2026

Linear Rate-Limit Freeze Fixes

A cluster of fixes targeting the shared Linear bucket saturation that was freezing fleet dispatch and silently stalling replicas. Fence-guard reads are now cached (45s TTL), anchor UUID lookups are cached permanently, and dispatch reads route through the replica instead of hitting Linear live — together dropping breaker trips from ~18 per 3 minutes to near zero. A cloud-sync stall watchdog now detects frozen replica sockets and self-heals via process restart rather than sitting silent for hours, and interactive claude sessions now load plugins from ~/catalyst/plugin-source on the same path as workers.

PRs

  • dev: cloud-sync stall watchdog + loud alert — stop silent replica freezes (#2547) (fd74bda)
  • dev: cluster-heartbeat — back off the shared bucket on a rate-class Linear 400/429 (CTL-1420 follow-up) (#2539) (01d8844)
  • dev: CTL-1420 — dispatch reads via replica (Stage 0: ownership→replica, eligible breaker-aware) (#2551) (32f34dd)
  • dev: CTL-863 — cache the fence entourage (ResolveIssueId anchor-UUID + GetIssueByIdentifier) to fully clear the shared bucket (#2554) (19e5a66)
  • dev: CTL-863 — interim in-process TTL cache for fence ReadFence to unfreeze the shared Linear bucket (#2552) (3cc975e)
  • dev: standard plugin-source loading for interactive sessions + drop marketplace guidance (#2549) (8c96b1f)

12.24.0

Jul 04, 2026

Durable Fence Event Log & Done Path Fix

The fence write path now appends durable fence.claimed/fence.released events to the canonical event log instead of relying solely on Linear, eliminating the risk of fence emits triggering the admission freeze. A bug in fenceGuard that caused it to compare the wrong generation counter — blocking every ticket from reaching Done automatically on multi-host rosters — is now fixed by reading the correct cross-host claim generation from cluster-generation.json. Pino log levels are also now mapped to OTel SeverityNumber/SeverityText at emit time, so operational logs no longer arrive in Loki as UNKNOWN severity.

PRs

  • dev: CTL-1424 — otel-forward pino level → OTel SeverityNumber/Text at emit (#2558) (514fd7e)
  • dev: CTL-863 — durable fence→event-log migration (N=1-gated), supersedes the interim ReadFence cache (#2553) (0e70424)
  • dev: CTL-1157 (A1) — fence-guard reads the cross-host claim generation (unblocks the Done path) (#2563) (cb35036)

12.25.0

Jul 07, 2026

Linear Breaker Observability & Board Health Actuation

The Linear circuit breaker now records why it opened (rate-limit 429 vs. timeout) and which caller triggered it, making the 12–22 daily trips on mini attributable and falsifiable from logs for the first time. On the board-health side, deferred recovery intents now have a live consumer so they actually dispatch instead of rotting, operator-sanctioned needs-human latches are suppressed from re-proposal so genuinely stuck tickets surface, and stale escalated recovery intents expire after 7 days instead of pinning tickets in needs-human forever. The top measured breaker driver — eligible empty-reconfirm firing a live Linear read every quiet tick — is also removed entirely; a replica-empty is now trusted directly with zero live Linear reads.

PRs

  • dev: CTL-1430 (WS-A A1) — instrument the Linear breaker (reason+caller on OPEN + durable linear.ratelimit.breaker event) (#2565) (ec03e6f)
  • dev: CTL-1431 (WS-B B1) — TTL on terminal recovery-intents + one-time June sweep (#2567) (9c5bb13)
  • dev: CTL-1432 (WS-B B2+B3) — dispatch deferred board-health intents + suppress sanctioned needs-human latches (#2570) (880261e)
  • dev: CTL-1433 (WS-A A2) — raise the eligible empty-reconfirm TTL above the reconcile interval (cut the top breaker driver, keep drift validation) (#2572) (96ea944)

12.26.0

Jul 08, 2026

Linear Read Observability & Actuation Liveness

Every Linear read now emits a catalyst.linear.read event with source and result attributes, so your OTEL collector can derive read totals and a staleness histogram — and alert on replica bypasses before the 429 breaker trips. The delegate’s board-scan events now record whether a proposed move was actually dispatched, and a new checkActuationLiveness invariant flags sustained propose-but-never-dispatch conditions automatically. A negative cache on terminal-probe and census reads stops replica-miss tickets from firing live Linear reads every tick, which was the primary driver of breaker flaps.

PRs

  • dev: CTL-1403 — emit reads-by-source (catalyst.linear.read{source,result}) on every Linear read (#2582) (d23e8b1)
  • dev: CTL-1435 (WS-C C1+C2) — self-observing actuation-liveness (act-outcome on board-scan + checkActuationLiveness invariant) (#2576) (06bb61f)
  • dev: CTL-1436 (WS-A A4) — negative-cache fetchTicketState replica-MISS live reads (stop the issues-read breaker flap) (#2579) (7f99ddc)
  • dev: CTL-1437 (A4 follow-up) — widen probeBackoff to the every-tick terminal-Done sweep (#2581) (52d58cc)

12.27.0

Jul 08, 2026

Recovery Loop Elimination & Escalation Fixes

This release closes five compounding loops that caused the recovery pass to silently discard verdicts, re-triage tickets indefinitely, and emit no-progress escalations forever. Recovery-pass sessions now persist a single verdict (fixed, leave-alone, or escalate) to the event log, ledger, and Linear in every case — and exhausted intents surface loudly as needs-human with a rendered brief instead of latching silently. Infinite escalation loops are capped and go terminal, triage re-dispatches are bounded per ticket, and the boot-resume approval gate finally has a CLI (boot-resume-approve.mjs --list / <ticket>) so gated recovery passes can actually be unblocked.

PRs

  • dev: CTL-1439 (P0a) — recovery-pass verdict persistence + surfacing (stop act-and-discard) (#2586) (af29551)
  • dev: CTL-1440 (P0b) — attempts-exhausted → loud escalation, RC3 defer-storm decoupling, truthful skip reasons (#2593) (1ef0e57)
  • dev: CTL-1443 (P1-loop-3) — operable boot-resume approval gate (approve CLI + 48h expiry into Needs-You + alert) (#2596) (a6aa271)
  • dev: CTL-1441 (P1-loop-2) — terminate the triage re-dispatch loop (cap + mismatch surfacing + WORKER_DIR hardening) (#2588) (9dd5309)
  • dev: CTL-1442 (P1-loop-1) — no-progress escalations go terminal after N asks (stop the every-10-min forever loop) (#2590) (001557c)

12.28.0

Jul 09, 2026

Liveness Off Linear

Cross-host dead-host detection now reads from Loki instead of Linear, eliminating the ~120 heartbeat writes per hour that were tripping the rate-limit breaker. Two live-deploy bugs in the initial reader were caught and fixed: stale streams no longer win the newest-host race, and in-flight ticket enrichment now runs as a separate fail-open query. The switch is gated behind CATALYST_LIVENESS_READ_SOURCE=loki — set it on all hosts simultaneously to enable; unset to revert instantly.

PRs

  • dev: CTL-1420 (#17) — move cross-host liveness off Linear → event log + Loki (PR1a: heartbeat carries in-flight tickets) (#2575) (ff99913)
  • dev: CTL-1420 (#17) — read cross-host liveness from Loki + retire the Linear heartbeat publish (PR1b) (#2604) (9924aa2)
  • dev: CTL-1420 (#17) follow-up — loki-liveness reader: newest-across-streams + two-query tickets (#2606) (4aa925b)
  • dev: CTL-1443 follow-up — sync CLI reference for boot-resume-approve (unblocks CI) (#2603) (7d34bd8)
  • dev: CTL-1451 (A4 final widening) — probeBackoff on the recovery-filter + reclaim terminal reads (kills the ADV-1433 read-storm) (#2608) (6d4928f)
  • dev: CTL-1452 — parity test exempts action:skip STALL_CATEGORY_MAP entries (restores exec-core CI on main) (#2610) (6e550ba)

12.29.0

Jul 13, 2026

Two-Axis Worker State Model

Worker state transitions now fan out through a single recordTransition chokepoint that writes to all five sinks — Linear Status, worker-status label, event log, OTLP, and broker table — on every confirmed state change, with per-sink fail-open isolation so one unavailable sink can’t block the others. A new convergeDispositionLabel function enforces full disposition precedence (needs-human > needs-input > blocked > queued), and the worker-status Linear label group is provisioned automatically by setup-execution-core-states.sh. The HUD queue UI now reflects the corrected disposition buckets, and waiting has been renamed to queued throughout.

PRs

  • dev: CTL-764 two-axis worker-state model — recordTransition chokepoint, worker-status labels, convergeDispositionLabel (#2597) (2ebbed3)
  • dev: CTL-764 follow-up — Codex round-3 emission gating + gitleaks allowlist (greens main) (#2631) (27781cf)
  • dev: CTL-764 follow-up — Codex round-4 emission/fallback edge cases (#2632) (3fa0429)
  • dev: CTL-764 follow-up — declare synthesizeOrphanTickets in board-data.d.mts (greens main quality gate) (#2630) (96ea021)

12.29.1

Jul 14, 2026

Thenable-Aware Removal Confirmation

The removeLabel async bug is fixed — previously, inspecting a Promise’s .removed property always returned undefined, so failed removals were silently treated as successful. The fix makes the result handler thenable-aware, deferring the admission clear emission until the async write actually resolves or rejects.

PRs

  • dev: CTL-764 follow-up — round-5: thenable-aware removal confirmation (#2636) (2df9d10)

12.30.0

Jul 15, 2026

Codex Executor & Worker Label Ownership

The daemon can now dispatch phase workers to OpenAI Codex via a new codex-exec executor adapter, routed per-phase through executorByPhase config with zero behavior change until you explicitly flip a phase to it. Linear boards now show which node owns each in-flight ticket via stamped worker:<host> labels — ownership is board-filterable and readable from the local replica without a live Linear call. Both worker-label provisioning paths (reconcile_worker_host_labels and reconcile_worker_status_labels) are hardened against the current Linear API’s isGroup:true requirement, which broke fresh-workspace installs; run the setup script on any new node to provision labels cleanly.

PRs

  • dev: CTL-1457 codex-exec executor adapter — daemon dispatches phase workers on Codex (#2639) (1ae616a)
  • dev: CTL-1481 worker:<host> label ownership — Linear board shows which node owns each ticket (#2650) (47946d7)
  • dev: CTL-1481 follow-up — worker group create needs isGroup:true (live API drift) (#2651) (f6099a9)
  • dev: CTL-1483 mirror isGroup:true fix to reconcile_worker_status_labels (#2653) (e1d5d0c)

12.30.1

Jul 17, 2026

Replica-Read Detector Fixed

The Linear replica-read detector introduced in a prior release was never actually firing, leaving agents free to burn the shared API quota on reads the replica could have served. The fix rewrites the command-word matching from a single anchored regex to a token walk that correctly resolves the real command past environment assignments, wrapper prefixes like direnv exec ., and shell keywords — and now recognizes both linear and linearis. The enforce mode remedy path is also corrected to an absolute location so it’s actually sourceable in the repos where the hook now fires.

PRs

  • dev: CTL-1420 replica-read detector was blind to the linear alias + wrapper prefixes (#2658) (19f7ada)

12.31.0

Jul 19, 2026

Agent House Rules & Replica Read Fix

Two changes land together to make unattended agents less error-prone. A new “Working the Loop” block is now seeded into every project’s AGENTS.md via agents-house-rules.md, teaching agents to subscribe to the unified event log instead of polling GitHub or CI, detect automated review approvals via reactions, and read Linear tickets from the local replica rather than the live API. Alongside that, the replica-read instruction itself is corrected — background agents were silently falling through to bare linearis because linear_read_ticket is a shell function that never resolves in an unattended Bash session; the instruction now leads with the sqlite3 form that works in any shell. Run check-project-setup.sh to verify your projects have the new reflex markers in place.

PRs

  • dev: agent house-rules block + checkup (CTL general-instructions) (#2663) (e6e67db)
  • dev: CTL-1420 replica-read rule pointed bg/daemon agents at a shell function not on PATH (#2661) (efd9a2b)

12.32.0

Jul 21, 2026

Agent House-Rules Auto-Seeding & Inbox Polish

Any repo you enroll in Catalyst now automatically receives the “Working the Loop” agent house-rules block — seeded into AGENTS.md (or CLAUDE.md if that’s what the repo uses) without any manual setup. The block itself has been hardened: Linear reads must go through the catalyst-dev:linearis skill rather than raw API calls or hand-rolled sqlite, and a contradictory degraded escape that could reintroduce shared-quota burn has been removed. Inbox rows also get a cleaner look — favicon restored, unwrapped ID, two-line title, and corrected pane accent.

PRs

  • dev: auto-seed agent house-rules on every enrolled repo + Codex-hardened block (#2666) (97aa6de)
  • dev: CTL-1127 — inbox row: restore favicon, unwrap ID, two-line title, drop verb cluster, fix pane accent (#1991) (2cda8d5)
  • dev: CTL-682 — wait-watcher skips background agents; pin scheduler test live-count seam (#2670) (4fd98b2)
  • dev: drop the Linear-API degraded escape (contradicted the absolute replica rule) (#2668) (507b227)

12.33.0

Jul 22, 2026

Dispatch Roster Failover & Worktree Repair

Offline and never-live hosts no longer strand their share of the ticket backlog — dispatch ownership now hashes over a liveness-filtered roster with restore-side deflap hysteresis, so a live host picks up any slice whose owner has gone dark. A separate fix repairs worktrees whose thoughts/shared was left as a plain directory instead of a symlink, so handoffs and research written into reused worktrees actually sync instead of silently accumulating in a dead-end local dir.

PRs

  • dev: CTL-1091 Phase 1 — route dispatch gates through the surviving roster (#2671) (2fb23ee)
  • dev: CTL-1497 — repair thoughts/shared on the worktree reuse path; guards test -L not -d (#2685) (c4bf08c)

12.34.0

Jul 23, 2026

Autonomous PR Block Recovery

When a PR fails to merge, the recovery pass now probes GitHub live — checking CI status, unresolved bot review threads, and review decisions — and routes autonomously: bounded fixes get dispatched to a worker, while genuine human gates (CHANGES_REQUESTED from a person, no open PR found) escalate with specific context instead of an opaque failure message. A CATALYST_EXECUTOR_BY_PHASE JSON env var also lands in this release, letting you set durable per-phase executor routing in execution-core.env without it being wiped by the broker’s periodic git reset. The recovery pass feature ships behind CATALYST_RECOVERY_PASS=shadow|enforce and is off by default.

PRs

  • dev: CTL-1496 recovery-pass drives blocked PR to merge instead of escalating (#2689) (bec5e03)
  • dev: CTL-1457 follow-up — CATALYST_EXECUTOR_BY_PHASE env override (durable per-node routing) (#2655) (3afb50a)

12.35.0

Jul 23, 2026

Agent Browser Leak Fix & Scheduler Hardening

Leaked agent-browser Chrome processes that outlived their worker sessions — sometimes pegging a CPU core indefinitely — are now reaped automatically by a new vector in the hourly orphan sweep, which targets runaway or idle Chrome-for-Testing instances while leaving personal Chrome untouched. Workers also receive an idle-timeout environment variable at dispatch so agent-browser shuts itself down after 5 minutes of inactivity on supported versions. Two scheduler fixes round out the release: phantom ticket directories (like .catalyst) no longer poison board-health checks, and a transient source conflict during dispatch-time rebase now triggers a single retry against a fresh base before parking the ticket as needs-human.

PRs

  • dev: CTL-1500 reap leaked agent-browser Chrome + idle-timeout + setup-tooling ownership (#2702) (74fa0a8)
  • dev: CTL-1504 guard scheduler census sites + classify not-found (stop CTC-phantom board-health poison) (#2698) (6d6d154)
  • dev: CTL-1505 retry rebase against fresh origin/<base> before parking a source conflict (#2701) (17de576)

12.36.0

Jul 25, 2026

Cloud-Sync Self-Heal & Daemon Health Responder

Two fixes targeting the root causes of the 2026-07-23 replica-writer outage. The cloud-sync writer now exits cleanly within a bounded timeout on both stall and shutdown paths, writes a breadcrumb when it self-heals, and detects half-open sockets in roughly 2 ticks instead of 80+ minutes using SDK lastFrameAt. A new stateless launchd sweep runs every 3 minutes to catch the case where the writer dies and launchd fails to respawn it — kicking it back with a bounded, escalating retry rather than depending on KeepAlive alone. After merging, run catalyst-stack install-services on affected nodes and verify with catalyst doctor.

PRs

  • dev: CTL-1509 daemon-health responder — stateless launchd sweep kickstarts a dead/stale cloud-sync writer (bounded, escalating) (#2710) (6e0ec37)
  • dev: CTL-1508 exit-safe cloud-sync self-heal + selfheal breadcrumb + lastFrameAt stall classifier (#2709) (1e33520)

12.37.0

Jul 26, 2026

Daemon Stability & Memory Audit Remediation

This release fixes a cluster of runtime reliability issues discovered during a live memory and health audit on production nodes. The most impactful changes stop a 115-second scheduler stall caused by reading a 300 MB event log on every tick (now a bounded cursor scan), close a file-descriptor leak in the delegate-runner that was trending toward EMFILE, and silence ~300 spurious “daemon degraded” phone notifications per day by replacing a naked edge trigger in the notification filter with a 180-second sustained-state hold. Also included: per-process RSS/heap OTel gauges on every daemon so future leaks can be attributed to a specific service, edge-triggered fleet-health probes that fire once per degradation episode instead of on every tick, and a health-responder backstop that now supervises the host-metrics sampler so a silently dead agent gets auto-kickstarted rather than going unnoticed for days.

PRs

  • dev: CTL-1503 edge-triggered fleet-health probe (hysteresis band + recovered event + durable latch) (#2704) (a4dc53e)
  • dev: CTL-1517 per-process RSS/heap OTel gauge on every daemon (leak attribution) (#2732) (8c85824)
  • dev: CTL-1518 health-responder supervises com.catalyst.agent sampler (self-heal backstop) (#2731) (b3ae705)
  • dev: CTL-1510 health-responder hardening — token-aware exit-0 gate, sweep lock, cron backstop + 5 more edges (#2714) (92ac2ec)
  • dev: CTL-1513 bash-3.2 comment-parsing crash in _token_provisioned (production hotfix) (#2719) (ffd7da1)
  • dev: CTL-1514 tail event log by cursor in execution-core (stop 115s scheduler stalls) (#2729) (ac009d9)
  • dev: CTL-1515 bound orch-monitor readBacklog/readTunnelEventStats fallbacks (chunked scan) (#2730) (9ea4502)
  • dev: CTL-1516 bound broker _emittedWakeCache + heartbeat/orchestrator maps (#2728) (2001242)
  • dev: CTL-1519 close delegate-runner log fd after detached spawn (fd leak → EMFILE) (#2727) (5709d17)
  • dev: CTL-1522 hold daemon-degraded notifications so a transient heartbeat stall never pushes (#2739) (5b56cef)
  • dev: CTL-1523 stop the broker reporting daemon-degraded on an idle fleet (#2740) (4a58ddd)

12.38.0

Jul 27, 2026

Dual-Harness Migration & Event Loop Fix

Run migrate-dual-harness.sh to migrate a single-harness repo (Claude-only or Codex-only) to the vendor-neutral dual-harness layout where both Claude Code and Codex share the same instructions and skills — checkup §10 and a new foundry skill handle the split automatically. A daemon event loop stall that caused 72–97 second heartbeat gaps during worktree cleanup bursts is also resolved, along with a fix that stamps provider delivery IDs onto webhook envelopes so the smee-vs-cloud parity harness can actually join on them.

PRs

  • dev: CTL-1530 dual-harness migration (migrate-dual-harness.sh + checkup §10 + foundry skill) (#2753) (0afc204)
  • dev: CTL-1524 unblock the daemon event loop in wt-cleanup-drain (free provenance gate first + bounded burst) (#2747) (d31c9c6)
  • dev: CTL-1532 stamp the provider delivery id on webhook envelopes (#2751) (708437b)

12.39.0

Jul 29, 2026

Supervised Watchers, Orphan Reaper & Board Health

Channel-watchers now run as supervised launchd daemons that emit a heartbeat every interval and trigger a broker dead-man’s switch alert when a watcher goes silent for more than three intervals. The orphan reaper drops its node/bun/turbo allowlist and now reaps any process whose cwd sits under a deleted worktree, batching the cwd lookups into a single lsof call to keep sweep cost under 730 ms. Two new board-health checks round out the release: one flags in-flight tickets with no worker, no signal file, and no open PR, and one bounds every read of the monthly event log to a time-covering tail — cutting a 341 MB scan from 1,114 MB peak RSS to 143 MB flat.

PRs

  • dev: CTL-1423 — supervised background channel-watchers with (6701521)
  • dev: CTL-1423 — Supervised background channel-watchers with heartbeat + dead-man’s-switch alerting (#2557) (6701521)
  • dev: CTL-1475 flag work that claims to be in flight while nothing owns it (#2763) (d022893)
  • dev: CTL-1531 reap orphaned processes by ownership evidence, not a node/bun allowlist (#2756) (c0267ba)
  • dev: CTL-1529 bound every read of the monthly event log (time-covering tail + shared per-tick scan) (#2757) (ab49964)

12.39.1

Jul 30, 2026

Needs-Human Clears on Reply

When a developer responds to a parked ticket, it now immediately drops off the “Needs you” list — no matter whether the worker directory still exists. Previously, most parked tickets were permanently stuck in that state because the clear was gated on a local directory that gets cleaned up after a worker is reaped.

PRs

  • dev: CTL-1567 clear needs-human the moment a human responds (#2796) (2f71e13)

12.40.0

Jul 31, 2026

Inbox Conversation Surface & Linear API Burn Fixes

The inbox is now a full conversation surface: you can read a parked ticket’s ask summary, thread, and suggested replies — and post a response as yourself without leaving the inbox. Alongside this, a cluster of Linear API quota fixes lands together: the Workers page now reads peer liveness and capacity from Loki instead of a stale Linear anchor, the broker authenticates as the app actor so reconcile reads no longer bill your personal API bucket, and several scheduler paths that were firing live Linear probes on every tick now use the replica or a cooldown window instead.

PRs

  • dev: CTL-1569 make the inbox a conversation surface (ask summary + thread + inline reply) (#2801) (1d59e75)
  • dev: CTL-1574 ticket activity feed (Discussion) in monitor inbox + ticket page (#2815) (d22b757)
  • dev: CTL-1551 budget the peer-liveness live window for transport lag (#2809) (8ad9ff5)
  • dev: CTL-1551 Workers page reads peer liveness+capacity from Loki, not the dead Linear anchor (#2808) (3b095af)
  • dev: CTL-1570 stop the phantom sweep spending a live Linear read per tick on workerless dirs (#2803) (8028469)
  • dev: CTL-1571 cache-reconcile reads the replica, not live Linear (#2824) (59fa625)
  • dev: CTL-1577 broker authenticates to Linear as the app-actor (#2814) (0a209a1)
  • dev: CTL-1580 stop per-tick live probes of stuck tickets; instrument the invisible reads (#2825) (ea6db1b)

12.41.0

Jul 31, 2026

Slot Deck Fixes & Direnv Profile Sync

The slot deck now correctly shows which slots are occupied — SDK/executor workers are visible to the deck, held tickets are separated into a “Held — awaiting you” section rather than ranked as imminent dispatches, and header counts derive from the deck’s own boxes so the two can never contradict each other. Triage admission is now level-triggered, meaning tickets already sitting in Triage when a worker dir vanishes get picked up on the next sweep instead of stranded. cluster-sync also gains a new syncProfileFiles step that materializes direnv profiles from a SOPS bundle, so worker repos get the right environment variables on every host without hand-provisioning files.

PRs

  • dev: CTL-1585 discussion newest-first in inbox, inline on detail page, Spec tab renamed Detail (#2832) (bc34131)
  • dev: CTL-1595 cluster-sync materializes direnv profiles from a SOPS bundle (#2849) (a0daa05)
  • dev: CTL-1581 slot deck renders occupancy, not ownership — counts derive from the boxes (#2826) (719bc9a)
  • dev: CTL-1588 queue humanHold falls back to replica labels when the webhook-fed store has gaps (#2845) (9d40a77)
  • dev: CTL-1588 slot deck sees SDK-executor workers; queue partitions human-held tickets (#2840) (df05fa6)
  • dev: CTL-1589 level-triggered triage sweep — pick up tickets already sitting in Triage (#2843) (4fc6993)
  • dev: CTL-1593 capture the recovery cursor before reconcileAll so boot telemetry can’t shift it (#2844) (45343f8)

12.42.0

Aug 02, 2026

Worktree Guard & DNS Rebinding Fix

The monitor’s reply endpoint now validates Origin against a trusted allowlist of loopback addresses, local hostnames, and non-loopback IPs — closing a DNS rebinding hole where an attacker-controlled page could post Linear comments as the operator. Separately, every shell-side git worktree remove --force call now runs a safety check that refuses removal if your current directory is inside the target or any process holds an open handle under it, protecting against accidental self-deletion that the Node reaper never covered.

PRs

  • dev: CTL-1417 — worktree-removal self-protection guard (#2556) (24b9a76)
  • dev: CTL-1573 validate reply Origin against a trusted allowlist, not the request Host (#2857) (10ecce7)

12.43.0

Aug 03, 2026

Deployment Mode Resolver & Credential Hardening

This release introduces a unified deployment-mode resolver (single-host, cluster, or cloud) that reads identically in bash and JS, with advisory doctor checks and gated tunnel/webhook behavior wired across execution-core, orch-monitor, and catalyst-join.sh. It also fixes a live credential outage: daemon processes now re-arm their GitHub token from disk on every cluster-sync tick rather than inheriting a frozen env at boot, and linear-reconcile-cli correctly falls back to LINEAR_API_KEY when LINEAR_API_TOKEN is absent. Several reliability fixes round out the release: stale needs-human/blocked labels can no longer be re-applied to tickets already terminal in Linear, escalated recovery intents no longer latch permanently past their 7-day TTL, and the board no longer shows zero tickets for teams registered only in cluster.json.

PRs

  • dev: CTL-1603 — fix board showing zero tickets for cluster-only teams (#2868) (47a8c78)
  • dev: CTL-1610 — fix escalated-intent permanent latch and actuation-liveness blind spot (#2882) (69dd8ad)
  • dev: CTL-1616 secret-contract registry pair + cluster-sync derivation (PR1) (#2902) (1275440)
  • dev: CTL-1617 deployment-mode resolver in isolation (PR1 of 7) (#2895) (581ad4f)
  • dev: CTL-1617 doctor deployment-mode tunnel-consistency check (PR6 of 7) (#2906) (4ac3bea)
  • dev: CTL-1617 execution-core wiring + advisory deployment-mode doctor checks (PR2 of 7) (#2899) (374c1b3)
  • dev: CTL-1617 gate catalyst-join webhook wiring on declared deployment mode (PR5 of 7) (#2913) (1b983f3)
  • dev: CTL-1617 gate orch-monitor smee tunnels on deployment mode (PR3 of 7) (#2900) (a73ce21)
  • dev: CTL-1605 — route worker-status labels through a terminal-aware chokepoint (#2872) (8855c10)
  • dev: CTL-1612 arm daemon credentials from the shared secret files at boot (#2884) (ea5d031)
  • dev: CTL-1617 jq-exact lone-surrogate acceptance in the deployment-mode reader (#2907) (84e7682)
  • dev: CTL-1617 whole-document lone-surrogate parity + architecture-doc precision (#2904) (6b1cfd8)
  • dev: CTL-1619 adopt LINEAR_API_KEY fallback in linear-reconcile-cli —graphql (#2893) (bb0fff5)
  • dev: CTL-1620 resolve the rescue prompt template from plugins/dev/templates (#2892) (cf13213)

12.44.0 (2026-08-04) Latest

Features

  • dev: CTL-1616 cloud-token name-resolver unification + Groq resolveApiKey adoption (PR5) (#2927) (be673ea)
  • dev: CTL-1616 doctor cloud-guard escalation + shadow-diffed Layer-2 stragglers (PR6) (#2929) (56fbe72)
  • dev: CTL-1616 doctor secret-contract shadow pass (PR2, zero grade change) (#2916) (0377813)
  • dev: CTL-1616 fold the 9-file Linear read into the secret contract + doctor cutover (PR3) (#2919) (01294fc)
  • dev: CTL-1616 fold the OAuth-mint trio + read-only 4th onto the secret contract (PR4) (#2924) (22afee0)
  • dev: CTL-1622 setup-catalyst prompts for and persists catalyst.deployment.mode (#2912) (3af40d2)
  • dev: CTL-1628 catalyst-runtime-root resolver — fold Tier 1 duplicates + 4 latent resolver bugs (Phase A2) (#2946) (c01ef76)
  • dev: CTL-1628 root bun workspace + turbo (Phase A1) (#2945) (a61c8a8)

Bug Fixes

  • dev: CTL-1616 clear the sticky export attribute on the value breadcrumb (#2926) (ea1e474)
  • dev: CTL-1616 declare the split-brain Layer-2 layout unsupported + finish the observe-only story (#2931) (ca7ec68)
  • dev: CTL-1616 divergence check round 3 — reject relative paths, per-service remedy, no committed ticket prefix (#2939) (6c134b1)
  • dev: CTL-1616 divergence check round 4 — prefix-agnostic assertion + no dead-end remedy (#2941) (b811eb0)
  • dev: CTL-1616 harden the layer2-path-divergence check (#2931 round-2 Codex x2) (#2938) (694dc20)
  • dev: CTL-1616 keep the resolved secret VALUE out of child-process environments (#2925) (2c6901c)
  • dev: CTL-1616 PR6 follow-up — observe-only Layer-2 shadow + doctor coherence (#2929 Codex x4) (#2930) (64dddf5)
  • dev: CTL-1617 align doctor webhook-ingestion with the declared deployment mode (#2918) (d1d66e9)
  • dev: CTL-1617 close the three late #2918 Codex findings on the mode-aligned doctor grant (#2920) (905dbaa)
  • dev: CTL-1617 harden the join webhook-wiring gate (Codex follow-up to #2913) (#2914) (0bd14f8)
  • dev: CTL-1628 A1 isolate bun sniff from project config (Codex #2966 post-merge) (#2967) (ef09cb4)
  • dev: CTL-1628 A1 multiline-tolerant jq-less packageManager sniff (Codex #2948 post-merge) (#2964) (bac5434)
  • dev: CTL-1628 A1 post-merge hardening (Codex #2945 threads) (#2948) (c3f6944)
  • dev: CTL-1628 A1 retry TMPDIR when safe-cache mktemp fails (Codex #2972 post-merge) (#2975) (14bd0b6)
  • dev: CTL-1628 A1 sniff scratch-dir hardening + tier fallthrough (Codex #2967 post-merge) (#2972) (92226cb)
  • dev: CTL-1628 A1 tiered packageManager detection (Codex #2964 post-merge) (#2966) (1f22f0e)
  • dev: CTL-1628 A1 verify TMPDIR parent + scratch-dir before trusting it (Codex #2975 post-merge) (#2977) (27517ec)
  • dev: CTL-1628 A2 post-merge hardening (Codex #2946 threads) (#2947) (831a469)
  • dev: CTL-1628 comment-wake emission accounting + cross-host dedup reset (Codex #2970 post-merge) (#2973) (36e4cf4)
  • dev: CTL-1628 credit survives throw + early-path needs-input dedup clear (Codex #2974 post-merge) (#2976) (666044d)
  • dev: CTL-1628 delete unreachable catalyst-filter daemon body (keep alias) (#2949) (6a7d4cd)
  • dev: CTL-1628 freeze-cause telemetry mirror, legacy hydration default, persist retry (#2968) (8fffff5)
  • dev: CTL-1628 heartbeat publisher — require Linear anchor only in linear read-source mode (#2958) (3247e76)
  • dev: CTL-1628 orch-monitor roster readers → cluster.json roster (stop-worker fence + cross-node tail) (#2959) (7d5b93d)
  • dev: CTL-1628 retire ADR-018 JSON-shadow scaffolding + unused recordWorkerTransition module; document CTL-532 as the live projection (#2961) (3600198)
  • dev: CTL-1628 single-consume early-write credit + disposition-scoped dedup reset (Codex #2973 post-merge) (#2974) (c877a25)
  • dev: CTL-1628 surface eligible-set projection-write failure as health event (#2960) (c04f1a7)
  • monitor: mint app-actor Linear token on monitor start (supersedes #2905) (#2978) (f6fdeb9)
  • monitor: post-merge hardening — scan reachability, stop-cancels-remint, bash probe status (#2979) (34c5467)