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. Passforce: 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 ortry 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 sostreamDevTools 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.