---
title: "0.25.2"
description: "SQLite-default pluggable backends with backend-aware reads, migration-marker authority, time-travel crash recovery and rewind safety, Gateway root routing, CLI self-healing skill installs, plus scheduler, sandbox, Pi, and security hardening."
---

Smithers 0.25.2 makes the pluggable storage backend safe to default. SQLite is the default backend again and every CLI read is backend-aware, so PGlite and Postgres runs are no longer invisible to `ps`, `inspect`, and `output`. The release also lands time-travel crash recovery, a batch of scheduler and sandbox correctness fixes, and several security hardening changes.

---

## Pluggable database backends

The default storage backend is SQLite again, and reads are backend-aware. Earlier the CLI resolved reads through bun:sqlite only, so runs written to a PGlite or Postgres store were invisible: `ps` returned an empty list, `inspect` reported `NOT_FOUND`, and `output` found nothing even though the run had executed. Backend resolution now flows through the same factory for writes and reads, so a run is visible from whichever backend actually holds it.

The `.smithers/migrated.json` marker is now authoritative for which backend a workspace uses, and an atomic-publish overwrite guard keeps a concurrent migration or publish from clobbering a store mid-write.

The `SMITHERS_MIGRATION_REQUIRED` remediation hint now tells operators to run `migrate --to <backend>` with the backend they actually want, instead of a generic message.

Legacy column migrations now skip tables that do not exist instead of failing the whole migration when an older store is missing a table the migration expected.

## Time travel

Smithers now recovers crash-interrupted rewinds at startup. If a process dies mid-rewind, the next start finishes or rolls back the partial jump instead of leaving the run wedged between frames.

Rewind refuses to act on a run that is still driven by a live process, so you cannot rewind a run out from under a running engine. Pass `force: true` to `jumpToFrame` to override the live-run guard when you know the driver is gone.

Forking and replaying no longer resurrect discarded state: snapshots and VCS tags are truncated together with their frames, so a fork from a checkpoint cannot pull back rows or worktree tags that a later rewind had already discarded.

## Gateway and server

The Gateway root path now routes to the console or the landing page instead of returning a bare response, so opening the gateway URL in a browser lands somewhere useful.

## CLI

`init` auto-detects and self-heals stale or retired agent skill installs, so an old or renamed skill on disk is repaired rather than left to fail silently.

`init` now notes smithers-workflow guidance in an existing `CLAUDE.md` or `AGENTS.md` so agents working in the repo learn how to drive Smithers.

Workflow skill discovery prints next-step guidance after it finishes, so operators know what to run next without consulting docs.

Cancel is now durable for live runs, and JSON argument parsing can no longer fall through to a wrong interpretation when an argument looks ambiguous.

A malformed workflow file is now skipped with a warning instead of hiding every other workflow in the directory.

## Scheduler

Failures inside a still-running action or `try` subtree are now recorded, so compensation and `catch` handlers run instead of being skipped when the subtree had not finished.

The `decide()` depth guard now scales with task count instead of a constant of 10, so large workflows are no longer cut off by the recursion guard.

## Sandbox

Cancelling a sandboxed run now kills the process group immediately instead of letting it run to its timeout.

## Pi plugin

The Pi plugin includes the full Smithers docs only on demand instead of shipping them on every launch.

In-flight RPCs are now rejected on a clean WebSocket close so `streamDevTools` reconnects cleanly instead of hanging on stale promises.

## Security and redaction

`smithers gateway` now requires auth before it will bind to a non-loopback host, closing an unauthenticated bind to `0.0.0.0`.

The Electric proxy fails closed on shapes that have no row-level scoping, so an unscoped shape cannot leak rows across tenants.

Observability redaction now catches hyphenated OpenAI and Anthropic keys and env-style dumps, so secrets are scrubbed from logs and traces in more shapes.

## Other correctness fixes

- Review records real Anthropic spend even when a single call crosses the spend cap, so accounting stays accurate at the boundary.
- The eval query and SQL verifier no longer substring-matches scalar answers, so a partial string match cannot mark a wrong answer correct.
- OpenAPI tool generation preserves free-form object request bodies instead of stripping them to `{}`.
- DevTools no longer duplicates a node that was reparented into a re-added subtree.
- The control plane reserves the `__org__` id, self-heals its migration, and upserts secrets atomically.

## CI

Coverage reporting runs in its own parallel CI job, keeping the main test gate fast.

## Migration notes

No breaking changes are identified in 0.25.2.

The default backend is SQLite. Workspaces that already migrated to PGlite or Postgres keep using that backend through their `.smithers/migrated.json` marker, which is now the authority for backend selection. Reads are backend-aware, so no action is needed for existing PGlite or Postgres runs to become visible to `ps`, `inspect`, and `output`.

Operators running `smithers gateway` on a non-loopback host must configure auth. An unauthenticated non-loopback bind is now refused.
