Ctrl K
ComunidadGuías…

RELEASE_NOTES.md

Rama dev · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# NetClaw Release Notes

## 0.28.3 (2026-11-07)

This is a stable patch release for 0.28.2. The daemon now redacts secrets in every log record. Notification webhook URLs move to `secrets.json`. The default output limit no longer shrinks after a session holds an image. A scripted uninstall for Linux, macOS, and Windows is new.

**Upgrade impact:** none for the database. 0.28.3 uses the same database format as 0.28.0, 0.28.1, and 0.28.2. The config format stays valid, and `netclaw doctor --fix` converts the old webhook list shape. Five behaviors change:

- A daemon log record that spans several lines now starts each line after the first with two spaces. Other control characters in a record show as `\uXXXX`.
- The daemon log no longer holds the ASP.NET "Request starting" and "Request finished" lines.
- `netclaw daemon install` refuses a path that holds whitespace, a quote, a backslash, or `%`. It also refuses a home that differs from the home of the installed systemd unit.
- `netclaw approvals <unknown>` now exits with code `1`.
- A webhook with no URL stops daemon startup.

### Security

- **Notification webhook URLs and auth header values live in `secrets.json`, encrypted.** A webhook URL can be a credential, and the TUI wrote it to `netclaw.json` in plain text. `Notifications:Webhooks` is now an object keyed by webhook name. The TUI writes only the `Format` to `netclaw.json` and writes the URL and header values to `secrets.json`. The old list shape and a plain `Url` in `netclaw.json` still load. `netclaw doctor` warns about them, and `netclaw doctor --fix` backs up `netclaw.json` and `secrets.json`, converts the list, and moves the values. A webhook with no URL from any source now stops daemon startup and names the key ([#2777](https://github.com/netclaw-dev/netclaw/issues/2777)).
- **The daemon redacts and frames every log record.** Before, only 14 of about 200 exception-bearing log calls redacted secrets, and framework log lines had no redaction. Now one stage, `RedactingLoggerFactory`, creates each logger of the daemon: `ILogger<T>`, Akka, ASP.NET, `HttpClient`, and SDKs. The stage redacts the message, the structured values, the scope values, and the exception of each record once. The OTLP export receives the redacted text.
  - Each line break becomes the platform newline. Each line after the first starts with two spaces, so log content cannot forge a record header. Other control characters and bidi controls show as `\uXXXX`.
  - `session.log` is redacted at its one writer. A secret that spans two streamed thinking deltas can no longer escape, because the writer joins the deltas into one line.
  - The crash log, the session-dispatcher failure beacon, the CLI probe log, and the `netclaw chat -p` session log redact what they write.
  - The memory recall plan log now lists only the words that survive redaction of their source text. Before, it listed words cut from a secret, such as `hunter2`.
  - See `docs/architecture/text-safety.md` for the owner and the rule of each text sink ([#2766](https://github.com/netclaw-dev/netclaw/pull/2766)).
- **A log record no longer shows a secret that a line break or a message template hid.** Three gaps stayed open after the redaction stage. The log now masks a value on the line after `KEY=`. It masks the signature of a presigned URL (`X-Amz-Signature`, `X-Goog-Signature`, `Signature`, and `sig`). It masks a value that only its message template marks as a secret, such as `Authorization: Bearer {Token}`. The new rules apply to log sinks only, so tool output keeps the shared rules and a presigned URL still reaches the model intact. The log no longer masks the `authorizationAttemptId` value by mistake ([#2789](https://github.com/netclaw-dev/netclaw/pull/2789), fixes [#2770](https://github.com/netclaw-dev/netclaw/issues/2770)).
- **Request query strings stay out of the daemon log.** ASP.NET logged each request URL with its query string. The log held the OAuth callback code and state, the SignalR connection token, and a local path from the shutdown request. The OTLP exporter sent these values off the machine. Now `ConfigureNetclawLogging` sets the category `Microsoft.AspNetCore.Hosting.Diagnostics` to `Warning` for every provider. The log loses the "Request starting" and "Request finished" lines. An explicit provider-specific setting can show them again ([#2745](https://github.com/netclaw-dev/netclaw/pull/2745)).
- **An MCP argument shows as an escaped string when `System.Uri` throws.** On .NET 10, `Uri.TryCreate` threw `IndexOutOfRangeException` for some short values, and the approval display failed. Now the display catches the exception and shows the value as an escaped string. It does not drop the value, and it does not show the value raw ([#2787](https://github.com/netclaw-dev/netclaw/pull/2787), fixes [#2771](https://github.com/netclaw-dev/netclaw/issues/2771)).

### Models

- **The output limit no longer shrinks with an estimate of the prompt.** 0.28.2 clamped the default output limit per call to the context window minus a character-based prompt estimate, with a floor of 1024. The estimate counted an inline image at its base64 size, so one generated image (about 1 MB) added about 330,000 phantom tokens, and every later call in that session was sent `max_tokens: 1024` and failed with "The model reply was truncated". Now the default is still 32000, capped to the known model maximum (hosted APIs) and to a quarter of the known context window, which is static and fits below the 75% compaction threshold. A self-hosted server with an unknown window still gets no limit field, and a configured or call-site value is sent as is. The 1024 floor and its warning are gone. A prompt that still overflows is rejected by the provider, and the session compacts and retries.

### Skills

- **`netclaw skill show` and `netclaw skill remove` read the daemon registry.** Before, `skill show` reported "not found" for every skill from a skill feed. The CLI scanned the disk and could not see feed skills. Now both commands ask the daemon (`GET /api/skills/{name}`), and the endpoint requires authorization. `skill remove` refuses a `system`, `server-feed`, or `external` skill, so it cannot delete a managed feed directory. `skill search` and `skill issues` now see feed skills. A skill version can come from the top-level `version:` key or from `metadata.version`, and the top-level key wins ([#2734](https://github.com/netclaw-dev/netclaw/pull/2734), fixes [#2728](https://github.com/netclaw-dev/netclaw/issues/2728)).

### MCP

- **`netclaw mcp auth` finds OAuth metadata for an issuer that has a path.** Netclaw appended `/.well-known/oauth-authorization-server` to the issuer URL. RFC 8414 puts that segment between the host and the issuer path. The official GitHub MCP server failed with `HTTP 404 NotFound`. Now Netclaw tries the RFC 8414 URL first and the appended URL second. When both fail, the error names both URLs. An issuer with no path still uses one URL. GitHub publishes no `registration_endpoint`, so register a GitHub OAuth App and run `netclaw mcp add` with `--client-id` and `--client-secret` ([#2738](https://github.com/netclaw-dev/netclaw/pull/2738), fixes [#2737](https://github.com/netclaw-dev/netclaw/issues/2737)).
- **The CLI shows how to fix a failed client registration.** Before, `netclaw mcp auth` printed only "Check daemon logs for details". Now the error names the authorization server and the remedy: run `netclaw mcp add` again with `--client-id <id>`, and add `--client-secret <secret>` when the provider issued a secret. Other exception text stays out of the response, because it can hold provider data ([#2741](https://github.com/netclaw-dev/netclaw/pull/2741), fixes [#2740](https://github.com/netclaw-dev/netclaw/issues/2740)).

### Configuration

- **The daemon applies a `netclaw.json` edit that arrives early.** An edit could arrive after the configuration load and before the watcher started, and the daemon never applied it. Now `ConfigWatcherActor` owns the file events and one 500 ms debounce timer. It starts the watcher before it compares the file with the loaded hash. It validates the config before it calls the restart coordinator. A secret-only event starts no reload ([#2713](https://github.com/netclaw-dev/netclaw/pull/2713), fixes [#2485](https://github.com/netclaw-dev/netclaw/issues/2485)).
- **`netclaw doctor` accepts the empty values that the loader ignores.** The config schema rejected `null`, `""`, `[]`, and `{}` in `ToolOverrides`, `McpServerDefaults`, and the lists that the loader defaults. These lists are `AllowedTools`, `AllowedMcpServers`, the `Roots` lists, `ChannelAttachments.AllowedCategories`, `GlobalReadRoots`, and `WebFetch.HttpAllowList`. So doctor failed a healthy file. Now the schema accepts these values. Doctor repeats the loader warning for a `null` or `{}` grant list. An unknown mode, or a scalar where a list belongs, still fails. An unmatched schema branch of a valid list no longer hides real errors ([#2757](https://github.com/netclaw-dev/netclaw/pull/2757), fixes [#2756](https://github.com/netclaw-dev/netclaw/issues/2756)).
- **The daemon reports an unwritable shell temp directory.** At startup the daemon probes the per-user base folder (`/tmp/netclaw-<uid>`) with the checks of the shell launch. When the probe fails, the daemon logs an error that names the path and the fix. `/api/health/status` and `netclaw status` run the probe again for each request, and they report a degraded `Shell/temp` connector. `/api/health/ready` does not change, so Docker health stays green. Windows has no such folder and skips the probe ([#2759](https://github.com/netclaw-dev/netclaw/pull/2759), fixes [#2758](https://github.com/netclaw-dev/netclaw/issues/2758)).
- **Startup skill scan warnings reach the log.** The warnings "Skill inventory is degraded at startup" and "Rejected skill item during startup scan" used a logger with no provider. They reached neither the console nor `daemon-*.log`. Now the `Netclaw.Startup` logger writes them. The skill-feed sync can log the same problem again about 200 ms later ([#2763](https://github.com/netclaw-dev/netclaw/pull/2763), fixes [#2760](https://github.com/netclaw-dev/netclaw/issues/2760)).

### CLI/TUI

- **A scripted uninstall exists for Linux, macOS, and Windows.** `scripts/uninstall.sh` and `scripts/uninstall.ps1` reverse the writes of the installers ([#2690](https://github.com/netclaw-dev/netclaw/pull/2690)).
  - Both scripts stop the daemon first and fail on a timeout. They remove the binaries, the `.backup` files, and the daemon env file. They keep the data directory unless you pass `--purge` (`-Purge` on Windows).
  - `uninstall.sh` also removes the systemd user service, the POSIX env script, and the shell profile block. `uninstall.ps1` also removes the User PATH entry and keeps its registry value kind.
  - `--dry-run`, `--yes`, and `--skip-shell` (`-DryRun`, `-Yes`, and `-SkipShell` on Windows) preview the work, confirm a purge, and keep the shell profile.
  - A script refuses to run from inside the install directory. It refuses `--purge` without `--yes` when stdin is redirected. It exits `0` when NetClaw is already gone.
  - Exit codes: `0` done, `1` the daemon did not stop and nothing was deleted, `2` invalid arguments, `3` purge refused in a non-interactive session, `4` run from inside the install directory.
  - The scripts do not remove a macOS LaunchAgent or a Windows service, because the installers create neither.
- **`netclaw approvals <unknown>` exits with code `1`.** Before, an unknown subcommand printed the usage text to stdout and exited with code `0`. Now it prints an error and the usage text to stderr and exits with code `1`. When the CLI cannot resolve the local daemon address, `netclaw daemon status` prints one message. The message gives the process state, the PID, the uptime, the failing file and its fix, and says that readiness was not checked ([#2755](https://github.com/netclaw-dev/netclaw/pull/2755), fixes [#2754](https://github.com/netclaw-dev/netclaw/issues/2754)).
- **`netclaw daemon install` makes the systemd unit serve a custom home.** Now the command always writes `Environment=NETCLAW_HOME=<home>` to the unit. Before it writes anything, it refuses a home, binary path, or `daemon.env` path that holds whitespace, a quote, a backslash, or `%`, because the unit holds these paths unquoted. One unit exists for each user. `install` and `uninstall` refuse when the unit serves a different home, and they name that home. Start and stop read the home from the unit file. Drop-ins from `systemctl --user edit` are not read ([#2774](https://github.com/netclaw-dev/netclaw/pull/2774), fixes [#2773](https://github.com/netclaw-dev/netclaw/issues/2773)).
- **`netclaw doctor` reads the active daemon log on Windows.** The Memory Curation LLM check failed with "being used by another process". It opened the log with a sharing mode that denied the write handle of the daemon. Now it opens the log with read-write sharing. A Windows user no longer sees a false `[FAIL]` and exit code `1` while the daemon runs ([#2786](https://github.com/netclaw-dev/netclaw/pull/2786), fixes [#2704](https://github.com/netclaw-dev/netclaw/issues/2704)).

### Channels

- **A shell approval note shows outside the command code span.** The grant-scope and near-miss notes joined the command text, and every channel wraps that text in one code span. Mattermost showed a stray backtick and a literal `**Pattern:**`. Now the notes travel in a separate optional `Notes` field, and the hub carries it as `SessionOutputDto.InteractionNotes`. An older client sees no notes.
  - Mattermost and Discord show the command in its own code span, and the notes as plain lines below it.
  - Slack shows the notes in a plain section after the command block.
  - The TUI shows the notes beside the command. Headless output prints a separate `[approval:note]` line.
  - Approval matching does not change ([#2748](https://github.com/netclaw-dev/netclaw/pull/2748), fixes [#2746](https://github.com/netclaw-dev/netclaw/issues/2746)).
- **The bot's own messages count as filtered, not dropped.** The Slack, Discord, and Mattermost conversation actors ran the ACL gate before the bot filter. An echo of a bot reply counted as `dropped`. Now the bot check runs first and counts the message as `filtered` with the reason `bot_message`. The set of processed messages does not change ([#2743](https://github.com/netclaw-dev/netclaw/pull/2743), fixes [#2742](https://github.com/netclaw-dev/netclaw/issues/2742)).

### Dependency Updates

- **CommunityToolkit.Aspire.Hosting.Ollama 13.6.1.** The package moves from 13.5.0 ([#2721](https://github.com/netclaw-dev/netclaw/pull/2721)).

## 0.28.2 (2026-10-28)

This is a stable patch release for 0.28.0. A model definition now carries a provider-neutral output limit and thinking level, so an Anthropic reply is no longer cut at 1024 tokens. The daemon rotates its log into bounded numbered segments. The CLI refuses to send local control traffic to a guessed address when the configuration cannot be read.

**Upgrade impact:** none. 0.28.2 uses the same database format as 0.28.0 and 0.28.1, and it changes no configuration format. Three behaviors change: a turn that keeps failing through different tools now stops, `netclaw doctor --json` writes only JSON to stdout, and `Logs:Days` now also prunes numbered daemon log segments.

### Models

- **A model definition has a provider-neutral output limit and thinking level.** `netclaw model set` gets `--max-output-tokens`, `--clear-max-output-tokens`, `--thinking <off|low|medium|high|max>`, and `--clear-thinking`. `netclaw model list` and the TUI role table show "Max out" and "Thinking". `P` in `netclaw model` edits both values. Netclaw maps them to the switch of each provider.
  - Netclaw rejects a level that the provider dialect or the model does not offer, and lists the offered levels. It never sends a nearby level.
  - An `openai-compatible` provider needs `Providers:<name>:VendorOptions:ThinkingDialect` (`ChatTemplateKwargs`, `ReasoningEffort`, `DeepSeek`, or `None`) before it can send a level. `model set` saves `ReasoningEffort` when it detects llama.cpp.
  - **Behavior change:** without a configured value, a hosted API now receives an output limit of 32000 tokens, capped to its known model maximum and clamped to its known context window. Anthropic replies are no longer cut at 1024 tokens. The cost per call can increase. A self-hosted server receives 32000 clamped to its context window only when that window is known from `ContextWindow` or from the server's own probe; otherwise the request has no limit field, as before.
  - A hand-edited level that the provider dialect cannot send now fails startup and `netclaw doctor`, and so does a level other than `off` on an Ollama provider with `DisableThinking`.
- **Each model definition resolves its capabilities against its own provider.** Before, the capability chain used the Main provider's endpoint for every role.
- **A fallback model no longer receives the request fields of a failed candidate.** Each failover candidate gets its own copy of the request options ([#2681](https://github.com/netclaw-dev/netclaw/issues/2681)).

### Security

- **An unreadable local configuration no longer leaves the CLI to guess a daemon address.** Before, a config that failed to load fell back to the default local daemon address, so a lifecycle command could send local control traffic to a destination that no configuration named. Now the CLI reports an unknown address before it creates the local control transport, and it skips the shutdown notice and the readiness probe. An explicit remote endpoint still takes precedence for a remote operation, and the existing process identity proof still governs a stop signal ([#2726](https://github.com/netclaw-dev/netclaw/pull/2726), fixes [#2476](https://github.com/netclaw-dev/netclaw/issues/2476)).
- **A bounded glob that crosses a contained directory alias can use an existing grant.** Before, a directory alias anywhere in a bounded glob asked for exact consent, so an ordinary repository-listing command could not use a folder or repository grant that already covered it. Now the glob resolves each known alias target with the same filesystem authority rules, and the grant applies only when it covers the authored scope and every target scope. A walk that is incomplete, external, cyclic, broken, or uninspectable stays unresolved, so it still asks. The target check also compares the authored pattern and each target's remaining pattern against protected paths, so a protected path that a lexical check hid is now refused ([#2716](https://github.com/netclaw-dev/netclaw/pull/2716), [#2718](https://github.com/netclaw-dev/netclaw/pull/2718)).

### Sessions

- **The loop guard counts failed calls, not only repeated actions.** The guard keyed on the tool name and the arguments hash, so a model that rotated tools never repeated a key and a model that hit one error through several tools stayed invisible to it. Now a second axis counts failed calls and resets the count when a batch holds one success. The model receives a nudge that names the repeated cause and its fix, in the parent session and in a child run ([#2710](https://github.com/netclaw-dev/netclaw/pull/2710), fixes [#2706](https://github.com/netclaw-dev/netclaw/issues/2706)).

### Configuration

- **The daemon log rotates into bounded numbered segments.** `~/.netclaw/logs/daemon-{yyyy-MM-dd}.log` stops at 10 MiB, and the writer continues in `daemon-{yyyy-MM-dd}.1.log`, then `.2.log`, and further numbered files. A restart appends to the first segment below the threshold, and a new UTC date starts a new series. `netclaw doctor` and the eval tools read every segment. **Upgrade impact:** `Logs:Days` now prunes those numbered segments as well as the daily file and `crash-*.log`, judged by the date in the file name. The newest 3 daemon logs and the newest 3 crash logs are still always kept ([#2712](https://github.com/netclaw-dev/netclaw/pull/2712)).

### CLI/TUI

- **`netclaw daemon help` exits successfully.** `netclaw daemon help`, `--help`, and `-h` print the usage text and exit with code `0`, so a script that asks for help no longer reads it as a failure. An unknown subcommand still exits non-zero. Help does not control the daemon or change a service file ([#2709](https://github.com/netclaw-dev/netclaw/pull/2709)).
- **`netclaw doctor --json` writes only JSON to stdout.** Before, a repair notice could join the JSON document and break a caller that parses stdout. The notice now goes to stderr ([#2711](https://github.com/netclaw-dev/netclaw/pull/2711)).

### Bug Fixes

- **A tool call that misspells a required key in another form resolves again.** A model that writes `rationale` or another variation instead of `_rationale` no longer fails the call. The argument resolver gains the entries that the timeout key already had ([#2705](https://github.com/netclaw-dev/netclaw/pull/2705)).

### Dependency Updates

- **Anthropic 13.3.0.** The provider SDK moves from 12.50.0 to 13.3.0 ([#2697](https://github.com/netclaw-dev/netclaw/pull/2697)).
- **Termina 0.17.1.** The terminal library moves from 0.17.0 ([#2708](https://github.com/netclaw-dev/netclaw/pull/2708)).
- **ShellSyntaxTree 0.5.0-beta.2.** The parser that proves a launch-variable glob moves from 0.5.0-beta.1, and its bounded handle-glob rules back the alias walk above ([#2718](https://github.com/netclaw-dev/netclaw/pull/2718)).
- **Discord.Net 3.20.2.** The Discord client library moves from 3.20.1 ([#2723](https://github.com/netclaw-dev/netclaw/pull/2723)).

## 0.28.1 (2026-10-26)

This is a stable patch release for 0.28.0. Compaction and child agents on the Compaction role now fail over to the Fallback model. A child reply that stops at the output limit now keeps its full text as a partial artifact.

**Upgrade impact:** none. 0.28.1 uses the same database format as 0.28.0.

### Fixes

- **Each model role fails over to the Fallback model, Compaction included.** Before, a configured Compaction model had no failover, so session compaction and each child agent on the default `modelRole: Compaction` never used the Fallback model. Now the candidate list of each role ends with the Fallback model when one is configured. When Compaction names the same model as Main, or is not configured, it uses the Main list ([#2691](https://github.com/netclaw-dev/netclaw/pull/2691), fixes [#2688](https://github.com/netclaw-dev/netclaw/issues/2688)).
- **A cut-off child reply keeps its full text.** When the final reply of a child stops at the output limit with text and no tool call, the run still fails with `output_truncated`. Now the runtime also writes the full cut-off text, redacted, to `artifacts/truncated-output.md`, and `result.md` names that path. Before, only a 300-character preview remained. A reply with only thinking writes no artifact ([#2682](https://github.com/netclaw-dev/netclaw/pull/2682), fixes [#2679](https://github.com/netclaw-dev/netclaw/issues/2679)).
  - The `agent-coordination` skill (1.5.3) tells the parent to read that file with `file_read`. The text is partial data from the child, and the parent must not follow instructions in it. The `subagent-authoring` skill (1.6.2) names the partial artifact.

## 0.28.0 (2026-10-25)

This is the stable 0.28.0 release. It collects 0.28.0-beta.1 to 0.28.0-beta.4 for users who upgrade from 0.27.1. Sub-agents now run in the background, and a child that waits for consent parks and survives a restart. A message from a person reaches the agent sooner, also during an automation turn. The daemon logs each tool call again with redacted arguments, and an OAuth refresh no longer restarts the daemon. Agent tools can no longer reach credential folders such as `~/.ssh` and `~/.aws`.

> **Caution: read these items before you upgrade from 0.27.1.**
> - **Forward-only.** After the upgrade, never start 0.27.1 or older on the database. 0.27.1 reads the child notice rows wrongly. It replays a notice as user input, and it can deliver a child result a second time. Older binaries also cannot read parked child runs, drain parks, or `ContinuationAuthorized` records. Before you go back to 0.27.1, also delete each `Providers.<name>.OAuthTokenExpiry` from `secrets.json`.
> - **Upgrade while idle.** Upgrade when no child agent runs and no turn is active. 0.27.1 keeps an active child, and a message that waits behind it, only in memory. A 0.27.1 stop loses them, and 0.28.0 cannot recover them.
> - **Security posture.** 0.28.0 denies `shell_execute` for a config with no `Security.DeploymentPosture`, because that config gets the strict Public posture. 0.27.1 asked for approval. `netclaw init` writes the key. For a hand-written or very old config, set `Security.DeploymentPosture` (for example `Personal`), and run `netclaw doctor` before you upgrade. Doctor reports "Security section missing" for such a config.
> - **Restart reminder IDs.** A reminder import file that has a `restart-resume-` ID now fails. Remove those entries from the file.
>
> Use these steps to make the backup and to roll back:
> 1. Before you upgrade, stop the daemon: `netclaw daemon stop`.
> 2. Copy the database: `cp ~/.netclaw/netclaw.db ~/.netclaw/netclaw.db.bak.$(date +%s)`.
> 3. To roll back, stop the daemon, restore that copy, and then start the older binary. A restore loses the journal records that the new release wrote after the backup.

The beta sections below give each change in full detail.

### Sub-agents

- **A child runs in the background.** `spawn_agent` returns a run ID at once. When the child ends, the parent gets one notice in a later turn and reads `result.md` with `file_read` ([#2464](https://github.com/netclaw-dev/netclaw/pull/2464), [#2467](https://github.com/netclaw-dev/netclaw/pull/2467), [#2515](https://github.com/netclaw-dev/netclaw/pull/2515)).
  - **Upgrade impact:** upgrade the CLI with the daemon. While a child run is open, `netclaw chat -p` waits and prints `[subagent:waiting]` (no line with `--json`). It exits 0 after the first turn that leaves no child open. A failed turn, a stopped session, or a lost connection ends it with exit 1 and names the open runs. A 0.27.1 CLI exits at turn 1 against this daemon and never prints the child result. The notice turn still runs in the daemon, and `result.md` stays in the run folder.
- **A child that waits for consent parks.** The parent gets a notice and pauses. After the last answer, the child runs only the parked calls, each one time, and the gate checks each call again. The park is in the run record, so it survives a restart, a config reload, a compaction, and passivation ([#2583](https://github.com/netclaw-dev/netclaw/pull/2583), [#2618](https://github.com/netclaw-dev/netclaw/pull/2618), [#2670](https://github.com/netclaw-dev/netclaw/pull/2670)).
- **A child that runs during a graceful restart parks and resumes after the restart.** A child that does not park in time ends as `owner_restarted`, and its tools do not run again ([#2604](https://github.com/netclaw-dev/netclaw/pull/2604), [#2672](https://github.com/netclaw-dev/netclaw/pull/2672)).
  - **Upgrade impact:** a graceful restart with an active child can take up to about 18 seconds longer.
- **Child prompts close cleanly.** Each channel redraws a prompt that nothing can answer, with no buttons and with the reason. A text answer does not resolve a child prompt ([#2584](https://github.com/netclaw-dev/netclaw/pull/2584), [#2676](https://github.com/netclaw-dev/netclaw/pull/2676)).
  - **Upgrade impact:** a Mattermost binding with no `CallbackUrl` refuses child consent requests.
- **Child control is clearer.** Status and cancel check only the requester. A reminder turn and an approval notice turn can manage the child runs of their own session. A notice turn handles only its notice ([#2504](https://github.com/netclaw-dev/netclaw/pull/2504), [#2550](https://github.com/netclaw-dev/netclaw/pull/2550), [#2617](https://github.com/netclaw-dev/netclaw/pull/2617), [#2657](https://github.com/netclaw-dev/netclaw/pull/2657)).
- **Child failures are honest.** A cut-off child reply fails with `output_truncated`, and a call that streams only thinking past its cap fails with `thinking_only_timeout` ([#2502](https://github.com/netclaw-dev/netclaw/pull/2502)). The parent keeps a productive child ([#2666](https://github.com/netclaw-dev/netclaw/pull/2666)). The `spawn_agent` template includes `_rationale` ([#2606](https://github.com/netclaw-dev/netclaw/pull/2606)).
- **Sub-agent profiles no longer set `timeoutSeconds`.** A profile that sets it still loads, with one warning. Each child now waits 600 seconds for a silent stream ([#2503](https://github.com/netclaw-dev/netclaw/pull/2503)).

### Sessions

- **A message from a person reaches the agent sooner.** A message joins the active turn of the same person. During a reminder, job, webhook, or approval-notice turn, a message from the operator or a trusted person ends that turn after its current tool batch. The model then gets a short stop note ([#2505](https://github.com/netclaw-dev/netclaw/pull/2505), [#2607](https://github.com/netclaw-dev/netclaw/pull/2607), [#2630](https://github.com/netclaw-dev/netclaw/pull/2630), [#2677](https://github.com/netclaw-dev/netclaw/pull/2677)).
  - **Upgrade impact:** when a person interrupts a reminder turn, the reminder records success and does not run the rest of its steps.
- **Restarts lose less work.** A restart drain stops a tool loop at a safe point and tells the user. A restart resumes a turn that stopped after its first tool batch. An expired restart reminder closes the stopped work with one notice ([#2608](https://github.com/netclaw-dev/netclaw/pull/2608), [#2651](https://github.com/netclaw-dev/netclaw/pull/2651), [#2676](https://github.com/netclaw-dev/netclaw/pull/2676)).
- **Queued input runs correctly.** A slash command from the input queue runs as a command and gets one acknowledgement. A restart or a rejected slash command starts the inputs behind it. A damaged input no longer stops a restart resume ([#2592](https://github.com/netclaw-dev/netclaw/pull/2592), [#2613](https://github.com/netclaw-dev/netclaw/pull/2613), [#2615](https://github.com/netclaw-dev/netclaw/pull/2615), [#2663](https://github.com/netclaw-dev/netclaw/pull/2663)).
- **A SQLite lock wait no longer stops a session.** The journal write timeout is now the SQLite `Default Timeout` plus 10 seconds. A failed save during a turn posts an error ([#2569](https://github.com/netclaw-dev/netclaw/pull/2569)).
- **Repeated or cut-off model output is handled.** A repeated refused call gets a nudge, not a turn failure. A cut-off reply fails the turn ([#2466](https://github.com/netclaw-dev/netclaw/pull/2466), [#2502](https://github.com/netclaw-dev/netclaw/pull/2502), [#2553](https://github.com/netclaw-dev/netclaw/pull/2553)).
  - **Upgrade impact:** `Session.MaxToolIterationsPerTurn` no longer limits a turn.
- **After a person denies a call, the agent stops and asks** ([#2616](https://github.com/netclaw-dev/netclaw/pull/2616)).

### Reminders

- **Interval reminders shorter than 61 minutes run again.** A run with a denied tool is recorded as `denied` ([#2402](https://github.com/netclaw-dev/netclaw/pull/2402)).
  - **Upgrade impact:** `netclaw reminder list` prints a table. Use `--json` for the old output.
- **A one-shot reminder deletes itself after it ends.** Its history stays for 12 days ([#2533](https://github.com/netclaw-dev/netclaw/pull/2533)).
- **A `current_session` reminder ends when the session admits the fire.** A failed reply post sends a `reminder.delivery.failed` alert ([#2511](https://github.com/netclaw-dev/netclaw/pull/2511), [#2537](https://github.com/netclaw-dev/netclaw/pull/2537)).
- **Reminder sessions resume after a restart**, and a one-shot occurrence has a delivery window of 7 days ([#2491](https://github.com/netclaw-dev/netclaw/pull/2491), [#2438](https://github.com/netclaw-dev/netclaw/pull/2438)).
- **Restart reminder IDs are reserved for the system** ([#2676](https://github.com/netclaw-dev/netclaw/pull/2676)).

### Security

- **Agent tools cannot reach credential locations,** such as `~/.ssh`, `~/.aws`, `~/.kube`, `~/.netrc`, and `~/.docker/config.json` ([#2405](https://github.com/netclaw-dev/netclaw/pull/2405)).
- **The daemon checks `Host` and `Origin` on loopback requests** ([#2530](https://github.com/netclaw-dev/netclaw/pull/2530)).
  - **Upgrade impact:** call the daemon as `http://127.0.0.1:<port>` or `http://localhost:<port>`. A browser app on another local port gets 401.
- **Tool access follows the effective posture audience** for a turn and its sub-agents ([#2619](https://github.com/netclaw-dev/netclaw/pull/2619)).
  - **Upgrade impact:** under a posture that is narrower than the source audience, a reminder from before the upgrade can have the Personal audience. `run_reminder` then refuses it. Create the reminder again from a chat.
- **Provider OAuth token reads require a local-control proof** ([#2621](https://github.com/netclaw-dev/netclaw/pull/2621)).
- **Approval override keys with no value are ignored** ([#2622](https://github.com/netclaw-dev/netclaw/pull/2622)).
  - **Upgrade impact:** `netclaw doctor` reports a `ToolOverrides` or `McpServerDefaults` key with a colon as an error. Remove it by hand. The tool returns to the audience default, so it can ask for approval again.
- **TUI commands no longer write a trace file** ([#2620](https://github.com/netclaw-dev/netclaw/pull/2620)).
  - **Upgrade impact:** delete each old `netclaw-*-trace.log` file from the system temp folder.
- **Personal file reads reach as far as Personal writes,** and the private temp folder is short ([#2559](https://github.com/netclaw-dev/netclaw/pull/2559)).
- **Shell approval judges more commands correctly** ([#2372](https://github.com/netclaw-dev/netclaw/pull/2372), [#2373](https://github.com/netclaw-dev/netclaw/pull/2373), [#2374](https://github.com/netclaw-dev/netclaw/pull/2374), [#2377](https://github.com/netclaw-dev/netclaw/pull/2377), [#2378](https://github.com/netclaw-dev/netclaw/pull/2378), [#2379](https://github.com/netclaw-dev/netclaw/pull/2379), [#2380](https://github.com/netclaw-dev/netclaw/pull/2380), [#2381](https://github.com/netclaw-dev/netclaw/pull/2381), [#2382](https://github.com/netclaw-dev/netclaw/pull/2382), [#2563](https://github.com/netclaw-dev/netclaw/pull/2563), [#2665](https://github.com/netclaw-dev/netclaw/pull/2665)).
- **The output redactor finds more secrets and runs in linear time** ([#2401](https://github.com/netclaw-dev/netclaw/pull/2401), [#2463](https://github.com/netclaw-dev/netclaw/pull/2463), [#2605](https://github.com/netclaw-dev/netclaw/pull/2605)).

### Configuration

- **The OAuth token expiry moves to `secrets.json`,** so a refresh no longer restarts the daemon ([#2529](https://github.com/netclaw-dev/netclaw/pull/2529)).
  - **Upgrade impact:** run `netclaw doctor --fix` to move an old `OAuthTokenExpiry` key from `netclaw.json`.
- **The daemon deletes old logs.** It deletes daemon and crash logs older than `Retention.Logs.Days` (default 14). Set the value in `netclaw config` or with `netclaw config retention` ([#2401](https://github.com/netclaw-dev/netclaw/pull/2401), [#2412](https://github.com/netclaw-dev/netclaw/pull/2412), [#2417](https://github.com/netclaw-dev/netclaw/pull/2417)).
  - **Upgrade impact:** to keep all logs, set `Retention.Logs.Days` to `0` before you upgrade.
- **Invalid model or provider configuration stops startup with one clear message,** and `netclaw doctor --fix` deletes less ([#2399](https://github.com/netclaw-dev/netclaw/pull/2399), [#2404](https://github.com/netclaw-dev/netclaw/pull/2404), [#2531](https://github.com/netclaw-dev/netclaw/pull/2531)).

### Channels, tools, memory, and providers

- **A channel keeps its output route until its session stops** ([#2429](https://github.com/netclaw-dev/netclaw/pull/2429)).
- **A large tool result keeps its tail,** and the full text stays readable with `tool_output_read` ([#2414](https://github.com/netclaw-dev/netclaw/pull/2414), [#2425](https://github.com/netclaw-dev/netclaw/pull/2425), [#2430](https://github.com/netclaw-dev/netclaw/pull/2430)).
- **`search_tools` ranks its results,** and the agent prefers a built-in tool to a `netclaw` CLI command ([#2385](https://github.com/netclaw-dev/netclaw/pull/2385)).
- **Memory fixes.** `update_memory` writes a new embedding. A same-name rewrite no longer adds a duplicate. Recall reports a coverage gap only for documents. Curation uses the Main model ([#2395](https://github.com/netclaw-dev/netclaw/pull/2395), [#2431](https://github.com/netclaw-dev/netclaw/pull/2431), [#2664](https://github.com/netclaw-dev/netclaw/pull/2664), [#2669](https://github.com/netclaw-dev/netclaw/pull/2669)).
- **Provider fixes.** Codex refreshes its token after an HTTP 401. A rejected OpenAI refresh sends the re-auth alert. Stream retry and failover work on Responses-based providers ([#2298](https://github.com/netclaw-dev/netclaw/pull/2298), [#2432](https://github.com/netclaw-dev/netclaw/pull/2432), [#2568](https://github.com/netclaw-dev/netclaw/pull/2568)).

### Telemetry

- **The tool call log line is back, with redaction,** and `session.log` redacts tool arguments too ([#2600](https://github.com/netclaw-dev/netclaw/pull/2600), [#2605](https://github.com/netclaw-dev/netclaw/pull/2605), [#2609](https://github.com/netclaw-dev/netclaw/pull/2609)).
- **Expected outcomes no longer write an Error log.** A call that needs approval, a policy denial, and a correction request stay on the authorization log. A real tool failure still writes an Error entry ([#2649](https://github.com/netclaw-dev/netclaw/pull/2649), [#2683](https://github.com/netclaw-dev/netclaw/pull/2683)).

### CLI/TUI

- **`netclaw chat -p` exits 1 when the turn fails,** and `netclaw daemon status` exits 1 when the daemon does not run ([#2400](https://github.com/netclaw-dev/netclaw/pull/2400), [#2409](https://github.com/netclaw-dev/netclaw/pull/2409), [#2517](https://github.com/netclaw-dev/netclaw/pull/2517)).
  - **Upgrade impact:** update scripts that read these exit codes.
- **Chat input is confirmed after the daemon saves it,** and a message can be up to 512 KB ([#2426](https://github.com/netclaw-dev/netclaw/pull/2426), [#2487](https://github.com/netclaw-dev/netclaw/pull/2487), [#2668](https://github.com/netclaw-dev/netclaw/pull/2668)).
  - **Upgrade impact:** update the CLI and the daemon together.
- **MCP, provider, and model commands are safer.** They keep and clean up server state, check names and endpoints, and show the OAuth redirect URI. C clears the highlighted role in the model manager ([#2390](https://github.com/netclaw-dev/netclaw/pull/2390), [#2394](https://github.com/netclaw-dev/netclaw/pull/2394), [#2403](https://github.com/netclaw-dev/netclaw/pull/2403), [#2462](https://github.com/netclaw-dev/netclaw/pull/2462), [#2610](https://github.com/netclaw-dev/netclaw/pull/2610), [#2667](https://github.com/netclaw-dev/netclaw/pull/2667)).
- **A bad `netclaw.json` gives one error line,** and messages name real commands ([#2391](https://github.com/netclaw-dev/netclaw/pull/2391), [#2459](https://github.com/netclaw-dev/netclaw/pull/2459)).

### Daemon and install

- **`netclaw daemon stop` stops only the daemon of its own home** ([#2544](https://github.com/netclaw-dev/netclaw/pull/2544)).
- **Install scripts use `NETCLAW_HOME`,** and `daemon.env` keeps operator lines ([#2528](https://github.com/netclaw-dev/netclaw/pull/2528)).
- **An update check timeout no longer stops the daemon** ([#2538](https://github.com/netclaw-dev/netclaw/pull/2538)).

### Dependency Updates

- **Bump ShellSyntaxTree** — 0.4.0-beta.22 → 0.5.0-beta.1 ([#2372](https://github.com/netclaw-dev/netclaw/pull/2372), [#2660](https://github.com/netclaw-dev/netclaw/pull/2660), [#2665](https://github.com/netclaw-dev/netclaw/pull/2665))
- **Bump OpenTelemetry** — 1.19.1 → 1.20.1 ([#2518](https://github.com/netclaw-dev/netclaw/pull/2518), [#2577](https://github.com/netclaw-dev/netclaw/pull/2577))
- **Bump ASP.NET Core packages** — 10.0.12 → 10.0.13 ([#2490](https://github.com/netclaw-dev/netclaw/pull/2490))
- **Bump Termina** — 0.16.2 → 0.17.0 ([#2410](https://github.com/netclaw-dev/netclaw/pull/2410), [#2465](https://github.com/netclaw-dev/netclaw/pull/2465), [#2520](https://github.com/netclaw-dev/netclaw/pull/2520))
- **Bump Aaron.Akka.Reminders** — 0.7.0 → 1.5.73.3 ([#2402](https://github.com/netclaw-dev/netclaw/pull/2402), [#2438](https://github.com/netclaw-dev/netclaw/pull/2438))
- **Bump Aspire.Hosting.AppHost** — 13.5.4 → 13.6.3 ([#2579](https://github.com/netclaw-dev/netclaw/pull/2579))

## 0.28.0-beta.4 (2026-10-25)

Follow-up beta to 0.28.0-beta.3. A child that runs during a graceful restart now parks, and it resumes after the restart. An expired restart reminder closes the stopped work with one notice. When a person ends an automation turn, the model gets a short stop note.

> **Caution: this release is forward-only.**
> - 0.28.0-beta.3 cannot recover a session in which a child parked at a graceful restart (a park with no consent requests). The beta.3 replay rejects the park, or the resumed child fails.
> - 0.28.0-beta.3 cannot recover a session that holds the new `ContinuationAuthorized` record until a snapshot replaces that record.
> - If 0.28.0-beta.3 starts while a restart expiry signal waits, beta.3 treats the signal as a normal reminder fire and runs one automation turn.
> - Never start 0.27.1 or older on a database that 0.28.0-beta.1 or newer wrote. 0.27.1 reads the child notice rows wrongly. It replays a notice as user input, and it can deliver a child result a second time.
> - To roll back, you must have the backup from before this upgrade. To roll back to 0.27.1, you must have the backup from before the first 0.28 beta upgrade.
>
> Use these steps to make the backup and to roll back:
> 1. Before you upgrade, stop the daemon: `netclaw daemon stop`.
> 2. Copy the database: `cp ~/.netclaw/netclaw.db ~/.netclaw/netclaw.db.bak.$(date +%s)`.
> 3. To roll back, stop the daemon, restore that copy, and then start the older binary. A restore loses the journal records that the new release wrote after the backup.

### Sub-agents

- **A child that runs during a graceful restart parks and resumes after the restart.** Before, a graceful restart ended each active child run as `owner_restarted`. Now the restart drain tells each live child to park. A child in a tool batch parks when the batch ends. A child that waits for a model reply cancels that call and parks at once. After the restart, the child resumes under the authority of the person who started it ([#2672](https://github.com/netclaw-dev/netclaw/pull/2672)).
  - The session writes the park to the run record before the drain ends. The park uses the same record as a consent park, with no consent requests.
  - A child that does not park in time ends as `owner_restarted`, and a tool that was still active never runs again. The session logs `Restart drain child_wait_ended live_children={N}`.
  - When Netclaw refuses a drain park, the run ends as a restart loss: `owner_restarted`, with the changed files of the park, and "effects uncertain" ([#2672](https://github.com/netclaw-dev/netclaw/pull/2672), [#2676](https://github.com/netclaw-dev/netclaw/pull/2676)).
  - A park that does not agree with its answers ends with `park_damaged` and an Error log.
  - **Upgrade impact:** a graceful restart with an active child can take up to about 18 seconds longer. This change is forward-only. Read the caution at the top of this section.
- **A late click after a failed resume gets the withdrawal reason.** Before, the click got "already answered" ([#2676](https://github.com/netclaw-dev/netclaw/pull/2676)).

### Sessions

- **An expired restart reminder closes the stopped work with one notice.** When a restart reminder expires before it runs, the daemon sends an expiry signal at startup. The session closes the held continuation, and a person input that the drain stopped at its first model call. It resumes nothing, and the person gets one short notice ([#2676](https://github.com/netclaw-dev/netclaw/pull/2676)).
  - An expired continuation never cancels a durable child park.
  - While a parent approval is open, the signal closes nothing and the session logs `restart_expired_skipped`. A second delivery of the signal closes nothing.
  - A restart reminder must stay valid for 1 minute after its fire time. Otherwise startup sends the expiry signal.
- **A held continuation runs only with a fresh restart reminder.** After the last consent answer, a held automation continuation runs only when a fresh restart reminder authorized it. Otherwise the continuation closes, and the person gets the restart notice one time. A new `ContinuationAuthorized` journal record keeps that authorization across passivation ([#2676](https://github.com/netclaw-dev/netclaw/pull/2676)).
- **A continuation input has an explicit marker.** Thus Netclaw never reads an empty input from a person as a continuation ([#2676](https://github.com/netclaw-dev/netclaw/pull/2676)).
- **The model gets a stop note when a person ends an automation turn.** The first turn of the person holds one fixed note: "The automated turn above stopped unfinished because a person sent a message. Answer the person's message first, and do not resume the stopped work in this reply unless the person asks for it." Later turns do not get the note ([#2677](https://github.com/netclaw-dev/netclaw/pull/2677)).
- **A due compaction runs where a person ends an automation turn.** The compaction runs before the first model call of the person. After a compaction, the session also ends an automation turn when a person waits. A stop never closes an input that no model request carried ([#2677](https://github.com/netclaw-dev/netclaw/pull/2677)).

### Reminders

- **Restart reminder IDs are reserved for the system.** The reminder manager refuses a `restart-resume-` ID from any creator other than the system. `/api/reminders/import` refuses that prefix with HTTP 400 ([#2676](https://github.com/netclaw-dev/netclaw/pull/2676)).
  - **Upgrade impact:** an import file that has a `restart-resume-` ID now fails. Remove those entries from the file.

### Internal

- Test reliability for the chat close expiry scenario, the notice order test, and the redactor time guard ([#2673](https://github.com/netclaw-dev/netclaw/pull/2673), [#2674](https://github.com/netclaw-dev/netclaw/pull/2674), [#2675](https://github.com/netclaw-dev/netclaw/pull/2675)).

## 0.28.0-beta.3 (2026-10-24)

Follow-up beta to 0.28.0-beta.2. A child that waits for operator consent now parks, and the park survives a daemon restart. A restart also resumes a turn that the restart drain stopped in a tool loop. Memory recall and memory curation get two fixes.

> **Caution: this release is forward-only.**
> - When this release writes a parked child run to a session journal, 0.28.0-beta.2 and older cannot recover that session. To roll back, you must have a backup from before this upgrade.
> - Never start 0.27.1 or older on a database that 0.28.0-beta.1 or newer wrote. 0.27.1 reads the child notice rows wrongly. It replays a notice as user input, and it can deliver a child result a second time. To roll back to 0.27.1, you must have the backup from before the first 0.28 beta upgrade.
>
> Use these steps to make the backup and to roll back:
> 1. Before you upgrade, stop the daemon: `netclaw daemon stop`.
> 2. Copy the database: `cp ~/.netclaw/netclaw.db ~/.netclaw/netclaw.db.bak.$(date +%s)`.
> 3. To roll back, stop the daemon, restore that copy, and then start the older binary. A restore loses the journal records that the new release wrote after the backup.

### Sub-agents

- **A child that waits for consent parks, and the park survives a restart.** When a child call needs operator consent, the child parks. The other calls of its batch end first. The session writes the park and its consent requests to the run record in one journal write. After the last answer, the child resumes and runs only the parked calls, each one time. The approval gate checks each parked call again under the current policy ([#2618](https://github.com/netclaw-dev/netclaw/pull/2618), [#2670](https://github.com/netclaw-dev/netclaw/pull/2670)).
  - A parked run survives a daemon restart, a config reload, a compaction snapshot, and passivation. After a restart, one click resumes the parked calls one time.
  - After a restart, the requester of a parked prompt comes from the run record. Netclaw refuses a click from another person.
  - When the daemon stops after a resume starts, recovery records the run as lost. The parked calls do not run again.
  - A park larger than 4 MiB ends the run with `park_too_large`, and no prompt appears. A damaged park ends the run with `park_damaged`.
  - A cancel of a parked run ends the run at once.
  - A resumed child does not keep the deferred tools that it loaded. The child can load them again.
  - Before, a child waited live for consent, and a restart recorded the run as lost.
  - **Upgrade impact:** this change is forward-only. Read the caution at the top of this section before you upgrade.
- **A notice turn handles only its notice.** An approval notice turn cannot ask for approval. Each approval notice now ends with one rule: handle only this notice, tell the operator the next step, and end the turn. Before, the model could continue other work in the notice turn and get an `approval_required_unattended` denial ([#2657](https://github.com/netclaw-dev/netclaw/pull/2657)).
- **The parent keeps a productive child.** The `agent-coordination` guidance now says that long child runs are normal, and that a status check sets no limit on rounds. The parent cancels a child only for an operator request, for wrong work, or for no progress ([#2666](https://github.com/netclaw-dev/netclaw/pull/2666)).

### Sessions

- **A restart resumes a turn that stopped after its first tool batch.** Before, the restart drain could stop a turn in a tool loop, and no restart reminder resumed that turn. Now the session records a continuation input for the stopped turn before the restart. After the restart, the turn continues from its stored history, with the authority of that turn ([#2651](https://github.com/netclaw-dev/netclaw/pull/2651)).
  - A later input that arrives before the turn continues closes the continuation. That input runs in its own turn, and the session posts the restart notice one time.
- **A slash command from the input queue gets one acknowledgement.** Before, the sender got a second acknowledgement when the queue drained ([#2663](https://github.com/netclaw-dev/netclaw/pull/2663)).

### Security

- **Shell approval reuses a proved grant and checks compound redirects.** A Bash assignment from the launch environment now uses its proved value in the grant check, so an equal grant no longer prompts again. A changed value, or a grant with no assignment qualification, gives no authority. PowerShell still needs the authored value. A supported compound redirect now gets its own file check. A one-time shell answer applies only to the exact command text, also for a call that recovery restarts ([#2665](https://github.com/netclaw-dev/netclaw/pull/2665)).

### Memory

- **A same-name memory rewrite no longer adds a duplicate.** Before, a rewrite of a memory with the same name could skip the model decision. Curation then added a duplicate document after the overwrite guard refused the rewrite. Now the decision waits until the model resolves it ([#2669](https://github.com/netclaw-dev/netclaw/pull/2669)).
- **Recall reports a coverage gap only for documents.** Memory records have no embeddings by design. Recall no longer reports a vector coverage gap for them. The `netclaw-memory` skill explains the diagnostic correctly ([#2664](https://github.com/netclaw-dev/netclaw/pull/2664)).

### CLI/TUI

- **A cold chat start no longer blocks a second request.** The chat client now starts its runtime outside its lifetime lock. The two-second limit for quit also applies while the runtime starts ([#2668](https://github.com/netclaw-dev/netclaw/pull/2668)).
- **C clears the highlighted role in the model manager.** Before, C did nothing until you selected a row with Enter or Space. Now C clears the role of the highlighted row, and the table shows the change. A role that is not set gets a message ([#2667](https://github.com/netclaw-dev/netclaw/pull/2667)).

### Telemetry

- **A tool call that needs approval no longer writes an Error log.** Before, the daemon wrote an Error entry with a stack trace in addition to the Information audit entry. Now only the Information entry remains. A real tool failure still writes an Error entry ([#2649](https://github.com/netclaw-dev/netclaw/pull/2649)).

### Internal

- `build.ps1` now writes `VersionPrefix` and `VersionSuffix` for a prerelease ([#2645](https://github.com/netclaw-dev/netclaw/pull/2645)).
- Session outputs, tests, mutation gates, evals, and design text ([#2646](https://github.com/netclaw-dev/netclaw/pull/2646), [#2647](https://github.com/netclaw-dev/netclaw/pull/2647), [#2648](https://github.com/netclaw-dev/netclaw/pull/2648), [#2650](https://github.com/netclaw-dev/netclaw/pull/2650), [#2652](https://github.com/netclaw-dev/netclaw/pull/2652), [#2654](https://github.com/netclaw-dev/netclaw/pull/2654), [#2658](https://github.com/netclaw-dev/netclaw/pull/2658)).

### Dependency Updates

- **Bump ShellSyntaxTree** — 0.4.0-beta.24 → 0.4.0 ([#2660](https://github.com/netclaw-dev/netclaw/pull/2660)), then 0.5.0-beta.1 for the compound redirect facts ([#2665](https://github.com/netclaw-dev/netclaw/pull/2665))

## 0.28.0-beta.2 (2026-10-23)

Follow-up beta to 0.28.0-beta.1. A message from a person now ends an active automation turn, so the person no longer waits for a long reminder or job turn.

### Sessions

- **A message from a person ends an active automation turn.** A reminder, background-job result, webhook, or approval-notice turn is an automation turn. When the operator or a trusted person sends a message during such a turn, the turn ends after its current tool batch. The turn of the person then starts next, with the authority of that person. A message from an admitted `UntrustedExternal` person still waits until the automation turn ends ([#2630](https://github.com/netclaw-dev/netclaw/pull/2630)).
  - The ended turn closes quietly and posts no fallback message. The daemon logs a Warning `turn_person_input_end_at_tool_batch`.
  - Child runs that the ended turn started continue, and they report later.
  - Before, the person waited until the whole automation turn ended.
  - **Upgrade impact:** when a person interrupts a reminder turn, the reminder records success and does not run its remaining steps. If you need those steps, ask the agent to continue the work.

### Internal

- Tests for the automation turn rule, and a fix for legacy replay: a background-job close with no input IDs no longer takes a legacy child continuation ([#2631](https://github.com/netclaw-dev/netclaw/pull/2631)).

### Dependency Updates

- **Bump OpenTelemetry** — 1.20.0 → 1.20.1 ([#2577](https://github.com/netclaw-dev/netclaw/pull/2577))
- **Bump Aspire.Hosting.AppHost** — 13.5.4 → 13.6.3 ([#2579](https://github.com/netclaw-dev/netclaw/pull/2579))

## 0.28.0-beta.1 (2026-10-23)

This is the first beta of 0.28.0. A sub-agent now runs in the background: `spawn_agent` returns a run ID at once, and the result arrives in a later turn. When a child asks for operator consent, the parent gets a notice and pauses until the prompt closes. The daemon logs each tool call again with redacted arguments, and `session.log` now redacts tool arguments too. An OAuth token refresh no longer writes `netclaw.json`, so it no longer restarts the daemon. Agent tools can no longer read or write credential folders such as `~/.ssh` and `~/.aws`.

> **Downgrade note:** read these items before you go back to 0.27.1 or older.
> - Delete each `Providers.<name>.OAuthTokenExpiry` from `secrets.json`. This release writes that value as plain text, and an older daemon cannot read it ([#2529](https://github.com/netclaw-dev/netclaw/pull/2529)).
> - 0.27.1 cannot read a restart manifest that this release writes, because this release writes reminder enum names ([#2400](https://github.com/netclaw-dev/netclaw/pull/2400)).
> - A 0.27.1 daemon deletes the retained records of completed one-shot reminders, as it did before ([#2402](https://github.com/netclaw-dev/netclaw/pull/2402)).

### Configuration

- **The OAuth token expiry moves to `secrets.json`.** Before, each OAuth access-token refresh wrote the new expiry to `netclaw.json`. The config watcher then restarted the daemon, which could stop work in progress. Now Netclaw writes `Providers.<name>.OAuthTokenExpiry` to `secrets.json`, next to the tokens. That one value is not encrypted, because the config binder cannot read an encrypted date. The refresh service also never sends a spent refresh token again ([#2529](https://github.com/netclaw-dev/netclaw/pull/2529)).
  - **Upgrade impact:** an `OAuthTokenExpiry` key in `netclaw.json` is retired. It still applies until the first refresh, and the daemon logs a startup warning for it. Run `netclaw doctor --fix` to move the value to the provider entry in `secrets.json`. Doctor makes a backup before it removes the key. Doctor does not change a `netclaw.json` that has comments, so remove the key by hand in that case.
  - If the daemon stops at startup with an error that names `Providers:<name>`, run `netclaw provider` and sign in again.
  - `netclaw secrets set` now rejects an expiry that is not an ISO 8601 date.
- **Invalid model or provider configuration stops startup with one clear message.** Before, a bad `Models` section or a provider with no credential or endpoint crashed the daemon with a stack trace (exit 134). Now the daemon exits 1 with one message. A daemon that runs refuses to reload an invalid file and keeps its current configuration ([#2404](https://github.com/netclaw-dev/netclaw/pull/2404)).
  - **Upgrade impact:** a supervisor that restarts the daemon on failure shows the same message again. Fix the file, and the daemon starts.
- **`netclaw doctor --fix` deletes less.** It never removes a key under `Models` or a credential. It backs up `netclaw.json` before it removes any other key ([#2404](https://github.com/netclaw-dev/netclaw/pull/2404)). Doctor also accepts the valid `Session` keys `MaxToolDescriptionChars`, `MaxToolSchemaWarnChars`, `MemoryDistillationTurnInterval`, and `Tuning.StreamingRetryPolicy`. Before, `--fix` deleted them with no backup ([#2399](https://github.com/netclaw-dev/netclaw/pull/2399)). Doctor now reads the `Tools` and `Security` sections without regard to letter case ([#2531](https://github.com/netclaw-dev/netclaw/pull/2531)).
- **The daemon deletes old logs.** A new retention job deletes `daemon-*.log` and `crash-*.log` files older than `Retention.Logs.Days` (default 14). It runs shortly after start and then every 12 hours. It always keeps the newest three daemon logs and the newest three crash logs. The value `0` keeps all logs. Set the value on the new Data Retention page of `netclaw config`, or with `netclaw config retention --logs-days <days>` ([#2401](https://github.com/netclaw-dev/netclaw/pull/2401), [#2412](https://github.com/netclaw-dev/netclaw/pull/2412), [#2417](https://github.com/netclaw-dev/netclaw/pull/2417)).
  - **Upgrade impact:** about 30 seconds after the first start, the daemon deletes daemon and crash logs older than 14 days. To keep them, set `Retention.Logs.Days` to `0` before you upgrade.
- **`netclaw doctor` warns when a profile can write wider than it can read.** The warning names the audience profile and its two modes. It has no auto-fix ([#2559](https://github.com/netclaw-dev/netclaw/pull/2559)).

### Sessions

- **A message from a person reaches the active turn.** A child consent notice waits at the front of the input queue for its own turn. A new message from the same person now passes that notice and joins the active turn, as in 0.27.1. An earlier development build held such messages until the turn ended ([#2607](https://github.com/netclaw-dev/netclaw/pull/2607)).
- **Each input runs under the authority of its own requester.** Inputs from different people no longer share one model call. Only the same requester can join an active turn, and the turn keeps its authority. An automated input, such as a reminder or a child result, no longer closes an open approval prompt. It waits and runs as its own turn ([#2505](https://github.com/netclaw-dev/netclaw/pull/2505)).
- **A restart drain stops a tool loop and tells the user.** Before, a config restart did not stop a session in a tool loop. The drain timed out after 20 seconds, the turn stopped, and nothing told the user. Now the session stops the turn at the next safe point ([#2608](https://github.com/netclaw-dev/netclaw/pull/2608)):
  - a tool batch boundary, a prepared model request, an empty-reply retry, or the end of a compaction;
  - when the turn cannot resume, the session posts one notice in its channel. The notice says "stopping" for `netclaw daemon stop` and "restarting" for other reasons;
  - the shutdown alert names each session that timed out in `timedOutSessionIds`.
  - A tool that runs longer than the drain timeout still holds the drain.
- **A restart or a rejected slash command starts the inputs behind it.** Before, a restart that resumed a slash command, or a slash command that the session rejected, could leave other inputs with no turn. For example, a reminder fire that waited behind an approval never ran after a mistyped slash command. Now those inputs run ([#2592](https://github.com/netclaw-dev/netclaw/pull/2592)).
- **A SQLite lock wait no longer stops a session.** The journal and snapshot write timeout is now the SQLite `Default Timeout` plus 10 seconds (40 seconds by default). Before, it was 10 seconds. A slow disk write now only delays the turn. When a save fails during a turn, the session posts an error that says some actions may already have run. Before, the session stopped with no message ([#2569](https://github.com/netclaw-dev/netclaw/pull/2569)).
  - **Upgrade impact:** a SQLite connection string with `Default Timeout` of 0 or less now stops the daemon at startup, because SQLite would wait forever.
- **A repeated tool call gets a correction, not a turn failure.** After two equal rounds, Netclaw refuses the next identical call. Calls that do new work stay allowed. The model gets a nudge for refused repeats 1 to 4 and a stronger nudge for repeat 5. At repeat 6 the turn ends quietly with the text of the model. The person sees no Netclaw error ([#2466](https://github.com/netclaw-dev/netclaw/pull/2466), [#2553](https://github.com/netclaw-dev/netclaw/pull/2553)).
  - **Upgrade impact:** `Session.MaxToolIterationsPerTurn` stays valid, but it no longer limits a turn. A turn that does new work in each round can now run past 60 rounds.
- **A cut-off reply fails the turn.** When a reply stops at the output limit with no tool call, the session does not post the cut-off text. The turn ends with an error that says the reply was truncated. A model call that streams only thinking now stops after three times the no-progress timeout (60 minutes by default) ([#2502](https://github.com/netclaw-dev/netclaw/pull/2502)).
- **Provider streams retry and fail over more often.** A stream attempt now starts at its first real output, not at its first metadata update. Thus retry and failover to the fallback model work again on Responses-based providers, Codex included ([#2298](https://github.com/netclaw-dev/netclaw/pull/2298)).

- **A slash command in the input queue runs as a command.** Before, a slash command that waited behind a turn or an approval reached the model as plain text. Now the session runs it on the live command path, with the same checks ([#2613](https://github.com/netclaw-dev/netclaw/pull/2613), fixes [#2591](https://github.com/netclaw-dev/netclaw/issues/2591)).
- **A damaged input no longer stops a restart resume.** When a stored input has damaged authority, the session logs it, keeps it, and queues the valid inputs. Before, a damaged input could stop the resume halfway with an error ([#2615](https://github.com/netclaw-dev/netclaw/pull/2615), fixes [#2576](https://github.com/netclaw-dev/netclaw/issues/2576)).

### Sub-agents

- **A child runs in the background.** `spawn_agent` records the run and returns its run ID at once, so the parent stays available. When the child ends, the runtime writes `result.md` in the run folder. The parent then gets one notice in a later turn and reads the result with `file_read`. A notice runs under the authority of the person who started the child ([#2464](https://github.com/netclaw-dev/netclaw/pull/2464), [#2467](https://github.com/netclaw-dev/netclaw/pull/2467), [#2515](https://github.com/netclaw-dev/netclaw/pull/2515)).
  - **Upgrade impact:** upgrade the CLI with the daemon. While a child run is open, `netclaw chat -p` waits and prints `[subagent:waiting]` (no line with `--json`). The daemon's notice turn reads the child result. It exits 0 after the first turn that leaves no child open. A failed turn, a stopped session, or a lost connection ends it with exit 1 and names the open runs. A 0.27.1 CLI exits at turn 1 against this daemon and never prints the child result. The notice turn still runs in the daemon, and `result.md` stays in the run folder.
- **The parent gets a notice and pauses while a child waits for consent.** When a child asks for operator consent, the parent gets one notice turn. The notice lists the open child requests and the answers since the last notice. While a child request is open, the session holds reminder fires and refuses `spawn_agent`. The parent can finish its turn, and prompts from other children still post ([#2583](https://github.com/netclaw-dev/netclaw/pull/2583)).
  - **Upgrade impact:** an open child approval now holds reminder fires for that session until the prompt closes.
- **Netclaw withdraws a child prompt that nothing can answer.** Slack, Discord, Mattermost, the TUI, and headless redraw the prompt with no buttons and show the reason. A prompt closes when the parent cancels the child, the child ends or is lost, the prompt post fails, or the daemon restarts. An answered prompt shows "This approval request has an answer." While a child prompt is open, a text answer resolves nothing, and the channel asks for a button ([#2584](https://github.com/netclaw-dev/netclaw/pull/2584)).
  - **Upgrade impact:** a Mattermost binding with no `CallbackUrl` (text only) now refuses child consent requests. Set the callback URL to approve child requests in Mattermost.
- **`owner_restarted` names a child that a restart lost.** Before, recovery recorded such a run as `actor_stopped`, and the log said `success=True`. Now the reason is `owner_restarted`. The notice says that the parent session restarted and that the runtime does not start the child again. When the run had a checkpoint, the notice also says that effects after the checkpoint are uncertain. A lost run is never a success ([#2604](https://github.com/netclaw-dev/netclaw/pull/2604)).
- **The `spawn_agent` call template includes `_rationale`.** The template in the system prompt had no `_rationale`, so the model copied it, and the first `spawn_agent` call of a session often failed. Now the template ends with `_rationale` ([#2606](https://github.com/netclaw-dev/netclaw/pull/2606)).
- **Child status and cancel check only the requester.** The owner of a child no longer loses access to it in a later turn. A reminder turn can check and cancel the child runs of its own session. Any other turn of the same session can manage a child that a reminder started ([#2504](https://github.com/netclaw-dev/netclaw/pull/2504), [#2550](https://github.com/netclaw-dev/netclaw/pull/2550)).
- **A second approval answer is not called "expired".** An answer to a prompt that already has an answer grants nothing. The session posts "Approval response ignored: that approval prompt already has an answer." ([#2504](https://github.com/netclaw-dev/netclaw/pull/2504)).
- **An approval notice turn can cancel a child run of its session.** Before, a notice turn that called `check_agent_run` with `Cancel: true` for its own child got "This child run is not available to the requester." Now a notice turn can read the status of a child run of its session and cancel it. The notice turn gets no other authority, and a tool that needs consent is still denied with no prompt ([#2617](https://github.com/netclaw-dev/netclaw/pull/2617)).
- **A cut-off child reply fails the run.** A child reply that stops at the output limit with no tool call now fails with reason `output_truncated`. A child call that streams only thinking past the cap fails with `thinking_only_timeout` ([#2502](https://github.com/netclaw-dev/netclaw/pull/2502)).
- **Sub-agent profiles no longer set `timeoutSeconds`.** Each child now detects a silent stream after the session `FirstTokenTimeout` (default 600 seconds). When the loader rejects a profile file, `spawn_agent` names the file and the reason ([#2503](https://github.com/netclaw-dev/netclaw/pull/2503)).
  - **Upgrade impact:** a profile that sets `timeoutSeconds` still loads, and the daemon logs one warning for each reload. A profile that used 60 to 180 seconds now waits 600 seconds for a silent stream.
- **Recovery logs a closed child approval once.** Replay no longer writes `Tool approval requested` again for a child approval that a later record closed ([#2552](https://github.com/netclaw-dev/netclaw/pull/2552)).

- **Replay clears a noticed child run at a turn of another requester.** A notice turn that fails or crashes leaves no end record in the journal. Before, replay kept the noticed run, and a later turn of another person recorded the reminder link of that run. This affected delivery records only, not authority ([#2614](https://github.com/netclaw-dev/netclaw/pull/2614), fixes [#2574](https://github.com/netclaw-dev/netclaw/issues/2574)).

### Reminders

- **Interval reminders shorter than 61 minutes run again.** Since 0.26.0, the scheduler skipped them on each fire. After downtime, a reminder gets at most one catch-up fire. An expired retry of a recurring reminder counts as one failure, and only five failures in a row disable the reminder ([#2402](https://github.com/netclaw-dev/netclaw/pull/2402)).
- **A one-shot reminder deletes itself after it ends.** Netclaw keeps a small end record and the history for 12 days. Thus `netclaw reminder status`, `netclaw reminder history`, and `get_reminder_history` still work in that period. `cancel_reminder` and `netclaw reminder cancel` delete a one-shot. A recurring reminder is still disabled and kept. Startup cleans up leftover one-shots, so the upgrade needs no operator step ([#2533](https://github.com/netclaw-dev/netclaw/pull/2533)).
- **A run with a denied tool is recorded as `denied`.** An unattended run in which authorization denied a tool call is no longer recorded as `ok`. Netclaw does not retry it and does not count it toward auto-disable. Netclaw sends at most one `reminder.tool_denied` alert for each distinct denial ([#2402](https://github.com/netclaw-dev/netclaw/pull/2402)).
- **A `current_session` reminder ends when the session admits the fire.** The reminder system no longer waits for the post. While an earlier fire of the same reminder waits in the queue, the session drops the newer fire ([#2511](https://github.com/netclaw-dev/netclaw/pull/2511)).
  - **Upgrade impact:** the reminder system no longer retries a failed post of a `current_session` reminder. When the reply post fails for good, the session writes an Error log and sends a `reminder.delivery.failed` alert ([#2537](https://github.com/netclaw-dev/netclaw/pull/2537)).
- **A reminder session resumes after a restart.** A reminder can enter its own session again after a daemon restart, and the session resumes the interrupted input ([#2491](https://github.com/netclaw-dev/netclaw/pull/2491)).
- **A one-shot occurrence has a delivery window of 7 days.** Before, an occurrence that nothing acknowledged replayed with no end. A daemon that is offline still delivers a reminder up to a week late ([#2438](https://github.com/netclaw-dev/netclaw/pull/2438)).
- **`set_reminder` accepts more model output.** `DeliveryKind` is now a required parameter. The tool ignores blank optional fields, so a `current_session` call with empty channel fields succeeds ([#2458](https://github.com/netclaw-dev/netclaw/pull/2458)).
- **Reminder import and time zones.** `netclaw reminder import` reads what `export` writes. Netclaw validates time zones as IANA IDs. `/run-reminder` and skill bodies reach the model ([#2400](https://github.com/netclaw-dev/netclaw/pull/2400)).

### Security

- **Agent tools cannot reach credential locations.** File tools and shell commands are now denied on `~/.ssh`, `~/.aws`, `~/.gnupg`, `~/.kube`, `~/.azure`, `~/.config/gh`, `~/.config/gcloud`, `~/.docker/config.json`, `~/.netrc`, and `~/.git-credentials`. On Windows, the deny also covers the `gcloud`, `GitHub CLI`, and `gnupg` folders under `%APPDATA%`, and `%PROGRAMDATA%\ssh`. No approval, `ToolOverrides` entry, or audience profile can override this deny ([#2405](https://github.com/netclaw-dev/netclaw/pull/2405)).
  - **Upgrade impact:** commands such as `cat ~/.ssh/id_ed25519`, `ls ~/.aws`, `ssh -i ...`, and `docker run -v $HOME/.aws:...` are now denied. Commands that name no credential path still work, for example `ssh host`, `git push`, `aws s3 ls`, and `kubectl get pods`. To change these files, edit them in your own shell.
- **The daemon checks `Host` and `Origin` on loopback requests.** In `Local` exposure mode, the `Host` must be `localhost` or a loopback IP address, such as `127.0.0.1` or `[::1]`. An `Origin` header, when present, must be `http://` plus the same `Host` ([#2530](https://github.com/netclaw-dev/netclaw/pull/2530)).
  - **Upgrade impact:** a client that calls the daemon through another host name now gets 401. A browser app on another local port, for example `http://localhost:3000`, also gets 401. Call the daemon as `http://127.0.0.1:<port>` or `http://localhost:<port>`. For a web app, make the call from its server process, or pair the app with `netclaw daemon pair` and send the device token.
- **Personal file reads reach as far as Personal writes.** For the Personal audience, `file_read`, `file_list`, `file_search`, and `attach_file` now reach at least as far as the write profile. Thus the agent can read the files that its shell writes, for example in `/tmp`. Protected paths stay denied. Team and Public do not change ([#2559](https://github.com/netclaw-dev/netclaw/pull/2559)).
  - **Upgrade impact:** a host with Personal `ReadFiles.Mode = Roots` and a wider `WriteFiles` gets wider Personal reads. Unattended Personal runs, such as reminders and webhooks, get the same reach with no prompt. Run `netclaw doctor` to see the profiles.
- **The private temp folder is short.** On Linux and macOS, the temp folder of a run is now `/tmp/netclaw-<uid>/<key>/p` (or `c<id>` for a child). Netclaw creates it with mode 0700 and refuses a shell launch when the owner, mode, or a link is wrong. A short path keeps Unix socket paths, such as the Chrome socket, under their length limit. Windows does not change ([#2559](https://github.com/netclaw-dev/netclaw/pull/2559)).
- **A repository grant composes with the session scratch folder.** A command that a repository grant covers no longer prompts again when it redirects output to the session scratch folder. Netclaw checks the command and the file write separately. A `Once` answer covers the command and each file operation ([#2563](https://github.com/netclaw-dev/netclaw/pull/2563)).
- **Shell approval judges more commands correctly.**
  - A loop or brace list with a finite set of values is judged as each literal command it runs ([#2372](https://github.com/netclaw-dev/netclaw/pull/2372), [#2373](https://github.com/netclaw-dev/netclaw/pull/2373)).
  - A Bash assignment that no program reads no longer forces an exact prompt for each later command ([#2374](https://github.com/netclaw-dev/netclaw/pull/2374)).
  - A command that runs no program, such as `> result.log` or `echo hi > file`, gets the file-tool decision for its redirect, not a shell prompt ([#2377](https://github.com/netclaw-dev/netclaw/pull/2377)).
  - A heredoc with a quoted delimiter, such as `python3 - <<'EOF'`, is data on stdin. A grant can now cover the command ([#2381](https://github.com/netclaw-dev/netclaw/pull/2381)).
  - An option value outside the folder, such as `--output=../x`, and a link to a target outside the folder now need a grant that covers that location ([#2378](https://github.com/netclaw-dev/netclaw/pull/2378), [#2380](https://github.com/netclaw-dev/netclaw/pull/2380)).
  - The agent gets a correction only when it can follow it. A word with a run-time value gets a one-time prompt instead ([#2379](https://github.com/netclaw-dev/netclaw/pull/2379)).
  - The prompt and the "Saved" line show the same grant words that Netclaw saves ([#2382](https://github.com/netclaw-dev/netclaw/pull/2382)).
- **The output redactor finds more secrets and runs in linear time.** It now masks known token formats, prefixed secret variable names, URL credentials, option values such as `--password hunter2`, API-key, Basic, Cookie, and Proxy-Authorization headers, and HAR or Postman name and value pairs. A long or repetitive tool output no longer slows the redactor ([#2401](https://github.com/netclaw-dev/netclaw/pull/2401), [#2463](https://github.com/netclaw-dev/netclaw/pull/2463), [#2605](https://github.com/netclaw-dev/netclaw/pull/2605)).
- **Tool access follows the effective posture audience.** Tool access for a turn and its sub-agents now follows the effective audience of the deployment posture ([#2619](https://github.com/netclaw-dev/netclaw/pull/2619)).
  - **Upgrade impact:** a posture can be narrower than the source audience, for example a Team posture with Slack direct messages. In that case, a reminder that someone created before the upgrade has the Personal audience. After the upgrade, `run_reminder` refuses that reminder, and a chat with the narrower audience does not show it. Create the reminder again from a chat after the upgrade.
- **Approval override keys with no value are ignored.** Netclaw now ignores a `ToolOverrides` or `McpServerDefaults` key that has a colon, such as `file_write:control-plane`, and keeps the audience default. The daemon logs a startup warning for each ignored key. Override keys now match tool names without regard to letter case. When two keys differ only in case, the more restrictive mode applies ([#2622](https://github.com/netclaw-dev/netclaw/pull/2622)).
  - **Upgrade impact:** `netclaw doctor` reports a key with a colon as an error and names the valid forms: `tool_name`, `server/tool`, and `server__tool`. `netclaw doctor --fix` does not change these keys, so remove them by hand. A tool that such a key changed returns to the audience default, so it can ask for approval again.
- **TUI commands no longer write a trace file.** Before, the TUI commands wrote `netclaw-<mode>-trace.log` to the system temp folder. Now no command writes this file ([#2620](https://github.com/netclaw-dev/netclaw/pull/2620)).
  - **Upgrade impact:** files from older releases stay on disk. Delete each `netclaw-*-trace.log` file from the system temp folder.
- **Provider OAuth token reads require a local-control proof.** The provider OAuth status endpoint no longer returns tokens. The CLI reads the tokens from a new local-control endpoint, and only with a local-control proof. The provider manager also shows the browser OAuth progress, the authorization URL, and errors ([#2621](https://github.com/netclaw-dev/netclaw/pull/2621)).
  - **Upgrade impact:** use the same version for the CLI and the daemon. A new CLI with an older daemon shows an upgrade message during a provider OAuth sign-in.

### Channels

- **A channel keeps its output route until its session stops.** Before, a channel binding could stop before its session, and the session lost its output route. Now a binding stays until the session passivates, then sends its last output and stops. Mattermost stops its typing indicator before that drain ([#2429](https://github.com/netclaw-dev/netclaw/pull/2429)).
- **Closed child prompts redraw in each channel.** See Sub-agents ([#2584](https://github.com/netclaw-dev/netclaw/pull/2584)).

### Tools

- **A large tool result keeps its tail.** When a tool result is longer than the inline limit (`Session.Tuning.MaxInlineToolResultChars`, default 12,000 characters), the model now gets the last part, not the first and last parts. Command output, logs, and stack traces put the useful text at the end. `tool_output_read` still reads the rest ([#2425](https://github.com/netclaw-dev/netclaw/pull/2425)).
- **A large tool result is always kept.** Before, a session with no workspace folder lost the full text, and the model could not read the middle. Now Netclaw creates the folder, and refuses a link at the folder or its parent ([#2414](https://github.com/netclaw-dev/netclaw/pull/2414), [#2430](https://github.com/netclaw-dev/netclaw/pull/2430)).
- **`search_tools` ranks its results.** Results with the most query words come first, so a built-in tool such as `list_reminders` is found. The agent guidance now prefers a built-in tool to a `netclaw` CLI command that needs a shell approval ([#2385](https://github.com/netclaw-dev/netclaw/pull/2385)).
- **`update_memory` keeps a memory in semantic recall.** An edit now writes a new embedding. `netclaw memory backfill-embeddings` does nothing when `Memory.Embeddings.Enabled` is false ([#2395](https://github.com/netclaw-dev/netclaw/pull/2395)). The `netclaw-memory` skill states the correct default and log event names ([#2419](https://github.com/netclaw-dev/netclaw/pull/2419)).
- **Memory curation uses the Main model.** Before, curation used the Compaction model ([#2431](https://github.com/netclaw-dev/netclaw/pull/2431)).
  - **Upgrade impact:** a deployment with a separate Compaction model now sends curation requests to the Main model. A deployment with no Compaction model does not change.
- **The content scanner accepts `.potx` PowerPoint templates** ([#2196](https://github.com/netclaw-dev/netclaw/pull/2196)).

- **After a person denies a call, the agent stops and asks.** Before, a denial forbade only a retry, so the agent could reach the same goal with another tool. Now the denial text and the agent guidance tell the agent not to reach that goal another way. The agent says what it wanted to do and asks how to continue. Timeout, policy, and unattended denials keep their text ([#2616](https://github.com/netclaw-dev/netclaw/pull/2616)).

### Providers

- **Codex refreshes its token after an HTTP 401.** When ChatGPT rotates an access token early, Netclaw refreshes the token and sends the request one more time ([#2432](https://github.com/netclaw-dev/netclaw/pull/2432)).
- **A rejected OpenAI refresh sends the re-auth alert.** Netclaw now reads the error object that auth.openai.com sends, so a dead login raises the `ProviderAuthExpired` alert. A transient failure gets one retry ([#2568](https://github.com/netclaw-dev/netclaw/pull/2568)).
- **OpenAI-compatible endpoints work with or without `/v1`** ([#2400](https://github.com/netclaw-dev/netclaw/pull/2400)).

### Telemetry

- **The tool call log line is back, with redaction.** 0.27.0 removed the Info line for each tool call, and the 0.27.0 notes did not say so. The line returns in the parent session and in sub-agents, with the 0.26.0 template and field names ([#2600](https://github.com/netclaw-dev/netclaw/pull/2600)):

  ```
  Invoking tool [{ToolName}] (call={CallId}) args={Args} rationale={Rationale} authorizationAttemptId={AuthorizationAttemptId} sessionId={SessionId}
  ```

  - The redactor masks secrets in the arguments at each depth, and in key names ([#2605](https://github.com/netclaw-dev/netclaw/pull/2605)).
  - A string longer than 256 characters becomes a length and a hash. A string that contained a secret becomes `<N chars, redacted>`.
  - The line is capped at 4,096 characters, and the rationale at 500 characters. The line never makes a tool call fail.
  - **Upgrade impact:** the exported logs now hold one more Info line for each tool call.
- **`session.log` redacts tool arguments.** Before, `session.log` wrote tool call arguments in clear text, cut at 1,000 characters. Now it uses the same redaction, hash, and cap as the log line above. Text that is not a JSON object becomes `<arguments unavailable>` ([#2609](https://github.com/netclaw-dev/netclaw/pull/2609)).
  - **Upgrade impact:** `session.log` no longer holds full long argument values. A long file body appears as its length and hash.
- **OTLP over HTTP/protobuf posts to the signal paths** ([#2400](https://github.com/netclaw-dev/netclaw/pull/2400)).
- **Skill load log lines include the session ID:** `turn_skill_loaded skill=X method=Y session=Z` ([#2512](https://github.com/netclaw-dev/netclaw/pull/2512)).

### CLI/TUI

- **`netclaw chat -p` exits 1 when the turn fails.** A provider error, a timeout, or another failed turn now gives exit code 1. A failed turn also writes one `[turn:failed] category=<model|infra> kind=<Kind>` line on stderr. With `--json`, the envelope adds `errorCategory` and `errorKind` ([#2409](https://github.com/netclaw-dev/netclaw/pull/2409), [#2517](https://github.com/netclaw-dev/netclaw/pull/2517)).
  - **Upgrade impact:** a script that ran `netclaw chat -p` and ignored the exit code can now stop on a failed turn. A tool call that headless mode denies still ends with exit code 0 when the model finishes.
- **`netclaw daemon status` exits 1 when the daemon does not run or is not ready.** Before, it exited 0 ([#2400](https://github.com/netclaw-dev/netclaw/pull/2400)).
  - **Upgrade impact:** update scripts that read this exit code.
- **Chat input is confirmed after the daemon saves it.** Before, Enter and then Ctrl+Q could exit before the daemon kept the text. Now the daemon confirms the text after it records it, and that work continues after the client disconnects. On quit, the CLI reports input that it could not send or confirm ([#2426](https://github.com/netclaw-dev/netclaw/pull/2426)).
  - **Upgrade impact:** update the CLI and the daemon together. The chat client needs the text-admission protocol of this release.
- **Chat messages can be up to 512 KB.** Before, a message over 32 KB closed the connection and showed "Message unconfirmed". Now the limit is 512 KB, and the CLI refuses a larger message with its size ([#2487](https://github.com/netclaw-dev/netclaw/pull/2487)).
- **The chat view shows each parallel tool call.** Each call has its own line, and a tool line stays on one row. A preview no longer breaks a character or an escape code ([#2461](https://github.com/netclaw-dev/netclaw/pull/2461), [#2411](https://github.com/netclaw-dev/netclaw/pull/2411)). A very long paste no longer stops input, and Ctrl+Q exits fast with a large transcript ([#2465](https://github.com/netclaw-dev/netclaw/pull/2465), [#2520](https://github.com/netclaw-dev/netclaw/pull/2520)).
- **A bad `netclaw.json` gives one error line.** When `netclaw.json` or `secrets.json` cannot be read, a CLI command prints `Couldn't read <file>: <reason>` and exits 1. Before, it crashed with exit 134 and a crash log ([#2459](https://github.com/netclaw-dev/netclaw/pull/2459)).
- **MCP commands keep and clean up server state.** `netclaw mcp add` on a known name keeps the audience grants, defaults, and enabled state. `netclaw mcp remove` also removes the OAuth tokens, grants, and saved approvals of that server ([#2394](https://github.com/netclaw-dev/netclaw/pull/2394)). The permissions screen asks before it grants all tools, and `--grant` adds the server to the audience ([#2403](https://github.com/netclaw-dev/netclaw/pull/2403)). `netclaw mcp auth` prints the OAuth redirect URI to register with the provider ([#2610](https://github.com/netclaw-dev/netclaw/pull/2610)).
- **Names and endpoints are checked.** MCP and provider names now resolve without regard to letter case, so a second key that differs only in case is not written. `provider add` rejects an endpoint with no scheme. `model list` shows what the daemon uses ([#2462](https://github.com/netclaw-dev/netclaw/pull/2462)). `provider remove`, the `netclaw config` dashboard, and the init wizard read model roles in the current `Models.Definitions` and `Models.Roles` shape ([#2390](https://github.com/netclaw-dev/netclaw/pull/2390)).
- **`netclaw approvals trust-verb` refuses a grant that can never match.** For a non-shell tool, the command prints the form that works and writes nothing ([#2392](https://github.com/netclaw-dev/netclaw/pull/2392)).
- **Messages name real commands.** CLI, TUI, doctor, and alert text no longer name commands that do not exist, and no longer tell you to restart the daemon after a config change ([#2391](https://github.com/netclaw-dev/netclaw/pull/2391)).
- **Identity setup.** `netclaw chat --onboarding` starts the identity interview ([#2401](https://github.com/netclaw-dev/netclaw/pull/2401)). After Redo identity setup, Enter starts the guided identity chat ([#2384](https://github.com/netclaw-dev/netclaw/pull/2384)). A new beta install with only a channel seed opens the first-run wizard ([#2192](https://github.com/netclaw-dev/netclaw/pull/2192)).
- **TUI fixes.** The Exposure Mode page keeps unrelated config when it saves ([#2531](https://github.com/netclaw-dev/netclaw/pull/2531)). A pre-filled input puts the cursor at the end, and Provider Manager and Model Manager fit their columns to the terminal ([#2400](https://github.com/netclaw-dev/netclaw/pull/2400), [#2410](https://github.com/netclaw-dev/netclaw/pull/2410)). On Windows, tables and stats use the locale of the user ([#2400](https://github.com/netclaw-dev/netclaw/pull/2400)).

### Daemon and install

- **`netclaw daemon stop` stops only the daemon of its own home.** The CLI sends no signal until it proves that the PID serves this home. The daemon answers 409 to a stop notice for another home ([#2544](https://github.com/netclaw-dev/netclaw/pull/2544)).
  - **Upgrade impact:** on macOS and Windows, the CLI cannot prove the home of a daemon that does not answer, or of a 0.27.1 daemon during `netclaw update`. `netclaw daemon stop` then refuses and prints the `kill <pid>` command to use. Linux reads the proof from `/proc`.
- **Install scripts use `NETCLAW_HOME`.** `install.sh` and `install.ps1` put the config in `<NETCLAW_HOME>/config`. `netclaw daemon install` and `netclaw doctor --fix` now keep the operator lines in `daemon.env` and change only `PATH` ([#2528](https://github.com/netclaw-dev/netclaw/pull/2528)).
- **systemd and Docker.** `daemon stop` and `daemon start` go through the systemd unit that owns the daemon. The Docker health check follows `Daemon.Port`. `daemon pair` prints a command that you can use ([#2400](https://github.com/netclaw-dev/netclaw/pull/2400)).
- **An update check timeout no longer stops the daemon.** Before, a network timeout in the update check stopped the daemon 10 seconds after start. `netclaw update --check` no longer crashes on a timeout ([#2538](https://github.com/netclaw-dev/netclaw/pull/2538)).
- **Session folders follow a moved home.** When the data directory moves, Netclaw finds session folders under the new path and logs one warning ([#2401](https://github.com/netclaw-dev/netclaw/pull/2401)).

### Fixes

- The headless channel closes its session log before it stops ([#2611](https://github.com/netclaw-dev/netclaw/pull/2611)).

### Internal

- The session actor moves its tool, model context, task lifetime, restart, and input rules into separate owners, with no behavior change ([#2439](https://github.com/netclaw-dev/netclaw/pull/2439), [#2441](https://github.com/netclaw-dev/netclaw/pull/2441), [#2442](https://github.com/netclaw-dev/netclaw/pull/2442), [#2443](https://github.com/netclaw-dev/netclaw/pull/2443), [#2445](https://github.com/netclaw-dev/netclaw/pull/2445), [#2446](https://github.com/netclaw-dev/netclaw/pull/2446), [#2449](https://github.com/netclaw-dev/netclaw/pull/2449), [#2451](https://github.com/netclaw-dev/netclaw/pull/2451), [#2454](https://github.com/netclaw-dev/netclaw/pull/2454), [#2455](https://github.com/netclaw-dev/netclaw/pull/2455), [#2598](https://github.com/netclaw-dev/netclaw/pull/2598)).
- Specs, evals, mutation gates, CI, and test reliability work ([#2371](https://github.com/netclaw-dev/netclaw/pull/2371), [#2376](https://github.com/netclaw-dev/netclaw/pull/2376), [#2398](https://github.com/netclaw-dev/netclaw/pull/2398), [#2408](https://github.com/netclaw-dev/netclaw/pull/2408), [#2415](https://github.com/netclaw-dev/netclaw/pull/2415), [#2427](https://github.com/netclaw-dev/netclaw/pull/2427), [#2433](https://github.com/netclaw-dev/netclaw/pull/2433), [#2434](https://github.com/netclaw-dev/netclaw/pull/2434), [#2435](https://github.com/netclaw-dev/netclaw/pull/2435), [#2436](https://github.com/netclaw-dev/netclaw/pull/2436), [#2437](https://github.com/netclaw-dev/netclaw/pull/2437), [#2447](https://github.com/netclaw-dev/netclaw/pull/2447), [#2448](https://github.com/netclaw-dev/netclaw/pull/2448), [#2450](https://github.com/netclaw-dev/netclaw/pull/2450), [#2456](https://github.com/netclaw-dev/netclaw/pull/2456), [#2457](https://github.com/netclaw-dev/netclaw/pull/2457), [#2460](https://github.com/netclaw-dev/netclaw/pull/2460), [#2501](https://github.com/netclaw-dev/netclaw/pull/2501), [#2506](https://github.com/netclaw-dev/netclaw/pull/2506), [#2508](https://github.com/netclaw-dev/netclaw/pull/2508), [#2509](https://github.com/netclaw-dev/netclaw/pull/2509), [#2513](https://github.com/netclaw-dev/netclaw/pull/2513), [#2514](https://github.com/netclaw-dev/netclaw/pull/2514), [#2521](https://github.com/netclaw-dev/netclaw/pull/2521), [#2522](https://github.com/netclaw-dev/netclaw/pull/2522), [#2532](https://github.com/netclaw-dev/netclaw/pull/2532), [#2534](https://github.com/netclaw-dev/netclaw/pull/2534), [#2536](https://github.com/netclaw-dev/netclaw/pull/2536), [#2543](https://github.com/netclaw-dev/netclaw/pull/2543), [#2545](https://github.com/netclaw-dev/netclaw/pull/2545), [#2549](https://github.com/netclaw-dev/netclaw/pull/2549), [#2555](https://github.com/netclaw-dev/netclaw/pull/2555), [#2556](https://github.com/netclaw-dev/netclaw/pull/2556), [#2562](https://github.com/netclaw-dev/netclaw/pull/2562), [#2564](https://github.com/netclaw-dev/netclaw/pull/2564), [#2565](https://github.com/netclaw-dev/netclaw/pull/2565), [#2580](https://github.com/netclaw-dev/netclaw/pull/2580), [#2582](https://github.com/netclaw-dev/netclaw/pull/2582), [#2585](https://github.com/netclaw-dev/netclaw/pull/2585), [#2586](https://github.com/netclaw-dev/netclaw/pull/2586), [#2588](https://github.com/netclaw-dev/netclaw/pull/2588), [#2594](https://github.com/netclaw-dev/netclaw/pull/2594), [#2612](https://github.com/netclaw-dev/netclaw/pull/2612), [#2623](https://github.com/netclaw-dev/netclaw/pull/2623), [#2624](https://github.com/netclaw-dev/netclaw/pull/2624), [#2626](https://github.com/netclaw-dev/netclaw/pull/2626), [#2627](https://github.com/netclaw-dev/netclaw/pull/2627), [#2628](https://github.com/netclaw-dev/netclaw/pull/2628)).

### Dependency Updates

- **Bump ASP.NET Core packages** — 10.0.12 → 10.0.13, for the `System.Security.Cryptography.Pkcs` and `System.Security.Cryptography.Xml` advisories ([#2490](https://github.com/netclaw-dev/netclaw/pull/2490))
- **Bump OpenTelemetry** — 1.19.1 → 1.20.0 ([#2518](https://github.com/netclaw-dev/netclaw/pull/2518))
- **Bump Termina** — 0.16.2 → 0.17.0 ([#2410](https://github.com/netclaw-dev/netclaw/pull/2410), [#2465](https://github.com/netclaw-dev/netclaw/pull/2465), [#2520](https://github.com/netclaw-dev/netclaw/pull/2520))
- **Bump Aaron.Akka.Reminders** — 0.7.0 → 1.5.73.3, and **Akka.Hosting** 1.5.71 → 1.5.73 ([#2402](https://github.com/netclaw-dev/netclaw/pull/2402), [#2438](https://github.com/netclaw-dev/netclaw/pull/2438))
- **Bump ShellSyntaxTree** — 0.4.0-beta.22 → 0.4.0-beta.24 ([#2372](https://github.com/netclaw-dev/netclaw/pull/2372))

## 0.27.1 (2026-10-06)

This is the stable 0.27.1 release. Configured tool lists now replace the defaults, so a narrowed allowlist narrows. Shell and tool approval now uses one authorizer and real parser facts, which gives fewer prompts and closes several ways around approval. Mattermost gets native typing indicators. MCP connections keep rotated tokens and deliver real file artifacts. The daemon stops more gracefully.

### Configuration

- **Configured tool lists now replace the defaults.** Before this change, the daemon added configured `Tools` list items to the built-in defaults, so an operator could not narrow an audience tool allowlist, file roots, `GlobalReadRoots`, attachment categories, or `WebFetch.HttpAllowList`. The Security & Access TUI tool-group and attachment changes also had no effect on the daemon. Now a configured list is the complete list.
  - `[]`, `null`, and `{}` give an empty list. For `null` and `{}`, the daemon logs a startup warning that names the key.
  - The daemon now stops at startup, with an error that names the key, when a list key has a scalar value, when an attachment category is not one defined name (for example `"Bogus"` or `"Pdf, Document"`), or when an empty `NETCLAW_*` variable and a config file both set the same list.
  - `netclaw doctor` now warns when a Public or Team allowlist does not include `tool_output_read`. Spilled tool output tells the model to call that tool. The warning has no auto-fix, because a narrow list can be intentional.
  - **Exact older default lists map to today's defaults.** `netclaw init` 0.8.0 to 0.25.4 (and 0.26.0-beta.1 to beta.5) wrote the complete Public and Team `AllowedTools` default lists. When a stored list exactly matches one of those older lists, the daemon applies today's default for that audience and logs a startup warning. A 0.8.0 to 0.19.0 Public list maps to today's Public default and so loses `file_write`.
  - **`netclaw doctor --fix` removes copied default lists.** `netclaw doctor` reports a Public or Team `AllowedTools` list that exactly matches any shipped default, which includes today's default. `netclaw doctor --fix` backs up `netclaw.json` to `netclaw.json.legacy-tool-defaults.bak` (or the next free `.N.bak`) and deletes that key. The rest of the profile stays. The audience then follows the default, so it gets the tools that later releases add.
  - **Edited older lists are applied as written.** An older list that was edited, for example with Web Access turned off in the TUI, or the 17-tool list that the 0.24 TUI wrote when it changed a profile from `All` to `Allowlist`, is not an exact match. The daemon applies it as written, so it does not get `file_search` or `tool_output_read`. Add those tools to the list by hand.
  - **Upgrade impact:** if `netclaw.json` has a narrowed list, the daemon now applies it. For example, `"Team": { "AllowedTools": ["file_read", "file_list"] }` gave all 15 Team tools before and gives only those two tools now. To add one entry to a default list, write the complete list, for example `"GlobalReadRoots": ["{skills_dir}", "{identity_dir}", "{workspaces_dir}", "/srv/docs"]`. Check each `Tools` list in `netclaw.json`, `secrets.json`, and `NETCLAW_*` variables before you upgrade.

- **`netclaw init` saves the posture, not the default tool lists.** Init writes `Security.DeploymentPosture`, `Security.ShellExecutionMode`, `Security.StrictDefaults`, and `Tools.ShellMode`. It does not write `Tools.AudienceProfiles`. The daemon computes the audience profiles from the posture, so a new install gets the tools that later releases add to its defaults. The Personal posture rule, approval for `shell_execute` on Personal, is now a daemon default. A new install gets the same effective tool configuration as before. `netclaw doctor` no longer asks for explicit audience profiles.
- **The CLI reads audience profiles the same way as the daemon.** `netclaw doctor` and the init wizard now resolve profiles consistently with the running daemon, so what you see in the CLI matches what the daemon enforces ([#2367](https://github.com/netclaw-dev/netclaw/pull/2367)).

### Shell authorization and tool approval

Netclaw now routes every tool call through one authorizer, and shell approval reads facts from the `ShellSyntaxTree` parser instead of guessing.

- **Security: shell approval sees commands that the parser missed before.** A backslash-newline inside `$(…)`, or a `#` right after a quote, could hide a command from the parser. In 0.27.0 and earlier, such a command could run with no approval. A command with a carriage return now always needs a one-time approval ([#2368](https://github.com/netclaw-dev/netclaw/pull/2368), [ShellSyntaxTree #243](https://github.com/Aaronontheweb/ShellSyntaxTree/pull/243)).
- **A folder grant stays inside its folder.** A folder, repository, or chat grant no longer covers a loop or variable value that points outside the folder. Only a grant for anywhere covers it ([#2363](https://github.com/netclaw-dev/netclaw/pull/2363)).
- **One authorizer for every tool.** A single linear `ToolAuthorizer` routes every tool call and every shell call through the same authority and consent loop. There is no second gate to drift ([#2299](https://github.com/netclaw-dev/netclaw/pull/2299), [#2301](https://github.com/netclaw-dev/netclaw/pull/2301), [#2302](https://github.com/netclaw-dev/netclaw/pull/2302), [#2303](https://github.com/netclaw-dev/netclaw/pull/2303), [#2304](https://github.com/netclaw-dev/netclaw/pull/2304)).
- **A stored grant decides for unattended runs.** A grant that covers a command lets an unattended run use it, also outside the trusted roots. Unattended runs follow the same audience policy as attended runs, and a call that would prompt is denied ([#2338](https://github.com/netclaw-dev/netclaw/pull/2338)).
- **The approval choice shows in the tool result.** Authorization attempts share one set of consent terms, and the agent sees which choice you made ([#2282](https://github.com/netclaw-dev/netclaw/pull/2282), [#2327](https://github.com/netclaw-dev/netclaw/pull/2327)).
- **An unresolved trust audience stops the call.** Netclaw does not run a tool or shell command when it cannot resolve which audience governs it ([#2257](https://github.com/netclaw-dev/netclaw/pull/2257)).
- **Shell approval uses real parser facts.** Glob, binding, quoting, and command-word facts come from `ShellSyntaxTree` 0.4.0 ([#2321](https://github.com/netclaw-dev/netclaw/pull/2321), [#2349](https://github.com/netclaw-dev/netclaw/pull/2349), [#2354](https://github.com/netclaw-dev/netclaw/pull/2354)).
- **A verb grant covers its arguments.** A grant that names a verb, such as `dotnet build`, covers any later words. A safe phrase can read each path the audience may read ([#2359](https://github.com/netclaw-dev/netclaw/pull/2359), [#2314](https://github.com/netclaw-dev/netclaw/pull/2314)).
- **Fewer prompts for read-only commands.** More common read commands run with no prompt ([#2310](https://github.com/netclaw-dev/netclaw/pull/2310), [#2342](https://github.com/netclaw-dev/netclaw/pull/2342)). Test builtins and run-time output values count as data ([#2344](https://github.com/netclaw-dev/netclaw/pull/2344), [#2315](https://github.com/netclaw-dev/netclaw/pull/2315)). `echo` in a loop after `cd` no longer prompts, and the agent gets advice to quote a word instead of a one-time prompt ([#2361](https://github.com/netclaw-dev/netclaw/pull/2361)).
- **Each command in a call is judged on its own.** An unresolved part no longer forces a prompt for the whole call ([#2318](https://github.com/netclaw-dev/netclaw/pull/2318)). An API route is not read as a folder ([#2317](https://github.com/netclaw-dev/netclaw/pull/2317)), and a multi-line operand is scoped by its clean text ([#2316](https://github.com/netclaw-dev/netclaw/pull/2316)).
- **Better word handling.** A quoted program word with a space is a normal word, a file name is not a command word, and a program path matches by its file, not its spelling ([#2336](https://github.com/netclaw-dev/netclaw/pull/2336), [#2334](https://github.com/netclaw-dev/netclaw/pull/2334), [#2312](https://github.com/netclaw-dev/netclaw/pull/2312), [#2329](https://github.com/netclaw-dev/netclaw/pull/2329)).
- **Only a kill of the Netclaw daemon is hard-denied.** Before, every `kill`, `pkill`, `killall`, and `Stop-Process` was hard-denied. Now those commands prompt, and a grant can cover them. A kill that names the Netclaw daemon is still denied ([#2319](https://github.com/netclaw-dev/netclaw/pull/2319)).
- **Static shell assignments can use exact reusable approvals.** Netclaw binds each grant to a digest of the complete Bash or PowerShell assignment facts. Finite PowerShell loops can reuse exact grants after Netclaw checks the public path facts ([#2215](https://github.com/netclaw-dev/netclaw/pull/2215)).
- **The grant store stays clean.** Netclaw does not save junk grants, and older grants match on their own command words ([#2339](https://github.com/netclaw-dev/netclaw/pull/2339), [#2322](https://github.com/netclaw-dev/netclaw/pull/2322)).
- **Config files are readable, except secrets.** The agent and the shell can read each config file except `secrets.json`, `keys/`, and `webhooks/`. File tools can read the grant store ([#2337](https://github.com/netclaw-dev/netclaw/pull/2337), [#2323](https://github.com/netclaw-dev/netclaw/pull/2323)).
- **A command too long to show gets a correction.** When a shell command is too long for an approval prompt, the agent gets a correction that asks for a shorter command ([#2355](https://github.com/netclaw-dev/netclaw/pull/2355)).
- **Skill folders are no longer write-protected.** A skill edit is allowed, and the next skill sync restores system skill files ([#2357](https://github.com/netclaw-dev/netclaw/pull/2357)).

### Channels

- **Native Mattermost typing indicators.** Mattermost shows typing indicators for active session turns, and approval action IDs are now alphanumeric ([#2358](https://github.com/netclaw-dev/netclaw/pull/2358), [#2366](https://github.com/netclaw-dev/netclaw/pull/2366)).
- **Long approval prompts stay postable.** Netclaw shortens a long approval prompt so the channel accepts it. When a post fails, Netclaw reports the failure and does not report it as a denial ([#2353](https://github.com/netclaw-dev/netclaw/pull/2353)).

### MCP

- **MCP tool results carry real artifacts.** Binary image, audio, and embedded-resource blocks from MCP tools are scanned with the existing content scanner, stored in the session artifact directory, and delivered to the primary channel through the normal file-output path. Rejected or unsupported artifacts stay visible as notes, and text-only results keep working unchanged ([#2232](https://github.com/netclaw-dev/netclaw/pull/2232)).
- **Multi-content MCP tool results render readably.** When the MCP SDK returns a successful result as in-memory content objects, text blocks are joined and image attachments project as MIME markers instead of surfacing the literal type name ([#2180](https://github.com/netclaw-dev/netclaw/pull/2180), fixes [#2051](https://github.com/netclaw-dev/netclaw/issues/2051)).
- **A reconnect no longer loses a rotated refresh token.** Netclaw sends one refresh grant at a time for each MCP server, and each connection redeems the newest stored refresh token. A connection from before an explicit authorization cannot replace the credentials of that authorization ([#2263](https://github.com/netclaw-dev/netclaw/issues/2263)).
- **Rejected refresh grants are logged.** The daemon logs the token endpoint status and the OAuth `error` fields when an authorization server rejects a refresh. The refresh diagnostic line no longer reports an absent client secret as a blocker ([#2263](https://github.com/netclaw-dev/netclaw/issues/2263)).
- **Catalog refresh backs off.** Failing catalog refreshes back off instead of hammering the endpoint, and a degraded server is reported rather than silently dropped ([#2276](https://github.com/netclaw-dev/netclaw/pull/2276)).

### Reliability

- **Graceful daemon stop, bounded to thirty seconds.** Shutdown drains webhook alerts and stops durable approval waits before delivery is cancelled, so work in flight has a chance to land ([#2211](https://github.com/netclaw-dev/netclaw/pull/2211), [#2208](https://github.com/netclaw-dev/netclaw/pull/2208), [#2251](https://github.com/netclaw-dev/netclaw/pull/2251)).
- **A graceful stop can resume interrupted sessions.** The daemon can resume a session that a graceful stop interrupted. It saves accepted session input before it acknowledges it, so a crash does not lose that input ([#2210](https://github.com/netclaw-dev/netclaw/pull/2210), [#2209](https://github.com/netclaw-dev/netclaw/pull/2209)).
- **Reminders get tested in-session.** You can test a reminder in a chat with `/run-reminder`, and reminder tools are now scoped to the caller audience ([#2328](https://github.com/netclaw-dev/netclaw/pull/2328), [#2240](https://github.com/netclaw-dev/netclaw/pull/2240)).
- **Skill management is safer and more flexible.** System skills are kept when a local skill uses the same name, and links and protected paths are denied in `skill_manage` mutations ([#2249](https://github.com/netclaw-dev/netclaw/pull/2249), [#2247](https://github.com/netclaw-dev/netclaw/pull/2247)). `skill_read_resource` returns the resource path ([#2325](https://github.com/netclaw-dev/netclaw/pull/2325)).
- **Webhook credential leaks are fixed.** Diagnostics no longer leak webhook credentials ([#2237](https://github.com/netclaw-dev/netclaw/pull/2237)).

## 0.27.0 (2026-09-23)

This is the stable 0.27.0 release, closing the beta cycle. The headline: NetClaw now remembers across sessions with local, on-device semantic memory - no cloud embeddings, no external services. Around that, shell approvals got sharper and quieter for both Bash and PowerShell, Slack replies render far better, MCP connections start faster and support OAuth client secrets, and the whole release carries a long tail of robustness fixes backed by behavioral evals.

### Local semantic memory (ONNX)

NetClaw remembers you across sessions, entirely on your machine. A new `Netclaw.Embeddings` assembly embeds every cross-session memory locally with ONNX and searches it on-device - no cloud, no external service.

- **Embed at write time, recall by meaning.** Memories are embedded on store, nominated by kNN during curation, and found through hybrid vector + lexical recall ([#1749](https://github.com/netclaw-dev/netclaw/pull/1749)).
- **A cross-encoder keeps weak matches out, with evidence behind it.** On an out-of-sample test of 450 real-traffic queries, the relevance gate cuts irrelevant injections almost entirely while keeping the good recall intact ([#1588](https://github.com/netclaw-dev/netclaw/pull/1588), [#1749](https://github.com/netclaw-dev/netclaw/pull/1749)).

| Metric | Hybrid floor only | Cross-encoder gate |
|--------|------------------:|-------------------:|
| Correct zero-injection | 7.3% | 86.8% |
| Relevant recall retention | — | 98.3% |
| Mean injected items | 2.538 | 0.251 |
| F0.5 | 0.100 | 0.130 |

- **Local, pinned models.** Defaults are [`snowflake-arctic-embed-m-int8`](https://huggingface.co/Snowflake/snowflake-arctic-embed-m) for embedding and [`ms-marco-minilm-l-6-v2`](https://huggingface.co/Xenova/ms-marco-MiniLM-L-6-v2) for the relevance gate. Both come from a pinned allowlist - NetClaw never loads an arbitrary model ([#1749](https://github.com/netclaw-dev/netclaw/pull/1749)).
- **Faster and lighter at rest.** The int8 embedder used about 57% less steady-state RSS than fp32 and ran about 1.7x faster ([#1749](https://github.com/netclaw-dev/netclaw/pull/1749)).
- **On by default - and we recommend leaving it on.** If you need to opt out, set `Memory.Embeddings.Enabled = false` in `netclaw.json`. Models download on first daemon start, alert on failure, and can be pre-provisioned for a fully offline start ([#1749](https://github.com/netclaw-dev/netclaw/pull/1749)).
- **Backfill your existing memories.** Run `netclaw memory backfill-embeddings` once to embed memories you already had before upgrading, so older context is searchable too. `netclaw doctor` reports embedding model health ([#1749](https://github.com/netclaw-dev/netclaw/pull/1749)).

> **Upgrade note:** embeddings default to enabled. Expect roughly 800 MB total RSS on the reference configuration, and plan for model access on first start. Operators can disable embeddings with `Memory.Embeddings.Enabled = false` or pre-provision the models for offline use.

### Smarter, quieter shell approvals

The approval engine got both sharper and less noisy this cycle - it catches unsafe commands it used to guess at, and stops prompting you for the ones that were always safe.

- **Static proof for compound shell scopes.** Netclaw authorizes proved static Bash command scopes; link scopes stay outside compound grants, sibling scopes need their own grant, and scope proof preserves causal policy ([#2191](https://github.com/netclaw-dev/netclaw/pull/2191), [#2193](https://github.com/netclaw-dev/netclaw/pull/2193)).
- **Explicit repository grants for registered worktrees.** Shell cwd parent traversal is rejected before approval ([#2195](https://github.com/netclaw-dev/netclaw/pull/2195), [#2194](https://github.com/netclaw-dev/netclaw/pull/2194)).
- **Reuse shell approvals after bare status output.** A bare `$?` no longer drops every reusable approval candidate; unknown parameters, redirects, and substitutions stay strict ([#2200](https://github.com/netclaw-dev/netclaw/pull/2200)).
- **Less Windows fatigue.** Netclaw reuses proven facts across similar PowerShell reviews and reduces prompts, and blocks PowerShell syntax it cannot analyze safely instead of guessing ([#2177](https://github.com/netclaw-dev/netclaw/pull/2177), [#2176](https://github.com/netclaw-dev/netclaw/pull/2176)).
- **One component completes shell authorization.** `ShellPolicyCoordinator` is the only completion path ([#2152](https://github.com/netclaw-dev/netclaw/pull/2152)).
- **Correlated authorization attempts.** Every tool call carries a PII-free `AuthorizationAttemptId` through evaluation, prompt, decision, retry, and result - one query reconstructs a full authorization attempt, including across cold recovery and sub-agents ([#2078](https://github.com/netclaw-dev/netclaw/pull/2078)).

### Better Slack rendering and reliability

- **Native Slack Markdown blocks for model replies.** Replies go out as a single Slack `MarkdownBlock` and render with Slack's own renderer - tables included. No more hand-built rich-text tree or the ~1,100-line converter it needed. Over-12,000-char replies fall back to plain text ([#2095](https://github.com/netclaw-dev/netclaw/pull/2095)).
- **Slack Socket Mode supervision.** A supervisor checks the transport every 5s, reconnects with exponential backoff up to 5 minutes, classifies fatal vs. transient failures, and alerts through the channel health contract ([#2089](https://github.com/netclaw-dev/netclaw/pull/2089)).

### More dependable MCP

- **OAuth client secrets for MCP servers.** Connect to pre-registered confidential OAuth clients over HTTP and SSE. `netclaw mcp add` writes the client ID to `netclaw.json` and the encrypted secret to `secrets.json`; the configured identity reaches the SDK for authorization-code and refresh-token exchange ([#2169](https://github.com/netclaw-dev/netclaw/pull/2169)).
- **Concurrent MCP startup.** Enabled MCP connections start in parallel through their server gates, so the daemon listener comes up faster; each failed server stays separate from the successful catalog ([#2203](https://github.com/netclaw-dev/netclaw/pull/2203)).
- **MCP auth failures demote only when real.** A typed HTTP 401 marks HTTP servers `AuthFailed`; tool-result text demotes OAuth-capable servers only, so stdio and static-header servers no longer trip false alarms. The remedy names the credential you configured ([#2062](https://github.com/netclaw-dev/netclaw/pull/2062), [#2057](https://github.com/netclaw-dev/netclaw/pull/2057)).
- **OAuth token exchanges request JSON responses**, keeping GitHub-compatible endpoints aligned with the MCP SDK decoder ([#2141](https://github.com/netclaw-dev/netclaw/issues/2141), [#2167](https://github.com/netclaw-dev/netclaw/pull/2167)).
- **openai-compatible providers accept an optional API key** for endpoints that need no key ([#2148](https://github.com/netclaw-dev/netclaw/pull/2148)).

### Unified session storage

Sessions now live in one versioned storage envelope with a managed temporary directory per process.

- One versioned layout holds work files, attachment staging, artifacts, temp files, worktrees, and logs ([#2090](https://github.com/netclaw-dev/netclaw/pull/2090)).
- Each process gets its own managed temp directory through standard environment variables ([#2090](https://github.com/netclaw-dev/netclaw/pull/2090)).
- Child runs inherit parent roots and restrictions; successful `spawn_agent` results return child run, log, and artifact paths ([#2090](https://github.com/netclaw-dev/netclaw/pull/2090)).
- File authority stays explicit - Netclaw validates attachment destinations before copy and denies linked and write-protected destinations ([#2145](https://github.com/netclaw-dev/netclaw/pull/2145)).

> **Downgrade note:** a pre-0.27 binary cannot resume a session that has a versioned storage binding. Existing sessions keep their current paths.

### System skills ship inside the daemon

- **System skills restore from the installed binary.** Startup replaces only the managed `.system` tree and keeps user skills unchanged ([#2138](https://github.com/netclaw-dev/netclaw/pull/2138)).
- **`netclaw skill sync` starts an external source pass immediately**, without saving configuration; a partial failure returns exit code 1 ([#2140](https://github.com/netclaw-dev/netclaw/pull/2140)).
- **The legacy hosted system-skill feed retires.** `netclaw doctor --fix` removes the obsolete `SkillSync.DisableSystemSkillSync` property ([#2138](https://github.com/netclaw-dev/netclaw/pull/2138)).

### Security posture

- **Path access mutation gate.** Netclaw blocks file-tool writes that mutate a path outside approved authority ([#2155](https://github.com/netclaw-dev/netclaw/pull/2155)).
- **Focused reminder execution mutation gate** tightens the reminder path ([#2178](https://github.com/netclaw-dev/netclaw/pull/2178)).
- **Full reset keeps installed binaries.** A reset from the init TUI purges everything except `bin/`, so the CLI no longer deletes itself mid-reset ([#2085](https://github.com/netclaw-dev/netclaw/pull/2085), [#2086](https://github.com/netclaw-dev/netclaw/pull/2086)).

### Proven by eval, not vibes

- Eval slider drove the shell approval work; behavioral guidance aligned end to end ([#2216](https://github.com/netclaw-dev/netclaw/pull/2216)).
- Native smoke tests run against a deterministic local provider; CLI command streams virtualized in tests ([#2081](https://github.com/netclaw-dev/netclaw/pull/2081), [#2076](https://github.com/netclaw-dev/netclaw/pull/2076)).

---
## 0.27.0-beta.4 (2026-09-14)

Follow-up beta to 0.27.0-beta.3. Shell authorization is safer and less noisy on Windows, openai-compatible providers accept an optional API key, and OAuth token exchanges stay aligned with the MCP SDK.

### Shell authorization

- **Less Windows approval fatigue.** Netclaw reuses proven facts across similar PowerShell reviews and reduces the number of prompts you face ([#2177](https://github.com/netclaw-dev/netclaw/pull/2177)).
- **Unsafe partial PowerShell analyses are denied.** Netclaw blocks PowerShell syntax it cannot analyze safely instead of guessing, and it keeps legacy deny patterns ([#2176](https://github.com/netclaw-dev/netclaw/pull/2176)).

### Providers

- **openai-compatible providers accept an optional API key.** Connect to endpoints that do not require a key ([#2148](https://github.com/netclaw-dev/netclaw/pull/2148)).

### MCP reliability

- **OAuth token exchanges request JSON responses.** This keeps GitHub-compatible token endpoints aligned with the MCP SDK decoder ([#2141](https://github.com/netclaw-dev/netclaw/issues/2141), [#2167](https://github.com/netclaw-dev/netclaw/pull/2167)).

### Security

- **Path access mutation gate.** Netclaw blocks file-tool writes that mutate a path outside approved authority ([#2155](https://github.com/netclaw-dev/netclaw/pull/2155)).

### Internal

- Approval directory and tool authorization mutation gates plus focused smoke isolation tighten the test surface ([#2168](https://github.com/netclaw-dev/netclaw/pull/2168), [#2170](https://github.com/netclaw-dev/netclaw/pull/2170), [#2171](https://github.com/netclaw-dev/netclaw/pull/2171), [#2172](https://github.com/netclaw-dev/netclaw/pull/2172)).

## 0.27.0-beta.3 (2026-09-12)

Follow-up beta to 0.27.0-beta.2. Sessions now live in one versioned storage envelope with a managed temporary directory per process, system skills ship inside the daemon binary, and shell authorization completes in one place. Slack Socket Mode no longer drops silently, and `netclaw skill sync` runs an external source pass on demand.

### Unified session storage

- **One versioned storage envelope per session.** Work files, attachment staging, artifacts, temporary files, worktrees, and logs now live under a single versioned layout ([#2090](https://github.com/netclaw-dev/netclaw/pull/2090)).
- **Each process gets its own managed temporary directory** through the standard temporary environment variables ([#2090](https://github.com/netclaw-dev/netclaw/pull/2090)).
- **Child runs inherit parent roots and restrictions.** Successful `spawn_agent` results return child run, log, and artifact paths. Legacy cross-run raw logs require explicit authority; child summaries and shared artifacts remain available ([#2090](https://github.com/netclaw-dev/netclaw/pull/2090)).
- **Session context announces `worktree_dir`.** Agents compose the existing shell and working-directory tools for Git worktrees ([#2090](https://github.com/netclaw-dev/netclaw/pull/2090)).
- **File authority stays explicit.** Netclaw validates attachment destinations before directory creation or file copy, and it denies linked and write-protected destinations ([#2145](https://github.com/netclaw-dev/netclaw/pull/2145)). Implicit session file roots follow the audience ([#2143](https://github.com/netclaw-dev/netclaw/pull/2143)), and allowed and denied path results stay separate ([#2144](https://github.com/netclaw-dev/netclaw/pull/2144)).
- **Tools read within their authority.** Public and Team file tools keep access to their current session and exact legacy log; other sessions need explicit configured roots. The current session envelope and configured trusted roots feed ordinary file and shell authority, and audience and operation permissions still apply. Authorized structured file reads can inspect `netclaw.json`; secret stores and control-plane state stay protected.
- **Personal access does not change.** Personal file access, existing paths, and session resumption behave as before.

Existing sessions keep their current paths. Netclaw does not move or rename their data.

> **Downgrade note:** A pre-feature binary cannot resume a session that has a versioned storage binding.

### System skills ship inside the daemon

- **System skills restore from the installed binary.** Startup replaces only the managed `.system` tree and keeps user skills unchanged ([#2138](https://github.com/netclaw-dev/netclaw/pull/2138)).
- **`netclaw skill sync` starts an external source pass immediately.** The command does not save configuration. Concurrent requests receive the same pass result, Ctrl+C ends only the caller wait, and a partial failure returns exit code 1 ([#2140](https://github.com/netclaw-dev/netclaw/pull/2140)).
- **The legacy hosted system-skill feed retires.** Binary releases no longer publish it, and maintainers can use the standalone `publish_skills` workflow for legacy updates. `netclaw doctor --fix` removes the retired `SkillSync.DisableSystemSkillSync` property. Private skill feeds remain supported and independent from system skills ([#2138](https://github.com/netclaw-dev/netclaw/pull/2138)).

### Shell authorization

- **One component completes shell authorization.** `ShellPolicyCoordinator` is the only completion path, and closed authorized, tool-validation, and stopped results replace the nullable coordinator tuple ([#2152](https://github.com/netclaw-dev/netclaw/pull/2152)).
- **Collected shell corrections.** A shell request returns correction facts only when a safer native tool covers the same operation, and a session and its delegated agent return the same response ([#2112](https://github.com/netclaw-dev/netclaw/pull/2112), [#2114](https://github.com/netclaw-dev/netclaw/pull/2114), [#2117](https://github.com/netclaw-dev/netclaw/pull/2117)).
- **Netclaw rechecks shell authority at shared process startup** ([#2122](https://github.com/netclaw-dev/netclaw/pull/2122)).
- **Tool denial guidance applies only to the current user turn** ([#2101](https://github.com/netclaw-dev/netclaw/pull/2101)).

### Reliability fixes

- **Host pairing works across exposure modes.** Local pairing commands use a host key-ring proof, and valid codes survive recoverable exchange failures ([#2093](https://github.com/netclaw-dev/netclaw/pull/2093)).
- **Slack Socket Mode stops dropping silently.** SlackNet 0.18.0 fixes the silent disconnect ([#2151](https://github.com/netclaw-dev/netclaw/pull/2151)).
- **Exact repeated tool cycles stop** ([#2105](https://github.com/netclaw-dev/netclaw/pull/2105)).

### Internal

- Tool result contracts separate receipt, child run, and Git cases ([#2146](https://github.com/netclaw-dev/netclaw/pull/2146)); the obsolete scalar correction exception API is gone ([#2125](https://github.com/netclaw-dev/netclaw/pull/2125))
- Slack reconnect and local control redirect tests use explicit completion signals instead of timing ([#2127](https://github.com/netclaw-dev/netclaw/pull/2127), [#2165](https://github.com/netclaw-dev/netclaw/pull/2165))
- Isolated background launch evals precede the runtime fix ([#2124](https://github.com/netclaw-dev/netclaw/pull/2124))

### Dependency Updates

- **Bump Anthropic** — 12.44.0 → 12.46.0 ([#2113](https://github.com/netclaw-dev/netclaw/pull/2113))
- **Bump Microsoft.ML.OnnxRuntime** — 1.27.0 → 1.29.0 ([#2108](https://github.com/netclaw-dev/netclaw/pull/2108))
- **Bump Microsoft.AspNetCore and Microsoft.OpenApi** — 10.0.12 / 2.12.2 ([#2150](https://github.com/netclaw-dev/netclaw/pull/2150))
- **Bump SkiaSharp** — 4.151.1 → 4.152.0 ([#2120](https://github.com/netclaw-dev/netclaw/pull/2120))
- **Bump HtmlAgilityPack** — 1.12.4 → 1.13.0 ([#2104](https://github.com/netclaw-dev/netclaw/pull/2104))
- **Bump Google.Protobuf** — 3.35.1 → 3.36.1 ([#2103](https://github.com/netclaw-dev/netclaw/pull/2103))
- **Bump Mattermost.NET** — 5.0.7 → 5.0.10 ([#2107](https://github.com/netclaw-dev/netclaw/pull/2107))
- **Bump Aspire.Hosting.AppHost** — 13.4.6 → 13.5.3 ([#2098](https://github.com/netclaw-dev/netclaw/pull/2098)); **CommunityToolkit.Aspire.Hosting.Ollama** 13.4.0 → 13.5.0 ([#2100](https://github.com/netclaw-dev/netclaw/pull/2100))
- **Bump Microsoft.SourceLink.GitHub** — 10.0.400 → 10.0.401 ([#2119](https://github.com/netclaw-dev/netclaw/pull/2119)); **Microsoft.NET.Test.Sdk** 18.9.0 → 18.10.0 ([#2130](https://github.com/netclaw-dev/netclaw/pull/2130))
- **Bump rolfbjarne/autoformat** — 0.5 → 0.6 ([#1899](https://github.com/netclaw-dev/netclaw/pull/1899))

## 0.27.0-beta.2 (2026-08-30)

Follow-up beta to 0.27.0-beta.1. Slack replies now render with Slack's own Markdown blocks and tables, Socket Mode connections are supervised and self-heal, MCP auth failures stop firing false alarms, and a full reset no longer deletes the binaries it resets from.

### Better Slack rendering

- **Native Slack Markdown blocks for model replies.** Replies go out as a single Slack `MarkdownBlock` instead of a hand-built Block Kit rich-text tree, so formatting follows Slack's own renderer — including tables, which now render natively (no more custom table blocks or the ~1,100-line converter they needed). The fallback: replies over 12,000 characters go out as plain text ([#2095](https://github.com/netclaw-dev/netclaw/pull/2095)).

### Reliability fixes

- **Slack Socket Mode supervision** — A connection supervisor now checks the transport every 5 seconds, reconnects with exponential backoff up to 5 minutes, classifies fatal vs. transient failures, and alerts through the channel health contract ([#2089](https://github.com/netclaw-dev/netclaw/pull/2089)).
- **MCP auth failures demote only when it's real** — A typed HTTP 401 marks any HTTP server `AuthFailed`; tool-result text demotes OAuth-capable servers only, so stdio and static-header servers no longer trip false `authentication_failed` alerts. The remedy names the credential you actually configured ([#2062](https://github.com/netclaw-dev/netclaw/pull/2062)).
- **Full reset keeps installed binaries** — A full reset from the init TUI purges everything except `bin/`, so the CLI no longer deletes itself mid-reset ([#2085](https://github.com/netclaw-dev/netclaw/pull/2085), [#2086](https://github.com/netclaw-dev/netclaw/pull/2086)).

### Observability

- **Authorization attempts are correlated** — Each tool call carries a PII-free `AuthorizationAttemptId` through policy evaluation, approval prompt, decision, retry, and result, including across cold recovery and sub-agents. One query reconstructs a full authorization attempt ([#2078](https://github.com/netclaw-dev/netclaw/pull/2078)).

### Internal

- Session tool approval state refactored with expanded test coverage ([#2091](https://github.com/netclaw-dev/netclaw/pull/2091))
- Unified session storage and managed temporary paths specified in OpenSpec ([#2068](https://github.com/netclaw-dev/netclaw/pull/2068))
- Native smoke tests run against a deterministic local provider ([#2081](https://github.com/netclaw-dev/netclaw/pull/2081)); CLI command streams virtualized in tests ([#2076](https://github.com/netclaw-dev/netclaw/pull/2076))

### Dependency Updates

- **Bump Anthropic** — 12.40.0 → 12.44.0 ([#2080](https://github.com/netclaw-dev/netclaw/pull/2080))
- **Bump OpenTelemetry** — 1.17.0 → 1.18.0 ([#2073](https://github.com/netclaw-dev/netclaw/pull/2073))
- **Bump Akka group** — Akka.Cluster.Sharding and Akka.Persistence 1.5.70 → 1.5.71 ([#2079](https://github.com/netclaw-dev/netclaw/pull/2079))
- **Bump Microsoft.Extensions.TimeProvider.Testing** — 10.8.0 → 10.9.0 ([#2070](https://github.com/netclaw-dev/netclaw/pull/2070))

## 0.27.0-beta.1 (2026-08-27)

This beta opens the semantic memory cycle. NetClaw now embeds and recalls memories locally on your machine with ONNX — no cloud embeddings, no external services. Recall gets a relevance gate that keeps weak matches out, and `netclaw doctor` watches your embedding model's health.

### Local semantic memory (ONNX)

A new `Netclaw.Embeddings` assembly gives every cross-session memory a local embedding, searched and gated on-device.

- **Embed at write time, recall by meaning.** Memories are embedded when stored, nominated by kNN during curation, and found through hybrid vector + lexical recall ([#1749](https://github.com/netclaw-dev/netclaw/pull/1749)).
- **A cross-encoder keeps weak matches out.** `OnnxCrossEncoderScorer` applies a post-floor relevance gate so vague hits don't slip into recall ([#1749](https://github.com/netclaw-dev/netclaw/pull/1749)).
- **Local, pinned models.** Defaults are `snowflake-arctic-embed-m-int8` for embedding and `ms-marco-minilm-l-6-v2` for the gate. Both come from a pinned allowlist — NetClaw never loads an arbitrary model ([#1749](https://github.com/netclaw-dev/netclaw/pull/1749)).
- **Faster and lighter at rest.** The int8 embedder used about 57% less steady-state RSS than fp32 and ran about 1.7 times faster ([#1749](https://github.com/netclaw-dev/netclaw/pull/1749)).
- **Provisioning you can control.** Models download on first daemon start, alert through the operational channel on failure, and can be pre-provisioned for a fully offline start ([#1749](https://github.com/netclaw-dev/netclaw/pull/1749)).
- **New CLI and health tooling.** `netclaw memory backfill-embeddings` embeds an existing corpus, and `netclaw doctor` reports embedding model health ([#1749](https://github.com/netclaw-dev/netclaw/pull/1749)).

### Small fixes

- Fixed release-note parsing so version metadata resolves cleanly ([#2067](https://github.com/netclaw-dev/netclaw/pull/2067)).
> **Upgrade note:** embeddings default to enabled. Expect roughly 800 MB total RSS on the reference configuration, and plan for model access on first start. Operators can disable embeddings or pre-provision the models for offline use.

## 0.26.0 (2026-08-26)

This release closes the 0.26 beta cycle. Across five betas and a post-beta polish pass, NetClaw got faster with your permission, lighter on your token budget, and more dependable with MCP servers.

### Less approval fatigue

Fresh sessions used to drown you in prompts. Now they land on a focused handful — approvals are reserved for genuinely risky actions, not routine setup and review.

- Fresh-session eval: prompt-equivalent events fell 32 → 25, and read/edit/web guardrails held at 15/15 ([#1982](https://github.com/netclaw-dev/netclaw/pull/1982)).
- Agents stop retrying a scope after a denial, one approval covers an entire causal Bash diagnostic chain, and persistent seed grants batch into a single Ask ([#1985](https://github.com/netclaw-dev/netclaw/pull/1985), [#1925](https://github.com/netclaw-dev/netclaw/pull/1925), [#1989](https://github.com/netclaw-dev/netclaw/pull/1989)).
- Agents declare project scope up front and keep it, instead of drifting to session scratch or fabricating phantom directories ([#1870](https://github.com/netclaw-dev/netclaw/pull/1870), [#1921](https://github.com/netclaw-dev/netclaw/pull/1921), [#1990](https://github.com/netclaw-dev/netclaw/pull/1990), [#2008](https://github.com/netclaw-dev/netclaw/pull/2008)).
- Approval scope gaps closed: `/dev/null`, dotted paths, quoted free-text operands, trailing-slash globs ([#1852](https://github.com/netclaw-dev/netclaw/pull/1852), [#1799](https://github.com/netclaw-dev/netclaw/pull/1799), [#1815](https://github.com/netclaw-dev/netclaw/pull/1815), [#1785](https://github.com/netclaw-dev/netclaw/pull/1785)).

### More token efficiency

The agent reaches for the right tool, so it spends fewer calls — and fewer tokens — to get the same result. Proven by eval, not vibes.

- **Tool calls cut by more than half on attachment tasks.** Five fresh-session trials dropped from baseline 11 tool calls / 15 model requests to 5 tool calls / 10 model requests per task — a single `attach_file` call in every run, with no shell or file-mutation prelude ([#2050](https://github.com/netclaw-dev/netclaw/pull/2050)).
- **Prompt-equivalent events cut by a quarter in fresh sessions** — 32 → 25, with read/edit/web guardrails held at 15/15 ([#1982](https://github.com/netclaw-dev/netclaw/pull/1982)).
- **Fewer tool calls per task, proven by eval.** On the reference five-run task, behavior completion rose (3/5 → 5/5) while shell calls dropped 6 → 5, compound shell calls 1 → 0, and approval-equivalent events 1 → 0 ([#1994](https://github.com/netclaw-dev/netclaw/pull/1994)).
- **Structured tools picked in 25/25 trials.** Recursive search, batch reads, JSON projection, and deferred discovery each chose the native structured tool over a shell fallback in every hosted trial ([#2039](https://github.com/netclaw-dev/netclaw/pull/2039), [#2037](https://github.com/netclaw-dev/netclaw/pull/2037)).
- **Native tool names can't leak into the shell** — a known first-party tool name typed into `shell_execute` is caught before any grant, approval, or execution, and returns a typed correction ([#2050](https://github.com/netclaw-dev/netclaw/pull/2050)).
- **Progressive tool disclosure.** Parent and subagent sessions each get a deterministic, role-scoped tool set, so a child only sees the surface it needs ([#2021](https://github.com/netclaw-dev/netclaw/pull/2021), [#2022](https://github.com/netclaw-dev/netclaw/pull/2022)).
- **Fewer tools by default.** Bulk/ambiguous workspace tools were removed in favor of composed primitives; a fixed synthetic catalog produced just 3 parent tool definitions (~1 KB of schema) vs. 202 child definitions (~134 KB) — proof the parent surface stays lean ([#2045](https://github.com/netclaw-dev/netclaw/pull/2045), [#2020](https://github.com/netclaw-dev/netclaw/pull/2020), [#2033](https://github.com/netclaw-dev/netclaw/pull/2033), [#2037](https://github.com/netclaw-dev/netclaw/pull/2037)).

### MCP reliability, OAuth, and prompts

The largest theme this cycle. NetClaw leaned harder into [Model Context Protocol](https://modelcontextprotocol.io) — server prompts now shape how the agent works, OAuth survives restarts, and a long tail of reliability fixes make MCP dependable at scale.

- **MCP server prompts are now invocable as skills** — the [prompts](https://modelcontextprotocol.io/specification/2025-06-18/server/prompts) primitive plugs straight into NetClaw's skill system, so any MCP server can steer agent behavior right out of the box. `netclaw skill load` them like built-ins and `netclaw skill list` surfaces them alongside your own ([#1813](https://github.com/netclaw-dev/netclaw/pull/1813), [#1891](https://github.com/netclaw-dev/netclaw/pull/1891)).
- **OAuth refresh survives cold restarts** — the SDK-resolved client identity is persisted, so token refresh still matches after a restart instead of falling back to interactive auth ([#1970](https://github.com/netclaw-dev/netclaw/pull/1970)).
- **Auth-loss explains itself** — diagnostics report the missing/mismatched binding field, refresh-token state, and token expiry ([#1969](https://github.com/netclaw-dev/netclaw/pull/1969)).
- **Output no longer corrupted by redaction** — legitimate credential-like payloads (e.g. presigned URLs) pass through trusted MCP output untouched; redaction stays on for shell, file, web, and background output ([#1992](https://github.com/netclaw-dev/netclaw/pull/1992)).
- **Sane server-level defaults** — new tools inherit the server approval default instead of silently hiding ([#1978](https://github.com/netclaw-dev/netclaw/pull/1978)).
- **Accurate connection and outcome health** — tool-call exceptions record as failed outcomes ([#2055](https://github.com/netclaw-dev/netclaw/pull/2055)), reconnects fire only on real transport/session failures ([#2056](https://github.com/netclaw-dev/netclaw/pull/2056)), dead OAuth connections stop reporting "Connected forever" ([#1841](https://github.com/netclaw-dev/netclaw/pull/1841)), and non-OAuth 401/403 surface as their true status ([#1908](https://github.com/netclaw-dev/netclaw/pull/1908)).
- **Secrets scrubbed** — token and client-registration error bodies can no longer leak the client secret into daemon logs ([#1976](https://github.com/netclaw-dev/netclaw/pull/1976)).

### Proven, not promised

Approval and tool-guidance changes now ship with executable behavioral evidence.

- Eval harness separates stdout from stderr so diagnostics can't fake JSON output ([#1896](https://github.com/netclaw-dev/netclaw/pull/1896)).
- Live shell-approval corpora and before/after fresh-session evals anchor each claim ([#1930](https://github.com/netclaw-dev/netclaw/pull/1930), [#1819](https://github.com/netclaw-dev/netclaw/pull/1819), [#1982](https://github.com/netclaw-dev/netclaw/pull/1982)).
- A post-merge binary-swap harvest records real-world tool selection to catch rollout drift ([#2039](https://github.com/netclaw-dev/netclaw/pull/2039), [#2040](https://github.com/netclaw-dev/netclaw/pull/2040)).

### Always-on reminders, in your timezone

- Timezone-aware cron via the Vixie `CRON_TZ=` prefix — DST-correct schedules in any IANA zone ([#1789](https://github.com/netclaw-dev/netclaw/pull/1789)).
- Reminders no longer skipped on execution capacity; failed one-shots are retained and duplicate acks are idempotent ([#1839](https://github.com/netclaw-dev/netclaw/pull/1839), [#1812](https://github.com/netclaw-dev/netclaw/pull/1812), [#1955](https://github.com/netclaw-dev/netclaw/pull/1955)).
- Scheduling failures surface loudly with a Critical alert and channel notice instead of silently staying enabled ([#1886](https://github.com/netclaw-dev/netclaw/pull/1886)).

### Quieter channels

- Thread replies become mention-gated with automatic history backfill — less noise, right context ([#1783](https://github.com/netclaw-dev/netclaw/pull/1783)).
- SlackNet 0.17.11 and faster Mattermost startup (no more WebSocket connect race) ([#1986](https://github.com/netclaw-dev/netclaw/pull/1986)).

### First-class Windows

- Native PowerShell on Windows with a 5.1 fallback for script hosts, instead of emulation.
- Self-update no longer crashes on Windows after success; a failed binary swap rolls back so installs never brick ([#1924](https://github.com/netclaw-dev/netclaw/pull/1924)).

### Under the hood

- **Netclaw.Channels** — duplicated channel helpers consolidated into one shared library ([#2002](https://github.com/netclaw-dev/netclaw/pull/2002), [#2005](https://github.com/netclaw-dev/netclaw/pull/2005)).
- Webhook route mutation moved to a daemon actor as the single authority ([#2011](https://github.com/netclaw-dev/netclaw/pull/2011)).
- JSON pointer token buffers reused for a hot-path allocation win ([#2041](https://github.com/netclaw-dev/netclaw/pull/2041)).
- Persistent-seed approval grants batch into one Ask per case ([#1989](https://github.com/netclaw-dev/netclaw/pull/1989)).
- CI deflaked: deterministic race-condition fixes, raised TestKit expect default, shared-timeout sizing, and fetched-content filename collision proofing ([#2001](https://github.com/netclaw-dev/netclaw/pull/2001), [#2014](https://github.com/netclaw-dev/netclaw/pull/2014), [#2019](https://github.com/netclaw-dev/netclaw/pull/2019), [#2018](https://github.com/netclaw-dev/netclaw/pull/2018)).

### Security posture

- Fail-closed tool and shell policy stays the default; approval scope gaps closed across the cycle.
- SSH.NET pinned to 2026.0.0 to resolve CVE-2026-48798 in a test-only transitive dependency ([#1909](https://github.com/netclaw-dev/netclaw/pull/1909)).

---

## 0.26.0-beta.5 (2026-08-18)

### Features
- **MCP tools inherit the server approval default** — A tool that a server adds after per-tool rules were configured now inherits the server's default posture instead of being hidden; disabled tools are hidden from the model entirely, and `netclaw mcp tools` grant/revoke toggles map to Approval/Deny and work correctly against Deny defaults ([#1978](https://github.com/netclaw-dev/netclaw/pull/1978))
- **Fewer shell approval prompts in fresh sessions** — Avoidable approval retries and prompts are reduced, agents stop retrying a scope after an access denial, and project scope declaration misses are cut ([#1982](https://github.com/netclaw-dev/netclaw/pull/1982), [#1985](https://github.com/netclaw-dev/netclaw/pull/1985), [#1983](https://github.com/netclaw-dev/netclaw/pull/1983), [#1990](https://github.com/netclaw-dev/netclaw/pull/1990))
- **One approval for causal Bash diagnostic chains** — Causal diagnostic command chains now collapse to a single approval decision instead of prompting per step ([#1925](https://github.com/netclaw-dev/netclaw/pull/1925))
- **Agents use file tools and stable project scope** — Agents are steered to file tools for known file work, subagents are guided to private session scratch, and subagent project scope corrections are fixed ([#1952](https://github.com/netclaw-dev/netclaw/pull/1952), [#1956](https://github.com/netclaw-dev/netclaw/pull/1956), [#1921](https://github.com/netclaw-dev/netclaw/pull/1921), [#1920](https://github.com/netclaw-dev/netclaw/pull/1920))

### Bug Fixes
- **MCP tool output is no longer corrupted by redaction** — Legitimate payloads that look credential-like, such as presigned upload URLs, pass through unmodified; redaction stays on for shell, file, web, and background-job output ([#1992](https://github.com/netclaw-dev/netclaw/pull/1992))
- **`shell_execute` no longer hangs on background children** — Commands that daemonize return promptly, buffered output flushes in a short grace window, and a note reports when output capture was cut ([#1887](https://github.com/netclaw-dev/netclaw/pull/1887))
- **Mattermost initial connection race fixed** — Startup now waits for the WebSocket `OnConnected` event before reporting ready ([#1986](https://github.com/netclaw-dev/netclaw/pull/1986))
- **MCP OAuth cold-start refresh works again** — The SDK-resolved client identity is persisted so token refresh still matches after a restart instead of falling back to interactive auth ([#1970](https://github.com/netclaw-dev/netclaw/pull/1970))
- **MCP secrets redacted from OAuth failure logs** — Token and client-registration error bodies can no longer leak the client secret into daemon logs ([#1976](https://github.com/netclaw-dev/netclaw/pull/1976))
- **MCP non-OAuth 401/403 no longer reported as awaiting auth** — Plain transport rejections surface as their real HTTP status instead of telling operators to run `netclaw mcp auth` ([#1908](https://github.com/netclaw-dev/netclaw/pull/1908))
- **MCP HTTP status detection hardened** — `netclaw mcp list` and `netclaw doctor` no longer misreport stdio servers whose command path contains "401" or "403" as HTTP auth failures ([#1913](https://github.com/netclaw-dev/netclaw/pull/1913))
- **Duplicate reminder acks are idempotent** — Re-sent acknowledgement messages no longer disturb reminder state ([#1955](https://github.com/netclaw-dev/netclaw/pull/1955))
- **Self-update no longer crashes on Windows after success** — Deleting the running binary's backup is skipped, and a failed binary swap rolls back so installs never brick ([#1924](https://github.com/netclaw-dev/netclaw/pull/1924))
- **PowerShell host probe timeout raised to 15 seconds** — Slow `pwsh` cold starts are less likely to fail the probe ([#1949](https://github.com/netclaw-dev/netclaw/pull/1949))
- **Headless reviewed-safe shell authority fixed** — Reviewed-safe commands in headless sessions now resolve authority correctly ([#1918](https://github.com/netclaw-dev/netclaw/pull/1918))

### Internal Improvements
- **Typed shell approval policy** — ShellSyntaxTree 0.3.3 path facts, a typed policy coordinator with bounded decision trace, extracted and ordered policy stages, and enforced reviewed-safe redirect boundaries ([#1916](https://github.com/netclaw-dev/netclaw/pull/1916), [#1915](https://github.com/netclaw-dev/netclaw/pull/1915), [#1890](https://github.com/netclaw-dev/netclaw/pull/1890), [#1926](https://github.com/netclaw-dev/netclaw/pull/1926), [#1929](https://github.com/netclaw-dev/netclaw/pull/1929))
- **Tool rationale required and preserved across tool loops** — Tool execution now requires a rationale and carries it across loop iterations ([#1933](https://github.com/netclaw-dev/netclaw/pull/1933))
- **OAuth refresh failure diagnostics on auth-loss** — Auth demotion now reports which binding field is missing or mismatched, refresh-token state, and token expiry ([#1969](https://github.com/netclaw-dev/netclaw/pull/1969))
- **Eval harness separates stdout and stderr** — No more false eval failures from diagnostic lines parsed as JSON output ([#1896](https://github.com/netclaw-dev/netclaw/pull/1896))
- **CI test stability** — Deterministic fixes for flaky session-log, reminder, and MCP startup tests ([#1991](https://github.com/netclaw-dev/netclaw/pull/1991), [#1927](https://github.com/netclaw-dev/netclaw/pull/1927), [#1906](https://github.com/netclaw-dev/netclaw/pull/1906), [#1904](https://github.com/netclaw-dev/netclaw/pull/1904))

### Dependency Updates
- **Bump ModelContextProtocol.Core** — 2.1.0 → 2.2.0 ([#1938](https://github.com/netclaw-dev/netclaw/pull/1938))
- **Bump Termina** — 0.16.2 ([#1953](https://github.com/netclaw-dev/netclaw/pull/1953))
- **Bump Microsoft.NET.Test.Sdk** — 18.8.1 → 18.9.0 ([#1971](https://github.com/netclaw-dev/netclaw/pull/1971))
- **Bump Testcontainers** — 4.13.0 → 4.14.0 ([#1972](https://github.com/netclaw-dev/netclaw/pull/1972))
- **Bump Microsoft.SourceLink.GitHub** — 10.0.301 → 10.0.400 ([#1902](https://github.com/netclaw-dev/netclaw/pull/1902))
- **Bump microsoft-platform packages** — Microsoft.AspNetCore.DataProtection and System.Security.Cryptography.Xml 10.0.10 → 10.0.11 ([#1900](https://github.com/netclaw-dev/netclaw/pull/1900))
- **Pin SSH.NET to 2026.0.0** — Resolves CVE-2026-48798 in the Testcontainers transitive dependency (test-only, no runtime exposure) ([#1909](https://github.com/netclaw-dev/netclaw/pull/1909))

## 0.26.0-beta.4 (2026-08-12)

### Features
- **Timezone-aware cron schedules** — Cron reminders now accept the Vixie `CRON_TZ=<IANA-zone>` prefix, so schedules evaluate DST-aware in a chosen time zone; expressions without the prefix still run in UTC, and unknown or Windows-style zones fail with IANA guidance ([#1789](https://github.com/netclaw-dev/netclaw/pull/1789))
- **Netclaw identity shown on MCP OAuth consent screens** — RFC 7591 dynamic client registration now sends `client_uri` and `logo_uri`, so authorization servers render a recognizable Netclaw consent screen instead of a bare client name ([#1877](https://github.com/netclaw-dev/netclaw/pull/1877))
- **`skill list` shows MCP prompt skills** — The CLI now reads the daemon's live skill registry via a new `GET /api/skills` endpoint, so dynamic MCP prompt skills appear in listings; the command now requires the daemon and reports "Daemon unavailable" instead of silently degrading ([#1891](https://github.com/netclaw-dev/netclaw/pull/1891))
- **Reminder scheduling failures surface loudly** — Post-fire rescheduling and startup-reconcile failures now emit a `ReminderScheduleFailed` warning, count toward the auto-disable threshold, and trigger the Critical alert plus channel notice on disable — a reminder can no longer silently stay enabled and never fire ([#1886](https://github.com/netclaw-dev/netclaw/pull/1886))

### Bug Fixes
- **Unknown Bash argument data no longer blocks safe commands** — The approval analyzer treats unresolved parameter expansion as structurally safe when ShellSyntaxTree classifies it as a non-path argument; dynamic command identities, paths, redirects, and substitutions still fail closed ([#1875](https://github.com/netclaw-dev/netclaw/pull/1875))

### Internal Improvements
- **General shell approval analysis required** — Constitution-only change prohibiting executable-specific parsing in the approval layer; unresolved inputs stay strict when general shell facts are unavailable ([#1874](https://github.com/netclaw-dev/netclaw/pull/1874))
- **Structured shell approval policy spec** — OpenSpec proposal, design, and spec with evidence fixtures (D01–D18 approval matrix) documenting the typed, per-candidate coverage pipeline ([#1876](https://github.com/netclaw-dev/netclaw/pull/1876))

## 0.26.0-beta.3 (2026-08-11)

### Features
- **Agents declare shell working scope up front** — Agents are now guided to declare their working directory once before multi-command work in a named project, pass the directory to the shell tool instead of inline `cd`, and retry rejected paths instead of working around them — fewer redundant approval prompts and more reliable scoped approvals ([#1870](https://github.com/netclaw-dev/netclaw/pull/1870))

### Bug Fixes
- **Shell approval scopes fixed for dotted paths** — Dotted and hidden paths (e.g. `.netclaw/`) and git refs now produce correct approval scopes, with normalized-verb matching and `git ls-tree` recognized as safe ([#1868](https://github.com/netclaw-dev/netclaw/pull/1868))
- **MCP: dead OAuth registrations discarded again under SDK 2.1** — The MCP SDK 2.1 discovery probe no longer swallows token-endpoint `invalid_client` rejections during interactive OAuth; rejected client registrations are discarded instead of wedging ([#1865](https://github.com/netclaw-dev/netclaw/pull/1865))

### Dependency Updates
- **Bump ModelContextProtocol** — 2.0.0 → 2.1.0 ([#1865](https://github.com/netclaw-dev/netclaw/pull/1865))
- **Bump Anthropic** — 12.39.0 → 12.40.0 ([#1842](https://github.com/netclaw-dev/netclaw/pull/1842))
- **Bump ShellSyntaxTree** — 0.2.0 → 0.3.0 ([#1867](https://github.com/netclaw-dev/netclaw/pull/1867))

## 0.26.0-beta.2 (2026-08-10)

### Features
- **MCP server prompts as dynamic skills** — Prompts exposed by connected MCP servers are now loadable through the skill index, with argument validation and cross-server conflict rejection ([#1813](https://github.com/netclaw-dev/netclaw/pull/1813))
- **Native PowerShell on Windows** — The daemon now runs Windows shell execution through native PowerShell (7.6 preferred, 5.1 fallback) instead of cross-language emulation, with unified execution, analysis, and approval policy ([#1848](https://github.com/netclaw-dev/netclaw/pull/1848))

### Bug Fixes
- **Reminders no longer skipped on capacity** — The execution-capacity gate that settled reminders as skipped is removed; reminders now defer instead of silently dropping ([#1839](https://github.com/netclaw-dev/netclaw/pull/1839))
- **MCP: dead OAuth connections no longer report Connected forever** — Servers with expired OAuth tokens demote to AwaitingAuth with an operator alert instead of wedging the daemon ([#1841](https://github.com/netclaw-dev/netclaw/pull/1841))
- **MCP: HTTP protocol fallback header race fixed** — The stale MCP protocol-version header is only removed from initialize requests; daemon and CLI now share one HTTP client ([#1861](https://github.com/netclaw-dev/netclaw/pull/1861))
- **Daemon working directory preserved** — The daemon no longer runs from a temp directory that cleanup could delete out from under it ([#1853](https://github.com/netclaw-dev/netclaw/pull/1853))
- **`/dev/null` approval scope fixed** — Safe commands redirecting to `/dev/null` no longer create a reusable `/dev` approval scope ([#1852](https://github.com/netclaw-dev/netclaw/pull/1852))
- **PowerShell host probe hardened** — Slow `pwsh` cold starts no longer brick daemon startup; the probe retries and falls back to Windows PowerShell 5.1 ([#1859](https://github.com/netclaw-dev/netclaw/pull/1859))

### Internal Improvements
- **Shell approval analysis migrated to ShellSyntaxTree** — Bash and PowerShell approval decisions now use the ShellSyntaxTree parser with fail-closed unknown syntax ([#1835](https://github.com/netclaw-dev/netclaw/pull/1835), [#1836](https://github.com/netclaw-dev/netclaw/pull/1836), [#1855](https://github.com/netclaw-dev/netclaw/pull/1855))
- **PowerShell approval repetition reduced** — Safe PowerShell command sequences prompt less often ([#1837](https://github.com/netclaw-dev/netclaw/pull/1837))
- **Bash hidden-execution approval boundaries pinned** — `source` builtins and nameref-deferred execution now require one-shot approvals ([#1838](https://github.com/netclaw-dev/netclaw/pull/1838))
- **PowerShell execution-region approvals improved** — Host and body commands must each match approval policy independently ([#1857](https://github.com/netclaw-dev/netclaw/pull/1857))

### Dependency Updates
- **Bump SlackNet** — 0.17.10 → 0.17.11 ([#1844](https://github.com/netclaw-dev/netclaw/pull/1844))
- **Bump ShellSyntaxTree** — 0.2.0 → 0.3.0-alpha.6

## 0.26.0-beta.1 (2026-08-09)

### Features
- **MCP OAuth surfaced at add time** — `netclaw mcp auth` now runs before permission prompts when adding a server ([#1773](https://github.com/netclaw-dev/netclaw/pull/1773))
- **Mention-required thread replies** — Slack, Discord, and Mattermost channels can gate thread replies on an @-mention, with per-channel control ([#1783](https://github.com/netclaw-dev/netclaw/pull/1783))
- **Mention-triggered thread history backfill** — Thread history is backfilled when a mention arrives on mention-gated channels ([#1798](https://github.com/netclaw-dev/netclaw/pull/1798))
- **File reads reach as far as the shell** — File-read tool permission scope now matches the shell tool's reach ([#1770](https://github.com/netclaw-dev/netclaw/pull/1770))
- **TUI state preserved across navigation** — Provider and model pages keep their state when navigating or refreshing ([#1804](https://github.com/netclaw-dev/netclaw/pull/1804))
- **Background job and one-shot reminder cleanup** — Completed background job definitions and successful one-shot reminders are pruned automatically ([#1821](https://github.com/netclaw-dev/netclaw/pull/1821))

### Bug Fixes
- **Approval prompts: already-granted candidates skipped** — Shell candidates with existing grants no longer re-trigger approval ([#1830](https://github.com/netclaw-dev/netclaw/pull/1830))
- **Approval: safe shell stages compose with grants** — Pipelines of safe stages now compose correctly with one-time grants ([#1828](https://github.com/netclaw-dev/netclaw/pull/1828))
- **Approval: background job control bypasses prompts** — `check_background_job` and cancellation no longer demand approval ([#1817](https://github.com/netclaw-dev/netclaw/pull/1817))
- **Reminders: failed one-shot executions retained** — Failed one-shot reminders retry instead of being dropped, with execution history recorded ([#1812](https://github.com/netclaw-dev/netclaw/pull/1812))
- **Approval: phantom directory scopes removed** — Stored approval patterns no longer fabricate fake directory scopes ([#1799](https://github.com/netclaw-dev/netclaw/pull/1799))
- **Approval: quoted free-text operands dropped from stored patterns** — Quoted free-text arguments are no longer baked into stored approval patterns ([#1815](https://github.com/netclaw-dev/netclaw/pull/1815))
- **Approval: trailing-slash globs scoped to parent** — `dir/`-style globs are scoped to their parent directory, closing a scope-expansion gap ([#1785](https://github.com/netclaw-dev/netclaw/pull/1785))
- **Approval: immediate-retry bypass seeded per approved scope** — Every approved scope now gets the immediate-retry bypass ([#1800](https://github.com/netclaw-dev/netclaw/pull/1800))
- **Sessions: tool-batch wedge fixed** — Unanswered tool calls are closed out before the error reply is sent ([#1796](https://github.com/netclaw-dev/netclaw/pull/1796))
- **TUI: stale provider/model state refreshed** — Provider and model manager pages no longer show stale data ([#1827](https://github.com/netclaw-dev/netclaw/pull/1827))
- **Security: ToolAccessPolicy fail-closed** — Deny-list and protected-path policies are now required; a policy missing them can no longer silently allow blocked commands ([#1787](https://github.com/netclaw-dev/netclaw/pull/1787))

### Dependency Updates
- **Bump Termina** — 0.16.0 → 0.16.1
- **Bump SkiaSharp.NativeAssets.Linux.NoDependencies** — 4.151.0 → 4.151.1
- **Bump Verify.XunitV3** — 31.20.0 → 31.28.0

## 0.25.4 (2026-08-06)

### Bug Fixes
- **MCP: live tool catalog refresh** — The daemon now re-lists healthy MCP servers' tool catalogs on a throttled cadence, so servers that add, remove, rename, or edit tools mid-session become visible to the model without a disconnect + reconnect ([#1771](https://github.com/netclaw-dev/netclaw/pull/1771))
- **MCP permissions: scroll position preserved** — Editing tool-grid rows with the left/right keys no longer jumps the scroll position back to the top ([#1775](https://github.com/netclaw-dev/netclaw/pull/1775))
- **Shell approvals: static fd-dup redirects allowed** — `2>&1` and similar static file-descriptor duplications are no longer classified as dynamic shell syntax, so safe commands like `git status 2>&1` skip the approval prompt ([#1776](https://github.com/netclaw-dev/netclaw/pull/1776))

## 0.25.3 (2026-08-05)

### Features
- **Pre-execution authorization decisions** — Tool execution now reports the authorization decision with its reason (e.g. `ApprovalExemptShellCandidates`, `StoredApproval`) instead of a bare outcome ([#1745](https://github.com/netclaw-dev/netclaw/pull/1745))

### Bug Fixes
- **TUI: Escape no longer quits the app** — Escape is now a no-op at the root of every TUI page; Ctrl+Q is the only quit key. Fixes accidental app exit ([#1765](https://github.com/netclaw-dev/netclaw/pull/1765))
- **TUI: Escape denies pending approvals** — Escape during an approval prompt now denies the request instead of quitting the app ([#1760](https://github.com/netclaw-dev/netclaw/pull/1760))
- **Slack mention rendering** — `<@user>`, `<@subteam^group>`, and `<#channel>` mentions now render as rich-text elements, including labeled and bang forms and private-channel usergroups ([#1763](https://github.com/netclaw-dev/netclaw/pull/1763))
- **Model capability discovery no longer pollutes config** — Runtime-discovered context window and modality capabilities are no longer persisted to config; operator overrides stay authoritative ([#1761](https://github.com/netclaw-dev/netclaw/pull/1761))
- **Incompatible session history degrades gracefully** — Restored history containing media the active model can't accept is stripped with a warning instead of failing the turn; newly supplied incompatible media is hard-rejected with a clear error ([#1729](https://github.com/netclaw-dev/netclaw/pull/1729))
- **`doctor` shell approval fallback aligned** — The tool-audience doctor check now matches the actual Personal-profile shell approval behavior ([#1744](https://github.com/netclaw-dev/netclaw/pull/1744))
- **Shell approvals fail closed** — Shell tool execution now fails closed when no approval candidates are produced ([#1747](https://github.com/netclaw-dev/netclaw/pull/1747))
- **Regex timeout race removed** — Prompt-injection regex matching is now race-free and culture-invariant ([#1748](https://github.com/netclaw-dev/netclaw/pull/1748))
- **Bash approval analysis gaps fixed** — Shell syntax analysis expanded to close approval bypass gaps across hosts ([#1753](https://github.com/netclaw-dev/netclaw/pull/1753))
- **Shell path approval scope hardened** — Every parsed shell path is checked against the approval scope; nested globs fail closed and symlink glob matches are rejected ([#1768](https://github.com/netclaw-dev/netclaw/pull/1768))

### Dependency Updates
- **Bump ShellSyntaxTree** — 0.2.0-alpha → 0.2.0-beta.1
- **Bump SkiaSharp** — 4.150.1 → 4.151.0
- **Bump CsCheck** — 4.7.0 → 4.8.0

## 0.25.2 (2026-08-01)

### Features
- **Provider manager: delete providers** — Providers can now be removed from the provider list via the TUI provider manager ([#1726](https://github.com/netclaw-dev/netclaw/pull/1726))
- **DeepSeek provider support** — First-party DeepSeek model provider with full provider lifecycle, model catalog, and TUI integration ([#1725](https://github.com/netclaw-dev/netclaw/pull/1725))

### Dependency Updates
- **Bump OllamaSharp** — 5.4.27 → 5.4.30
- **Bump Grpc.Tools** — 2.82.0 → 2.83.0

## 0.25.1 (2026-07-31)

### Bug Fixes
- **MCP OAuth lifecycle hardened** — Takes back client registration from the MCP SDK to prevent credential loss on upgrade; fixes `token_endpoint_auth_method` hardcoding issue with RFC 7591 ([#1708](https://github.com/netclaw-dev/netclaw/pull/1708))
- **MCP tool-level auth failures now visible** — Daemon logs MCP `isError: true` responses at warning level, fixes `netclaw mcp auth` fallback for older daemons during upgrades ([#1720](https://github.com/netclaw-dev/netclaw/pull/1720))
- **MCP permissions focus and save interaction fixed in TUI** ([#1694](https://github.com/netclaw-dev/netclaw/pull/1694))
- **Revoke the highlighted approval in TUI** — Approval revocation now targets the currently highlighted item ([#1721](https://github.com/netclaw-dev/netclaw/pull/1721))

### Internal Improvements
- **Migrate to ModelContextProtocol SDK 2.0.0** — Brings in thread-safe token cache and updated OAuth flow ([#1714](https://github.com/netclaw-dev/netclaw/pull/1714))
- **GitHub Copilot GHE: route models through advertised responses endpoint** with model catalog support ([#1707](https://github.com/netclaw-dev/netclaw/pull/1707))

### Dependency Updates
- **Bump Anthropic SDK** — 12.35.1 → 12.39.0
- **Bump Mattermost.NET** — 5.0.3 → 5.0.7
- **Bump Netclaw.SkillClient** — 0.4.0 → 0.4.1
- **Bump OpenTelemetry** — 1.16.0 → 1.17.0
- **Bump OllamaSharp** — 5.4.25 → 5.4.27
- **Bump SkiaSharp.NativeAssets.Linux** — 4.148.0 → 4.150.1
- **Bump Microsoft.SourceLink.GitHub** — 10.0.300 → 10.0.301
- **Bump Akka** — Akka.Cluster.Sharding and Akka.Persistence updated

## 0.25.0 (2026-07-18)

This stable release concludes the 0.25.0 beta cycle (five beta releases from 0.25.0-beta.1 through beta.5) and adds a round of final polish focused on installation, CLI reliability, and daemon shutdown robustness.

### Features
- **Automated shell PATH integration for installers** — Unix and Windows installers now automatically update the user's shell profile or PATH registry on install. Unix installers detect the active shell (bash, zsh, fish) and source a self-guarding `~/.netclaw/env` script from the correct RC file with duplicate prevention. Windows installers modify the User-scope PATH and broadcast `WM_SETTINGCHANGE`. Use `--skip-shell` (`-SkipShell` on Windows) to opt out ([#1687](https://github.com/netclaw-dev/netclaw/pull/1687))
- **Timestamped HMAC verification for webhooks** — Webhook routes now verify request timestamps alongside HMAC signatures to prevent replay attacks, with configurable HMAC algorithm support ([#1660](https://github.com/netclaw-dev/netclaw/pull/1660))
- **TSV support in content scanner** — Added `text/tab-separated-values` as a recognized MIME type, allowing TSV files to be scanned and processed by the content pipeline ([#1645](https://github.com/netclaw-dev/netclaw/pull/1645))
- **Preserve Git working context across sessions and subagents** — A bounded, audience-aware Git working-context snapshot (branch, worktree, repository, upstream, changed files) now stays current in the system prompt, and coding subagents inherit recent-file/project context so parent sessions merge back only confirmed successful child edits. Measured 20% → 100% success rate on a linked-worktree coding eval ([#1630](https://github.com/netclaw-dev/netclaw/pull/1630))
- **User-written `AGENTS.md` for application-specific agent guidance** — Operators can now author `~/.netclaw/identity/AGENTS.md`, layered after NetClaw's embedded operating core and inherited by sub-agents, to give the running agent deployment-specific mission and workflow guidance. Seeded with a minimal scaffold during init without overwriting existing guidance ([#1622](https://github.com/netclaw-dev/netclaw/pull/1622))
- **Discord DM reminder delivery** — Reminders can now be delivered to Discord DMs via improved `DiscordReminderTargetResolver` ([#1609](https://github.com/netclaw-dev/netclaw/pull/1609))
- **Named model configuration & provider runtime validation** — New `NamedModelConfiguration` and `ProviderRuntimeValidation` types, config schema updates, and CLI wizard improvements for provider/model setup ([#1610](https://github.com/netclaw-dev/netclaw/pull/1610))
- **SkillServer native sub-agent sync** — Optional native manifest sidecar sync for server-managed sub-agents, keeping RFC skill sync primary while downloading verified native artifacts when available. Local sub-agent files load before server-feed files so user-authored definitions always win ([#1539](https://github.com/netclaw-dev/netclaw/pull/1539))
- **GitHub Enterprise Copilot support** — Authenticate GitHub Copilot tokens against GHE instances and route requests to the correct data residency endpoint ([#1509](https://github.com/netclaw-dev/netclaw/pull/1509), [#1512](https://github.com/netclaw-dev/netclaw/pull/1512), [#1555](https://github.com/netclaw-dev/netclaw/pull/1555))
- **Slack native processing status** — Real-time processing indicators in Slack instead of generic "working" messages ([#1524](https://github.com/netclaw-dev/netclaw/pull/1524))
- **Reminder failure visibility** — Operators can now see when reminders fail or are skipped ([#1503](https://github.com/netclaw-dev/netclaw/pull/1503))
- **Degraded startup mode** — Daemon starts with a "no valid model" banner when no provider is configured, instead of failing host startup ([#1540](https://github.com/netclaw-dev/netclaw/pull/1540))
- **Synced skill resources via shell** — Skill resources synced from the cloud can now execute via shell commands ([#1551](https://github.com/netclaw-dev/netclaw/pull/1551))
- **DwarfStar (ds4) provider support** — New openai-compatible backend strategy supporting DwarfStar models ([#1349](https://github.com/netclaw-dev/netclaw/pull/1349))
- **Inherit embedded AGENTS.md for sub-agents** — Sub-agents now inherit the parent session's embedded operating rules from AGENTS.md ([#1490](https://github.com/netclaw-dev/netclaw/pull/1490))
- **Show advertised skill count for remote skill servers** — The Skill Sources config screen now displays how many skills each remote server advertises ([#1452](https://github.com/netclaw-dev/netclaw/pull/1452))

### Bug Fixes
- **MCP arguments shown in approval prompts** — Fixed: approval prompts now display full MCP tool arguments for better operator context ([#1689](https://github.com/netclaw-dev/netclaw/pull/1689))
- **CLI reports unresolved model references cleanly** — Fixed: CLI no longer crashes with opaque errors when a model reference cannot be resolved ([#1680](https://github.com/netclaw-dev/netclaw/pull/1680))
- **CLI handles model migration errors without crashing** — Fixed: model migration validation errors are now reported gracefully instead of crashing the CLI ([#1678](https://github.com/netclaw-dev/netclaw/pull/1678))
- **CLI rejects numeric model modalities** — Fixed: model modality values are now validated as strings, rejecting numeric input ([#1677](https://github.com/netclaw-dev/netclaw/pull/1677))
- **Daemon-stop session drain bounded** — Fixed: `netclaw daemon stop` now properly bounds the session drain timeout, preventing hangs on interactive-tool-paused sessions and giving the CLI adequate headroom ([#1673](https://github.com/netclaw-dev/netclaw/pull/1673))
- **Reminders rescan definitions before startup alerts** — Fixed: startup alerts now fire only after reminder definitions are fully loaded, preventing missed or duplicate reminders on restart ([#1653](https://github.com/netclaw-dev/netclaw/pull/1653))
- **OpenAI client 2.12 compatibility** — Fixed: updated OpenAI provider plugin to work with OpenAI client 2.12+ changes ([#1654](https://github.com/netclaw-dev/netclaw/pull/1654))
- **Attachment path guidance** — Fixed: authoritative attachment path guidance now points to the correct session media directory ([#1686](https://github.com/netclaw-dev/netclaw/pull/1686))
- **Windows actor checks made deterministic** — Fixed: Windows actor lifecycle tests were non-deterministic ([#1661](https://github.com/netclaw-dev/netclaw/pull/1661))
- **Ollama smoke test pinned** — Fixed: pinned Ollama installer to a specific release for smoke test stability ([#1659](https://github.com/netclaw-dev/netclaw/pull/1659))
- **VHS process group timeout** — Fixed: full VHS process group now times out properly during smoke tests ([#1655](https://github.com/netclaw-dev/netclaw/pull/1655))
- **Screenshot regression determinism** — Fixed: screenshot regression suite now uses pixel comparison with blank/partial retry and Termina seam fixes ([#1451](https://github.com/netclaw-dev/netclaw/pull/1451))
- **Legacy model environment overrides serialized** — Fixed: legacy model environment overrides are now properly serialized ([#1656](https://github.com/netclaw-dev/netclaw/pull/1656))
- **Subagent token usage tracked** — Sub-agent token usage is now properly tracked and reported ([#1597](https://github.com/netclaw-dev/netclaw/pull/1597))
- **Subagent fail-closed for unattended approvals** — Fixed: subagents fail safely when approvals are required but no human is present ([#1616](https://github.com/netclaw-dev/netclaw/pull/1616))
- **Memory core: curation documents stable** — Fixed: memory curation documents were unstable across writes, causing cross-session memory recall issues ([#1575](https://github.com/netclaw-dev/netclaw/pull/1575))
- **Model set/picker preserves modalities** — Fixed: model selection UI now preserves model modalities correctly ([#1610](https://github.com/netclaw-dev/netclaw/pull/1610))
- **Slack processing status serialization** — Fixed: Slack processing status now serializes correctly for all states ([#1556](https://github.com/netclaw-dev/netclaw/pull/1556))
- **Autonomous sessions can write workspace directory** — Fixed: autonomous sessions could not write to the workspace directory ([#1498](https://github.com/netclaw-dev/netclaw/pull/1498))
- **Reminder duplicate-execution guard** — Fixed: Mode A reminder session wedge prevented the duplicate guard from releasing ([#1500](https://github.com/netclaw-dev/netclaw/pull/1500))
- **Reset stops daemon first** — Fixed: `netclaw reset` now stops the daemon before proceeding and shows a progress screen ([#1494](https://github.com/netclaw-dev/netclaw/pull/1494))
- **MCP tool errors display cleanly** — Fixed: MCP errors now show as attributed messages instead of raw JSON dumps ([#1510](https://github.com/netclaw-dev/netclaw/pull/1510))
- **TUI: auto-advance the add-skill-server flow** — Fixed: skill server probe flow now auto-advances on successful connection ([#1458](https://github.com/netclaw-dev/netclaw/pull/1458))
- **TUI: auto-start init health checks** — Fixed: init health checks now start automatically ([#1454](https://github.com/netclaw-dev/netclaw/pull/1454))
- **TUI: discoverable Done rows** — Added "Done" back-out rows across Security & Access menus and config screens ([#1448](https://github.com/netclaw-dev/netclaw/pull/1448), [#1441](https://github.com/netclaw-dev/netclaw/pull/1441))
- **TUI: session browser selection highlight** — Fixed: session browser now shows selection highlight ([#1531](https://github.com/netclaw-dev/netclaw/pull/1531))
- **TUI: identity redo timezone loop** — Fixed: identity redo would loop on timezone; also fixed session browser regression ([#1518](https://github.com/netclaw-dev/netclaw/pull/1518))
- **TUI: flaky host crash during reset** — Fixed: thread-unsafe ReactiveProperty access during reset caused crashes ([#1525](https://github.com/netclaw-dev/netclaw/pull/1525))
- **Subagent terminal result summaries** — Fixed: subagent terminal results now display properly ([#1519](https://github.com/netclaw-dev/netclaw/pull/1519))
- **UTF-8 BOM in skill frontmatter** — Fixed: skill scanner now strips UTF-8 BOM before parsing YAML frontmatter ([#1583](https://github.com/netclaw-dev/netclaw/pull/1583))
- **Block system and external skill mutations** — Fixed: skill system now blocks mutations to system and externally-synced skills ([#1457](https://github.com/netclaw-dev/netclaw/pull/1457))
- **Self-monitoring spawn_agent liveness respected** — Fixed: tool pipeline now respects self-monitoring spawn_agent liveness ([#1456](https://github.com/netclaw-dev/netclaw/pull/1456))

### Breaking Changes
- **Removed silent local-ollama fallback** — Users without any provider configured will now see a "no valid model" banner instead of an automatic fallback to local Ollama. Explicit provider configuration is now required for full functionality ([#1540](https://github.com/netclaw-dev/netclaw/pull/1540))

### Improvements
- **Tool execution pipeline refactoring** — Restructured the session tool execution pipeline with isolated invocation scope, composed execution pipeline, typed sub-agent context isolation, and proper lifecycle cleanup ([#1641](https://github.com/netclaw-dev/netclaw/pull/1641), [#1643](https://github.com/netclaw-dev/netclaw/pull/1643), [#1644](https://github.com/netclaw-dev/netclaw/pull/1644), [#1646](https://github.com/netclaw-dev/netclaw/pull/1646))
- **Logical skill access and authoritative inventory refresh** — Skill loading now resolves through logical `skill_load`/`skill_read_resource` access with native > managed-feed > external precedence. Startup, sync, watcher, and `skill_manage` inventory rebuilds centralized through one live-source refresher ([#1634](https://github.com/netclaw-dev/netclaw/pull/1634))
- **Session actor decomposed into transient-state handlers** — `LlmSessionActor` decomposed into smaller, focused handlers for improved maintainability and testability ([#1496](https://github.com/netclaw-dev/netclaw/pull/1496))
- **Log stream partitioned by session** — Each session now gets its own `session.log` while `daemon.log` remains sparse. Cleaner logs and better observability with OTEL union support ([#1499](https://github.com/netclaw-dev/netclaw/pull/1499))
- **Memory core redesign** — Shared curation evaluator unified across both memory write pipelines so they can never diverge. July 2026 audit: revived curation LLM, balanced prompt, and recall precision re-tune ([#1575](https://github.com/netclaw-dev/netclaw/pull/1575), [#1568](https://github.com/netclaw-dev/netclaw/pull/1568))

### Security
- **Pinned Microsoft.OpenApi to 2.7.5** — Addresses CVE-2026-49451 ([#1543](https://github.com/netclaw-dev/netclaw/pull/1543))
- **Suppressed GHSA-2m69-gcr7-jv3q (SQLitePCLRaw CVE-2025-6965)** — Temporarily suppressed until upstream patches available. Tracking: dotnet/efcore#38257 ([#1444](https://github.com/netclaw-dev/netclaw/pull/1444))

### Dependency Updates
- **OpenAI SDK** — Updated to 2.12 (required for API compatibility) ([#1654](https://github.com/netclaw-dev/netclaw/pull/1654))
- **Microsoft.Extensions.AI** — 10.6.0 → 10.8.0 ([#1650](https://github.com/netclaw-dev/netclaw/pull/1650))
- **Microsoft.AspNetCore.DataProtection** — 10.0.9 → 10.0.10 ([#1657](https://github.com/netclaw-dev/netclaw/pull/1657))
- **Microsoft.NET.Test.Sdk** — 18.7.0 → 18.8.1 ([#1651](https://github.com/netclaw-dev/netclaw/pull/1651))
- **Mattermost.NET** — 5.0.0 → 5.0.3 ([#1626](https://github.com/netclaw-dev/netclaw/pull/1626))
- **SkillServer** — `Netclaw.SkillClient` 0.4.0-beta.4 → 0.4.0 (stable) ([#1638](https://github.com/netclaw-dev/netclaw/pull/1638))
- **Anthropic SDK** — 12.30.0 → 12.35.1 ([#1488](https://github.com/netclaw-dev/netclaw/pull/1488), [#1561](https://github.com/netclaw-dev/netclaw/pull/1561))
- **Akka** — Akka.Cluster.Sharding and Akka.Persistence 1.5.69 → 1.5.70 ([#1560](https://github.com/netclaw-dev/netclaw/pull/1560))
- **Testcontainers** — 4.12.0 → 4.13.0 ([#1563](https://github.com/netclaw-dev/netclaw/pull/1563))
- **YamlDotNet** — 18.0.0 → 18.1.0 ([#1516](https://github.com/netclaw-dev/netclaw/pull/1516))
- **Verify.XunitV3** — 31.19.1 → 31.20.0 ([#1446](https://github.com/netclaw-dev/netclaw/pull/1446))

## 0.25.0-beta.5 (2026-07-16)

### Features
- **Timestamped HMAC verification for webhooks** — Webhook routes now verify request timestamps alongside HMAC signatures to prevent replay attacks, with configurable HMAC algorithm support ([#1660](https://github.com/netclaw-dev/netclaw/pull/1660))
- **TSV support in content scanner** — Added `text/tab-separated-values` as a recognized MIME type, allowing TSV files to be scanned and processed by the content pipeline ([#1645](https://github.com/netclaw-dev/netclaw/pull/1645))

### Bug Fixes
- **Reminders rescan definitions before startup alerts** — Fixed: startup alerts could fire before reminder definitions were fully loaded, causing missed or duplicate reminders on restart ([#1653](https://github.com/netclaw-dev/netclaw/pull/1653))
- **OpenAI client 2.12 compatibility** — Updated OpenAI provider plugin to work with the breaking API change in OpenAI SDK 2.12 (`OpenAIClientOptions` → `ResponsesClientOptions`) ([#1654](https://github.com/netclaw-dev/netclaw/pull/1654))

### Improvements
- **Tool execution pipeline refactoring** — Restructured the session tool execution pipeline with isolated invocation scope, composed execution pipeline, typed subagent context isolation, and proper lifecycle cleanup. Fixes subagent fatal spawn failures ([#1641](https://github.com/netclaw-dev/netclaw/pull/1641), [#1643](https://github.com/netclaw-dev/netclaw/pull/1643), [#1644](https://github.com/netclaw-dev/netclaw/pull/1644), [#1646](https://github.com/netclaw-dev/netclaw/pull/1646))

### Dependency Updates
- **Bump OpenAI client to 2.12** — Required for compatibility with the updated SDK API ([#1654](https://github.com/netclaw-dev/netclaw/pull/1654))
- **Bump Microsoft.Extensions.AI** — 10.6.0 → 10.8.0 ([#1650](https://github.com/netclaw-dev/netclaw/pull/1650))
- **Bump Microsoft.AspNetCore.DataProtection** — 10.0.9 → 10.0.10 ([#1657](https://github.com/netclaw-dev/netclaw/pull/1657))
- **Bump Microsoft.NET.Test.Sdk** — 18.7.0 → 18.8.1 ([#1651](https://github.com/netclaw-dev/netclaw/pull/1651))
- **Bump Mattermost.NET** — 5.0.0 → 5.0.3 ([#1626](https://github.com/netclaw-dev/netclaw/pull/1626))

## 0.25.0-beta.4 (2026-07-14)

### Features
- **Preserve Git working context across sessions and subagents** — A bounded, audience-aware Git working-context snapshot (branch, worktree, repository, upstream, changed files) now stays current in the system prompt, and coding subagents inherit recent-file/project context so parent sessions merge back only confirmed successful child edits. Measured 20% → 100% success rate on a linked-worktree coding eval ([#1630](https://github.com/netclaw-dev/netclaw/pull/1630))
- **User-written `AGENTS.md` for application-specific agent guidance** — Operators can now author `~/.netclaw/identity/AGENTS.md`, layered after Netclaw's embedded operating core and inherited by sub-agents, to give the running agent deployment-specific mission and workflow guidance. Seeded with a minimal scaffold during init without overwriting existing guidance ([#1622](https://github.com/netclaw-dev/netclaw/pull/1622))

### Bug Fixes
- **Memory curation no longer overwrites existing documents on collision** — Fixed: when a curation Create decision targeted an anchor that already had a document, the write silently overwrote the existing title, body, and classification with no history — observed 88 times in 14 days in production, including one case that destroyed an LLM-merged document. Collisions now append the new content under a dated separator instead of overwriting; a verbatim duplicate is skipped as a no-op ([#1637](https://github.com/netclaw-dev/netclaw/pull/1637))
- **STDIO MCP server arguments no longer rewritten** — Fixed: configured STDIO MCP server arguments were being rewritten by the daemon; the daemon now preserves them as configured. Also simplified to one daemon-owned client per configured MCP server, removing Playwright-specific session-scoped process handling ([#1636](https://github.com/netclaw-dev/netclaw/pull/1636))

### Improvements
- **Logical skill access and authoritative inventory refresh** — Skill loading now resolves through logical `skill_load`/`skill_read_resource` access instead of physical skill-root paths, with native > managed-feed > external precedence. Startup, sync, watcher, and `skill_manage` inventory rebuilds are now centralized through one live-source refresher publishing atomic registry snapshots ([#1634](https://github.com/netclaw-dev/netclaw/pull/1634))

### Dependency Updates
- **Bump SkillServer to stable** — `Netclaw.SkillClient` 0.4.0-beta.4 → 0.4.0 (stable release) ([#1638](https://github.com/netclaw-dev/netclaw/pull/1638))

## 0.25.0-beta.3 (2026-07-12)

### Features
- **Discord DM reminder delivery** — Reminders can now be delivered to Discord DMs via improved `DiscordReminderTargetResolver` ([#1609](https://github.com/netclaw-dev/netclaw/pull/1609))
- **Named model configuration & provider runtime validation** — New `NamedModelConfiguration` and `ProviderRuntimeValidation` types, config schema updates, and CLI wizard improvements for provider/model setup ([#1610](https://github.com/netclaw-dev/netclaw/pull/1610))

### Bug Fixes
- **Model set/picker preserves hand-set modalities** — Re-selecting the same model no longer wipes operator-set `InputModalities`/`OutputModalities` and `ContextWindow`. Added `--input-modalities`, `--output-modalities`, `--clear-modalities`, and `--clear-context-window` CLI flags ([#1610](https://github.com/netclaw-dev/netclaw/pull/1610))
- **Slack processing status serialization** — Slack processing status updates are now serialized to prevent race conditions during concurrent sends ([#1556](https://github.com/netclaw-dev/netclaw/pull/1556))
- **Sub-agent token usage tracked in daily stats** — Sub-agent LLM calls now record token usage, making them visible in `netclaw stats` ([#1597](https://github.com/netclaw-dev/netclaw/pull/1597))
- **Subagents fail closed for unattended approvals** — When a subagent requires approval but the session is unattended, it now fails closed instead of proceeding or hanging ([#1616](https://github.com/netclaw-dev/netclaw/pull/1616))

## 0.25.0-beta.2 (2026-07-07)

### Bug Fixes
- **UTF-8 BOM in skill frontmatter** — Fixed: skill scanner now strips UTF-8 BOM (`\uFEFF`) before parsing YAML frontmatter, and populates `SkillName` on all `SkillScanIssue` records so degenerate frontmatter no longer crashes the scan ([#1583](https://github.com/netclaw-dev/netclaw/pull/1583))
- **Model capability provenance logging** — Fixed: daemon now logs effective model capabilities with their provenance source, improving diagnostic visibility for model configuration issues ([#1584](https://github.com/netclaw-dev/netclaw/pull/1584))

### Dependency Updates
- **Bump SkillServer** — `Netclaw.SkillClient` 0.4.0-beta.1 → 0.4.0-beta.3 and adapt to API changes ([#1593](https://github.com/netclaw-dev/netclaw/pull/1593))

## 0.25.0-beta.1 (2026-07-05)

### Features
- **SkillServer native sub-agent sync** — Optional native manifest sidecar sync for server-managed sub-agents, keeping RFC skill sync primary while downloading verified native artifacts when available. Local sub-agent files load before server-feed files so user-authored definitions always win ([#1539](https://github.com/netclaw-dev/netclaw/pull/1539))

### Bug Fixes
- **Systemd shell tool PATH** — Fixed: daemon now captures the operator's full PATH into the systemd EnvironmentFile instead of relying on a hardcoded list, so tools like `~/.dotnet/dotnet` are visible to the shell tool ([#1565](https://github.com/netclaw-dev/netclaw/pull/1565))

### Memory
- **Shared curation evaluator** — Unified curation logic across both memory write pipelines (inline per-session actor and daemon checkpoint-worker) so they can never diverge again ([#1575](https://github.com/netclaw-dev/netclaw/pull/1575))
- **Memory audit quick wins** — July 2026 audit: revived curation LLM, balanced prompt, and recall precision re-tune ([#1568](https://github.com/netclaw-dev/netclaw/pull/1568))

## 0.24.4 (2026-07-03)

### Bug Fixes
- **Environment-variable-only configuration** — Fixed doctor misdiagnosis and OAuth config-file side effect that prevented daemon startup when configuration is supplied entirely via environment variables ([#1569](https://github.com/netclaw-dev/netclaw/pull/1569))
- **Remote daemon CLI** — Fixed: CLI no longer demands a local daemon config file when the daemon is explicitly configured as remote ([#1567](https://github.com/netclaw-dev/netclaw/pull/1567))

### Dependency Updates
- **Bump Anthropic SDK** — 12.34.1 → 12.35.1 ([#1561](https://github.com/netclaw-dev/netclaw/pull/1561))
- **Bump Akka group** — Akka.Cluster.Sharding and Akka.Persistence 1.5.69 → 1.5.70 ([#1560](https://github.com/netclaw-dev/netclaw/pull/1560))

## 0.24.3 (2026-07-03)

### Features
- **GitHub Enterprise Copilot support** — Authenticate GitHub Copilot tokens against GHE instances and route requests to the correct data residency endpoint ([#1509](https://github.com/netclaw-dev/netclaw/pull/1509), [#1512](https://github.com/netclaw-dev/netclaw/pull/1512), [#1555](https://github.com/netclaw-dev/netclaw/pull/1555))
- **Slack native processing status** — Real-time processing indicators in Slack instead of generic "working" messages ([#1524](https://github.com/netclaw-dev/netclaw/pull/1524))
- **Reminder failure visibility** — Operators can now see when reminders fail or are skipped ([#1503](https://github.com/netclaw-dev/netclaw/pull/1503))
- **Degraded startup mode** — Daemon starts with a "no valid model" banner when no provider is configured, instead of failing host startup. Removed silent local-ollama default ([#1540](https://github.com/netclaw-dev/netclaw/pull/1540))
- **Synced skill resources via shell** — Skill resources synced from the cloud can now execute via shell commands ([#1551](https://github.com/netclaw-dev/netclaw/pull/1551))

### Bug Fixes
- **Autonomous sessions can write workspace directory** — Fixed: autonomous sessions could not write to the workspace directory ([#1498](https://github.com/netclaw-dev/netclaw/pull/1498))
- **Reminder duplicate-execution guard** — Fixed: Mode A reminder session wedge prevented the duplicate guard from releasing ([#1500](https://github.com/netclaw-dev/netclaw/pull/1500))
- **Reset stops daemon first** — Fixed: `netclaw reset` now stops the daemon before proceeding and shows a progress screen ([#1494](https://github.com/netclaw-dev/netclaw/pull/1494))
- **MCP tool errors display cleanly** — Fixed: MCP errors now show as attributed messages instead of raw JSON dumps ([#1510](https://github.com/netclaw-dev/netclaw/pull/1510))
- **TUI identity redo timezone loop** — Fixed: identity redo would loop on timezone; also fixed session browser regression ([#1518](https://github.com/netclaw-dev/netclaw/pull/1518))
- **Subagent terminal result summaries** — Fixed: subagent terminal results not displaying properly ([#1519](https://github.com/netclaw-dev/netclaw/pull/1519))
- **Flaky host crash during install reset** — Fixed: thread-unsafe ReactiveProperty access during reset caused crashes ([#1525](https://github.com/netclaw-dev/netclaw/pull/1525))
- **Session browser selection highlight** — Fixed: session browser didn't show selection highlight in TUI ([#1531](https://github.com/netclaw-dev/netclaw/pull/1531))
- **Slack active thread status refresh** — Fixed: thread status not refreshing during tool loops and buffered messages ([#1534](https://github.com/netclaw-dev/netclaw/pull/1534))
- **Stable memory handles** — Fixed: memory handles were unstable, affecting cross-session memory ([#1538](https://github.com/netclaw-dev/netclaw/pull/1538))
- **GHE Copilot routing** — Fixed: GHE Copilot chat now routes to the token's `endpoints.api` host instead of hardcoded `api.githubcopilot.com` ([#1555](https://github.com/netclaw-dev/netclaw/pull/1555))
- **Security: Microsoft.OpenApi CVE-2026-49451** — Pinned to 2.7.5 to address vulnerability ([#1543](https://github.com/netclaw-dev/netclaw/pull/1543))

### Breaking Changes
- **Removed silent local-ollama fallback** — Users without any provider configured will now see a "no valid model" banner instead of an automatic fallback to local Ollama. Explicit provider configuration is now required for full functionality ([#1540](https://github.com/netclaw-dev/netclaw/pull/1540))

### Performance
- **Log stream partitioned by session** — Each session now gets its own `session.log` while `daemon.log` remains sparse. Cleaner logs and better observability with OTEL union support ([#1499](https://github.com/netclaw-dev/netclaw/pull/1499))