Skip to content

v0.32.1

Choose a tag to compare

@github-actions github-actions released this 15 Jul 11:24

v0.32.1

A hardening release. A partitioned adversarial audit pass covered every subsystem — transform core, historian, emergency paths, storage, TUI/RPC, smart-notes, CLI — and this patch ships the resulting fixes: two silent-data-loss classes closed, a fail-closed overflow gate, a batch of lifecycle races, and cleaner historian summaries.

Context safety

Emergency overflow now fails closed

At ≥95% usage with no fold available, Magic Context previously did its best-effort reduction and let the request through — which could still overflow the provider and crash the turn mid-stream. The emergency path now blocks the request outright and interrupts the turn cleanly when three conditions hold together: the context limit is provider-proven (a persisted overflow detection or a real 400, never the token estimator), usage is genuinely ≥95%, and no fold materialized in the current pass. The token estimator is demoted to telemetry on this path, so estimate drift can never abort a healthy request. Restart-safe via a new schema column (migration v52).

Historian gaps are rejected, not absorbed

When the historian's output left small gaps between compartments, a healing step silently extended the previous compartment to cover them. Tool-only noise absorbed that way is fine — but the same path could absorb up to 15 messages of real narrative into a compartment whose summary never saw them: silently missing history. Gap healing is now strict: tool-only gaps still absorb, narrative-bearing gaps reject the chunk and the range is re-read on the next run. Nothing user-visible changes on healthy sessions; degenerate outputs now retry instead of losing content.

Historian

Summaries in the first person

The historian writes memory for the agent's own future self, but its summaries drifted into third-person reporting ("The agent investigated X..."). The prompt now enforces first-person voice with named actors ("I traced the timeout to readLoop; Alice rejected the load theory"), validated on the production model class: cleaner to read back, and the agent treats recalled history as its own memory rather than a report about someone else.

Compartment titles are sanitized

Titles emitted by the historian render into the history block verbatim; a degenerate title carrying markup or control characters could distort the rendered structure. Titles are now sanitized at render time (control characters collapsed, markup escaped) in both the TypeScript and Rust renderers, and a render-epoch bump re-renders any cached history containing an unsanitized title once, cache-neutrally.

Pi

  • Image-only tool results no longer 400 on Anthropic. A tool result whose only content was an image (screenshot tools) could serialize to empty content after image handling and be rejected by Anthropic. Those results now carry an [image stripped] placeholder.
  • Status/progress notices remain display-only under the stricter delivery path shipped in v0.32.0; a residual leak through the fallback renderer on older Pi versions was closed.

TUI, notifications, and RPC

  • Dialogs no longer vanish across restarts. The notification protocol now resets its cursor on reconnect handshake and acknowledges by exact ID — previously a restart could mark undelivered dialogs (upgrade prompts, warnings) as consumed.
  • Upgrade-skew compatibility both directions. A newer TUI can discover an older server and an older TUI no longer 401-loops against a newer server (one-release auth bridge, negotiated legacy mode).
  • Sidebar no longer zeroes out under DB contention. A busy database during a snapshot read returned an all-zero snapshot that purged the TUI's cache; it now returns an error envelope and the sidebar keeps its last good state.
  • Fixed a WebSocket sink leak on re-hello (lost TUI actions), a reconnect loop against dead endpoints, port-file collisions between instances, and cross-session cursor pruning.

Smart notes

  • Sandbox and egress hardening: the file denylist re-checks canonical paths (symlink bypass closed), FIFO/special files can no longer wedge the check mutex, note transitions are CAS-guarded against concurrent evaluators, and IPv6 egress is denied entirely (closes a NAT64/Pref64 literal-IP bypass) while dual-stack hosts keep IPv4 reachability.

Storage and CLI

  • Concurrent startup is clean. Multiple instances booting at once could collide on schema migrations (SQLITE_BUSY); migrations now take immediate transactions with proper backoff (migration v51), and session deletion no longer leaks a bookkeeping row.
  • The CLI can't eat your config. A malformed JSONC config now aborts the write path instead of being replaced with defaults; doctor opens the shared database read-only so a newer schema can never be tripped by an older CLI; issue-report sanitization enforces its size cap post-condition.
  • Background maintenance lanes (search indexing, session backfill) no longer block the event loop on large sessions and recover cleanly from partial failures.

Dashboard

  • The cache page's session list filtering fix (managed-session detection across Claude Code / Codex stores) rides the next dashboard release.

Under the hood

  • The Rust module lane (runs under the subconscious daemon; not part of the npm packages) moved to the subc wire-v2 protocol, gained a durable command ledger for idempotent reduction commands, hardened its MCP facade memory operations and historian producer validation, and its shadow-mode dev lane — off by default — now pages large cold-start seeds, bounds its work queues, and rides the shared subc client (fixes a memory-growth path when the daemon stalls).