Back to Freedom.Tech Back
All NanoClaw releasesAll versions
Release Mon, Aug 24, 2026 8 min read

NanoClaw 2.3.0

Original release notes
  • [BREAKING] A new Slack experience - per-agent provisioned Slack apps, agent spawning from Slack, and UX improvements - is available to classic single-bot Slack installs. Classic Slack keeps working unchanged; this gate asks for a decision, not a forced migration. New installs and non-Slack installs are unaffected. Migration: run /migrate-slack-agents - it detects classic state (exits cleanly otherwise) and either walks the upgrade or records the choice to stay on classic; both outcomes satisfy this requirement.
  • /add-codex now pins @openai/codex 0.146.0. The previous pin (0.138.0) defaults to GPT-5.4, which OpenAI retires from Codex on 2026-08-31 - codex-provider agents ride the CLI default model, so stock installs stop completing turns at retirement - and it rejects the newer GPT-5.6 models with a 400 asking for a newer Codex CLI. Existing codex installs are not re-pinned by re-running /add-codex (the manifest merge is keyed on package name): edit the @openai/codex entry in container/cli-tools.json to 0.146.0, rebuild the agent image (./container/build.sh), and restart.
  • [BREAKING] Agent mailbox access now goes through storage-neutral host and runner registries. The built-in SQLite implementation preserves existing session data and runtime behavior, but custom source may need to replace raw session-database access, await mailbox writes, update moved runner state/heartbeat helpers, drop DeliveryActionHandler's database argument, use booleans for trigger/onWake, and use the closed inbound-kind set. Migration: follow the agent mailbox seam migration guide for the complete detect grep, oldnew symbol map, verification, and rollback.
  • Scheduled-task lifecycle semantics are stricter. Deleting an isolated task cascades its session state, updates refuse already-due runs, recurring selection uses the active series snapshot, and generated task timestamps retain millisecond precision.
  • [BREAKING] The container runtime moves behind the session driver seam. Session containers are composed as a validated, admission-checked spec and realized by a selectable driver (src/drivers/; Docker ships built-in and stays the default). Three surfaces break: (1) group folder names align to the runtime label grammar - at most 63 characters of [A-Za-z0-9_-], alphanumeric at both ends - so previously-legal 64-character names, trailing -/_, and unvalidated legacy imports refuse to spawn; (2) container names and invocation change from nanoclaw-v2-<folder>-<timestamp> to key-derived ncl-... names (the old human-readable name survives as the nanoclaw-container-name label) and from docker run to create + start --attach - name-based tooling, Docker-command allowlists, wrappers, and audit rules should match by label instead (docker ps --filter label=nanoclaw-session, or --filter label=nanoclaw-group-folder=<folder>); (3) internal container helpers moved into the driver module - customized installs importing hostGatewayArgs, readonlyMountArgs, stopContainer, ensureContainerRuntimeRunning, cleanupOrphans, or patching buildContainerArgs stop compiling. The use-native-credential-proxy skill is retired: the spec's admission rules refuse credential values in container env on every lane, by design - credentials ride the OneCLI vault, and custom Anthropic endpoints use the ANTHROPIC_BASE_URL + placeholder-token pattern from setup. Migration: run bun scripts/detect-driver-migration.ts - it detects all three surfaces in your install and prints one finding per line with a minimal fix instruction; hand the output to your coding agent. Nothing detected means nothing to do.
  • Host restarts now adopt running sessions instead of restarting them. A service restart no longer kills in-flight agent work; to apply image or runtime changes to a group, restart it deliberately with ncl groups restart. Pre-seam containers (spawned before this release) cannot be adopted and are removed at first upgraded startup, exactly as the old startup cleanup did.
  • Container gateway wiring is typed and admission-checked. The gateway's per-session contribution (proxy env, trust anchors, credential-stub mounts) merges into the session spec before validation instead of riding raw docker flags around it, and gateway selection becomes a registry (NANOCLAW_GATEWAY_PROVIDER, default onecli - an install that never sets it behaves as it always has).
  • Non-root hosts get an explicit container identity. Every non-root host now passes --user <uid>:<gid> and HOME=/home/node (previously uid-1000 hosts relied on the image's node user). On uid-1000 systems whose primary gid is not 1000, files the agent writes into mounted workspaces now carry the host's gid - which is the intended behavior.
  • CONTAINER_MEMORY_LIMIT is validated at spawn. Invalid values refuse the spawn with a named error instead of surfacing as a raw Docker error; blank and 0 still mean uncapped.
  • An unknown NANOCLAW_RUNTIME_DRIVER aborts startup (new variable - installs that never set it are unaffected), and drivers that cannot rebuild images in place deny install_packages and --rebuild at request time instead of failing later.
  • [BREAKING] The host runtime now requires Node.js 22 or newer. Node 20 is not supported by the upgraded better-sqlite3 release used for current Node runtimes. Migration: run bash setup/install-node.sh, verify node --version reports v22 or newer, then rerun /update-nanoclaw; stay on the previous NanoClaw release if Node cannot yet be upgraded.
  • New NanoClaw installs now use OneCLI gateway 1.41.0. Existing 1.36.0 gateways remain compatible because NanoClaw does not depend on any 1.41-only behavior. See the OneCLI upgrade guide to upgrade an existing gateway.
  • [BREAKING] Central database access is now asynchronous behind DbDriver. SQLite remains the default and existing data/v2.db files are unchanged, but custom source and installed channel/provider extensions must await central reads and writes and adopt the retyped host seams. Migration: follow the central database async migration guide to find affected calls, preserve transaction boundaries, update extensions, verify SQLite behavior, or roll back.
  • Central DB composition and migrations are backend-ready. A one-slot driver registry keeps backend selection in src/db/compose.ts; pnpm run migrate is the explicit schema-change path, host validation can fail closed without DDL, and a shared conformance suite pins transaction, parameter, ordering, and timestamp behavior. SQLite remains the installed default.

New Contributors

  • @teran13 made their first contribution in https://github.com/nanocoai/nanoclaw/pull/3230
  • @brentkearney made their first contribution in https://github.com/nanocoai/nanoclaw/pull/3210

Contributors

Thanks to everyone who landed work in this release:

  • ci: let verify-agent-image run on every PR so it can gate by @gavrielc in https://github.com/nanocoai/nanoclaw/pull/3238
  • ci: open the agent-image bump PR from a dispatch by @gavrielc in https://github.com/nanocoai/nanoclaw/pull/3240
  • verify-agent-image: pin the publisher identity, and check attestations per arch by @gavrielc in https://github.com/nanocoai/nanoclaw/pull/3158
  • ci: let a verified signature be the approving review by @gavrielc in https://github.com/nanocoai/nanoclaw/pull/3241
  • verify-agent-image: arming auto-merge is not a verdict by @gavrielc in https://github.com/nanocoai/nanoclaw/pull/3243
  • fix(poll-loop): stopped loops leaked their active query's follow-up poller by @gavrielc in https://github.com/nanocoai/nanoclaw/pull/3268
  • engine: bump OneCLI gateway pin to 1.41.0 by @amit-shafnir in https://github.com/nanocoai/nanoclaw/pull/3277
  • Permissions: registerChannelCardInterceptor seam before registration cards (A4) by @gavrielc in https://github.com/nanocoai/nanoclaw/pull/3266
  • Agent-to-agent: CreateAgentOptions.suppressCreatedNotify (A3) by @gavrielc in https://github.com/nanocoai/nanoclaw/pull/3265
  • Delivery: registerDeliveryBatchPreview hook over each undelivered batch (A2) by @gavrielc in https://github.com/nanocoai/nanoclaw/pull/3264
  • Channel registry: hot-start a registered adapter after boot (A1) by @gavrielc in https://github.com/nanocoai/nanoclaw/pull/3263
  • channels: Chat SDK bridge agent-mode DM surface - app-context capture, DM-thread normalization, dm-opened hook (A8 + C4) by @gavrielc in https://github.com/nanocoai/nanoclaw/pull/3262
  • channels: optional adapter capabilities - status-bearing setTyping, setThreadTitle, setSuggestedPrompts + registry passthroughs by @gavrielc in https://github.com/nanocoai/nanoclaw/pull/3261
  • permissions: 'decline_notify' unknown-sender policy - polite decline + one-line owner FYI, no approval card by @gavrielc in https://github.com/nanocoai/nanoclaw/pull/3260
  • setup/tooling: skill-apply heading-ordinal strip, headless browser URL surfacing, inherit-script extraction by @gavrielc in https://github.com/nanocoai/nanoclaw/pull/3259
  • container: mid-turn streaming is the single delivery door - cross-segment assembly, DB-backed echo suppression, no result-door sends by @gavrielc in https://github.com/nanocoai/nanoclaw/pull/3284
  • Preserve structured chat links by @Koshkoshinsk in https://github.com/nanocoai/nanoclaw/pull/3283
  • fix: idle container with no heartbeat file is exempt from the absolute-ceiling kill forever by @gavrielc in https://github.com/nanocoai/nanoclaw/pull/3252
  • fix(skills): stop removal docs pointing at the retired data/env mirror by @teran13 in https://github.com/nanocoai/nanoclaw/pull/3230
  • docs(container): tell the agent where received attachments land by @brentkearney in https://github.com/nanocoai/nanoclaw/pull/3210
  • fix(container): bump pnpm and npm past fixable-critical tar CVE by @gabi-simons in https://github.com/nanocoai/nanoclaw/pull/3207
  • Add AnyDoc document conversion skill by @amit-shafnir in https://github.com/nanocoai/nanoclaw/pull/3198
  • Cross-session context for multi-session agent groups (batching, delivery-resolution, and detached-state prerequisites included) by @gavrielc in https://github.com/nanocoai/nanoclaw/pull/3285
  • channels: generic membership-event hook on the Chat SDK bridge by @gavrielc in https://github.com/nanocoai/nanoclaw/pull/3295
  • agent-runner: extendTool - additive MCP tool schema and description extension by @gavrielc in https://github.com/nanocoai/nanoclaw/pull/3296
  • delivery: post-delivery hook with first-delivery context by @gavrielc in https://github.com/nanocoai/nanoclaw/pull/3294
  • router: session-created hook for brand-new engaged sessions by @gavrielc in https://github.com/nanocoai/nanoclaw/pull/3293
  • setup: per-channel pre-step and companion-skill declarations for the wizard by @gavrielc in https://github.com/nanocoai/nanoclaw/pull/3297
  • channels: bridge inbound-policy registration seam by @gavrielc in https://github.com/nanocoai/nanoclaw/pull/3292
  • channels: adapter-declared session-mode context defaults (threads stamp derived) by @gavrielc in https://github.com/nanocoai/nanoclaw/pull/3304
  • fix(update): make NanoClaw upgrades transactional by @glifocat in https://github.com/nanocoai/nanoclaw/pull/3195
  • cross-session context: extend new-session backfill to group conversations by @gavrielc in https://github.com/nanocoai/nanoclaw/pull/3312
  • skills: channel welcome addenda, matched host-side (zero cost when absent) by @gavrielc in https://github.com/nanocoai/nanoclaw/pull/3313
  • setup: optional automatic Slack app provisioning behind an opt-in flag by @gavrielc in https://github.com/nanocoai/nanoclaw/pull/3314
  • Fix Telegram skill copy list by @Koshkoshinsk in https://github.com/nanocoai/nanoclaw/pull/3316
  • ci: add zvi-fried to core team roster by @gabi-simons in https://github.com/nanocoai/nanoclaw/pull/3348
  • drivers: a session-runtime driver seam, with Docker as the built-in realization by @gavrielc in https://github.com/nanocoai/nanoclaw/pull/3306
  • host: route session lifecycle through the driver seam by @gavrielc in https://github.com/nanocoai/nanoclaw/pull/3307
  • groups: refuse to create a group over a folder that already exists undisposed by @gavrielc in https://github.com/nanocoai/nanoclaw/pull/3308
  • refactor(db): prepare the central database for portable drivers by @moshe-nanoco in https://github.com/nanocoai/nanoclaw/pull/3332
  • refactor(db): add async central database seam by @moshe-nanoco in https://github.com/nanocoai/nanoclaw/pull/3333
  • [BREAKING] refactor(db): adopt async central database safely by @moshe-nanoco in https://github.com/nanocoai/nanoclaw/pull/3334
  • refactor(db): add backend composition and portable tests by @moshe-nanoco in https://github.com/nanocoai/nanoclaw/pull/3335
  • fix setup ping folder compatibility by @amit-shafnir in https://github.com/nanocoai/nanoclaw/pull/3350
  • docs(telegram): document approved group connection flow by @amit-shafnir in https://github.com/nanocoai/nanoclaw/pull/3352
  • setup: --slack-agents installs the whole Slack agents feature by @Koshkoshinsk in https://github.com/nanocoai/nanoclaw/pull/3357
  • fix(setup): fail closed when a stored sign-in cannot be verified by @gavrielc in https://github.com/nanocoai/nanoclaw/pull/3339
  • feat(setup): forward optional client metadata on Slack service requests by @gavrielc in https://github.com/nanocoai/nanoclaw/pull/3345
  • fix(approvals): record the delivering instance on pending_approvals by @gavrielc in https://github.com/nanocoai/nanoclaw/pull/3340
  • fix: support current Node runtimes by @Koshkoshinsk in https://github.com/nanocoai/nanoclaw/pull/3360
  • fix: expose decline notification overrides by @Koshkoshinsk in https://github.com/nanocoai/nanoclaw/pull/3361
  • feat(cli): accept bounded JSON from stdin by @zvi-fried in https://github.com/nanocoai/nanoclaw/pull/3218