NanoClaw
NanoClaw routes command denials through the channel that owns delivery
NanoClaw proposes sending command-gate denials through the delivery adapter instead of writing around it to an outbound database. Two companion changes bound WhatsApp setup when a logged-out session stalls startup and forward gateway environment into spawned MCP servers.
nanocoai/nanoclaw PR #3192 is the inspected primary source: “fix: route command-gate denials through the delivery adapter, not outbound.db.” The related records below were inspected as supporting context rather than independent confirmation.
The facts
- nanocoai/nanoclaw PR #3192 was created 2026-08-05T23:10:48Z and was open at inspection; its title is “fix: route command-gate denials through the delivery adapter, not outbound.db.” - nanocoai/nanoclaw PR #3191 was created 2026-08-05T16:27:17Z and was open at inspection; its title is “fix(whatsapp): bound setup() to a timeout so a logged-out session can't hang host startup.” - nanocoai/nanoclaw PR #3188 was created 2026-08-05T13:04:56Z and was open at inspection; its title is “fix(container): forward OneCLI gateway env to spawned MCP servers.” - The repository reported 30445 stars, 870 open issues, default branch main, and last push 2026-08-05T18:03:11Z. - The latest tagged-release baseline checked was v2.1.54 published 2026-08-01T20:46:31Z.
What changed
nanocoai/nanoclaw PR #3192 reports: writeOutboundDirect() (command-gate denial notices) had the host INSERT rows into a session's outbound.db — a second writer on a container-owned database that this repo's own invariants (docs/db.md single-writer rule, the session-manager.ts header) treat as a corruption risk. Its seq allocation (MAX(seq)+2 from messages_out alone) could also collide with both the container's odd namespace and the inbound even namespace under UNIQUE(seq) + INSERT OR IGNORE — silently dropping the denial, so a user who was refused an admin command saw nothing at all. This PR routes denial notices through the live ChannelDeliveryAdapter instead — the same path normal outbound delivery takes: **Exact-instance dispatch.** The origin messaging group's instance rides the deliver call, so a named-instance channel (e.g. a second Slack app in one workspace) never replies through its default sibling bot. A replyTo redirect that only changes the thread keeps the origin instance; a genuinely different target resolves its own messaging-group
nanocoai/nanoclaw PR #3191 reports: Summary ChannelAdapter.setup() in src/channels/whatsapp.ts awaits an unbounded Promise for Baileys' first connection: open event. If the linked WhatsApp session is logged out and nobody is present to re-scan a QR/pairing code, that event never fires — and it isn't a close/loggedOut event either, so the existing reject path never triggers. Since initChannelAdapters() (src/channels/channel-registry.ts) awaits each channel adapter's setup() sequentially before moving to the next, a stuck WhatsApp setup() blocks **every other channel** and all post-init host work (delivery poll, host sweep, scheduled tasks) indefinitely, with nothing logged to explain why. Observed in the wild: a logged-out WhatsApp session stalled an entire host for ~57 minutes after a VPS restart, with no channel delivering and no scheduled tasks firing, before the cause was tracked down. Fix Race the first-open wait against a 45s timeout in adapter.setup(). If the timeout fires first, resolve anyway (with a warn log) and let the socket
nanocoai/nanoclaw PR #3188 reports: What MCP servers spawned as stdio child processes (via add_mcp_server or container.json directly) start with a bare environment — @modelcontextprotocol/sdk's getDefaultEnvironment() only carries HOME/LOGNAME/PATH/SHELL/TERM/USER. They never see the HTTPS_PROXY/CA-trust vars the host injects at the container level for OneCLI's credential gateway (onecli.applyContainerConfig() in src/container-runner.ts). This forwards those gateway vars into each spawned server's own env (explicit config wins on collision). Why Without this, a "onecli-managed" placeholder in a third-party MCP server's env just gets sent to the origin API literally — the gateway never sees the request to rewrite it. The only way to actually authenticate such a server today is a raw API key embedded in plaintext in container.json, which defeats the point of the OneCLI vault model. Closes #2636. How it works New container/agent-runner/src/mcp-gateway-env.ts: withGatewayEnv(env) merges a fixed allowlist of proxy/CA env keys (HTTPS_PROXY, NODE_EXTRA_CA_CERTS, NODE_USE_ENV_PROXY, etc.) from process.env into a server's own env, with the server's explicit
Why it matters
Policy outcomes still need the normal delivery contract. Bypassing the adapter can lose routing, acknowledgement or channel semantics precisely when an operator needs to understand why work did not run. The operator test is whether persisted state, execution authority and the visible outcome describe the same event after retries, restarts or delegation.
Current
The primary record was open when captured on 2026-08-06. The release baseline was v2.1.54 published 2026-08-01T20:46:31Z. Repository metadata, pull requests, issues, release records, Google News discovery, Hacker News discovery, Lobsters, Metamesh and the rendered ClawCharts row were checked. ClawCharts selected the subject; it did not prove the claim.
Evidence
The primary URL is https://github.com/nanocoai/nanoclaw/pull/3192. Supporting records are https://github.com/nanocoai/nanoclaw/pull/3191 and https://github.com/nanocoai/nanoclaw/pull/3188. Source bodies, timestamps and states are preserved in the daily evidence bundle. Test counts, reproductions and deployment observations remain attributed to their authors unless explicitly identified as independently rerun.
Source boundary
Open work is described as open, closed work as closed, and operator reports as reports. A pull request is evidence of proposed or reviewed direction, not proof of a shipped release. Search residue, package mirrors and historically published source spines were excluded.
Operator take
Keep denials on the same bounded delivery path as ordinary outcomes, timeout channel setup, and pass only the explicit environment needed by child MCP servers. Preserve a before-state receipt, make the smallest reversible change, and verify the original failure independently after intervention.
Caveat
Public project records are mutable. Status, scope and evidence can change after publication. This brief records the inspected state and does not authorize changes to a reader’s deployment.
Source inspected; source state, environment and release boundary remain explicit.