v0.9.9
ScaleX-IO/uGDSv0.9.9Aug 18, 2026by github-actions[bot]
AI Summary
A truth-and-resilience release ensuring honest labeling of capabilities and preventing wedges on resource exhaustion.
Key Highlights
- Shell tool no longer wedges when disk or descriptors are exhausted.
- Context-window and output-ceiling values are now honestly labeled as 'assumed' or 'unverified'.
- Fleet scout's read-only shell carve-out is now honored by the posture gate.
- Telemetry default-on status is now visible in `codewhale doctor` output.
New Features
- Honest labeling of unverified context windows.
- Honest labeling of unverified output ceilings.
- Read-only shell carve-out for Fleet scouts.
- Telemetry visibility in runtime posture diagnostics.
Full Release Notes
> **Codewhale** is the public product from Shannon Labs. The `codewhale` > command, npm package, and release-asset names remain lowercase technical > identifiers. The legacy npm package `deepseek-tui` is deprecated and > receives no further releases. Users coming from v0.8.x legacy `deepseek` / > `deepseek-tui` names should migrate with `docs/REBRAND.md`. ## Install ### Recommended — npm (one command, both entrypoints) ```bash npm install -g codewhale ``` The wrapper downloads the matched `codewhale` and `codew` command assets from this Release. Both contain the same compiled runtime. ### Docker / GHCR ```bash docker run --rm -it \ -e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \ -v codewhale-home:/home/codewhale/.codewhale \ ghcr.io/hmbown/codewhale:v0.9.9 ``` The image exposes the same runtime as both `codewhale` and `codew`. The `latest` tag is also updated on release. ### Cargo (Linux / macOS) ```bash cargo install codewhale-cli --locked ``` The Cargo package installs `codewhale`. Cargo cannot create a second command alias from one binary target; users who want the shorter spelling can add a `codew` symlink to that installed executable. The npm, Homebrew, archive, shell-installer, and container channels install both command names directly. ### Manual download — platform archives (recommended) Each archive below contains the same runtime under the `codewhale` and `codew` command names, plus an install script: | Platform | Archive | Install script | |---|---|---| | Linux x64 | `codewhale-linux-x64.tar.gz` | `install.sh` | | Linux ARM64 | `codewhale-linux-arm64.tar.gz` | `install.sh` | | Android ARM64 (Termux) | `codewhale-android-arm64.tar.gz` | `install.sh` | | macOS x64 | `codewhale-macos-x64.tar.gz` | `install.sh` | | macOS ARM | `codewhale-macos-arm64.tar.gz` | `install.sh` | | Windows x64 (installer) | `CodeWhaleSetup.exe` | NSIS setup | | Windows x64 | `codewhale-windows-x64.zip` | `install.bat` | | Windows x64 (portable) | `codewhale-windows-x64-portable.zip` | — | | Windows ARM64 | `codewhale-windows-arm64.zip` | `install.bat` | | Windows ARM64 (portable) | `codewhale-windows-arm64-portable.zip` | — | **Unix (Linux / macOS):** ```bash tar xzf codewhale-<platform>.tar.gz cd codewhale-<platform> ./install.sh ``` **Windows:** - For the installer path, run `CodeWhaleSetup.exe`; it installs `codewhale.exe` and `codew.exe` under `%LOCALAPPDATA%\Programs\CodeWhale\bin` and adds that directory to the current-user PATH. - Extract the archive for your machine: `codewhale-windows-x64.zip` or `codewhale-windows-arm64.zip` - Run `install.bat` (copies to `%USERPROFILE%\bin`) - Add `%USERPROFILE%\bin` to your PATH The **portable** Windows archive skips the install script — extract and run from any directory. The NSIS installer is currently unsigned and may trigger Windows SmartScreen until a signing certificate is wired into the release pipeline. Each platform also has **bare, unarchived** `codewhale-<platform>` and `codew-<platform>` assets. The seven `codewhale-tui-<platform>` filenames attached to v0.9.5 are byte-identical compatibility copies used only to let already-installed v0.9.4 clients discover and cross this single-binary transition; current installers do not expose a third runtime. The legacy npm package `deepseek-tui` is deprecated and is not republished. For migration from v0.8.x legacy binary names, see `docs/REBRAND.md`. ### Verify (recommended) Download the checksum manifests from this Release and verify: ```bash # Linux — archive bundles sha256sum -c codewhale-bundles-sha256.txt --ignore-missing # Linux — individual binaries sha256sum -c codewhale-artifacts-sha256.txt --ignore-missing # macOS shasum -a 256 -c codewhale-bundles-sha256.txt --ignore-missing shasum -a 256 -c codewhale-artifacts-sha256.txt --ignore-missing ``` ## What's in v0.9.9 Codewhale v0.9.9 is a truth-and-resilience release: the shell tool can no longer wedge a session when the host runs out of disk or descriptors, unverified context windows and output ceilings are labeled honestly at every surface, DeepSeek V4 is priced on the published peak/off-peak tiers, SSE UTF-8 fails closed in every dialect, Fleet shadowing is visible, bwrap gets container essentials and extra roots, the `dsh` skin rides the bundle profile, the `agent` tool schema is down to 12 fields, and README/website locales grow to 18 and 8. ### Fixed - The lowercase `bash` tool no longer wedges when its complete-output spill file cannot be created: a full temp volume or exhausted descriptor table used to fail *every* call — `echo ok` included — with the harness-internal "Failed to create streaming shell output" and never recover until the host was cleaned up. The spill is now best-effort (the bounded tail is still returned and the truncation notice says why the full-output path is missing), and any remaining spawn/stream failure names the exhausted resource — disk, file descriptors, memory — and says the next call is safe to retry (#5465; the wedge that took out the owner's own 0.9.9 session). - A concrete route/offering output limit now outranks the conservative 8,192-token compatibility guess for an uncatalogued model. Routes that publish no output limit remain fail-closed, documented model ceilings stay authoritative, and a route limit can never raise the requested cap (#5460). - Context-window honesty at every surface (#5239, #5441): the `model-name hint` and `fallback` rungs of the context-window ladder are guesses, and every surface that renders one now says so — the status line, `/status`, `/config`, the context-pressure message, the model picker chips, and the auto-router inventory. Unverified windows still drive real budgets (compaction trigger, context meter, output reservation); they just stop reading as capabilities anyone checked. A window parsed from an `_Nk` model-name suffix (`qwen3-32b-256k` → 256K) is now its own `model-name hint` rung below `catalog`, because it is optimistic rather than conservative — a catalog or provider-reported value beats it. The `[providers.<name>] context_window` override remains the hard fix and renders as `configured` with no marker. - Output-ceiling honesty (#5440): an Anthropic-family model the catalog does not describe keeps the 64K Messages floor as its clamp and the ChatGPT/ Codex OAuth route keeps its 4K policy, but `OutputCeilingSource` gained an `unverified` rung for both, so exec-stream receipts and the model picker label them `unverified`/"assumed floor" instead of `documented`. Clamp values are unchanged. - Telemetry default-on is visible (#5441): `codewhale doctor`'s runtime-posture section gained a `telemetry=on (default)`-style row with the source that decided it (cli | env | config | default), and `codewhale config get telemetry` reports the resolved consent with its source instead of `key not found` on a machine whose batches ship. Truth change only; resolution and behavior are untouched. - Fleet: a scout's read-only shell carve-out (#5428) is now honored by both the posture gate and the execution envelope, so `git log`, `find | head`, `npm view` and the other bounded read-only commands run in-place instead of being refused as "Executes" (#5426). Delegation still never widens authority: the role-isolation test and docs/SUBAGENTS.md pin that a child cannot exceed its parent's posture (#5426, #5435). - `/rename` and `/title` now apply mid-first-turn: the session file does not exist until the first autosave, so the rename fell through with NotFound; the shared path now prefers the per-session checkpoint and rebuilds from App state, with a PTY regression test through the live event loop (#5430). - `integrations dsh plan` no longer refuses DeepSeek's default Responses-dialect route (`deepseek-v4-flash`); Responses and Anthropic-Messages routes are carried through pi-ai `openai-responses` / `anthropic-messages` instead of being approximated or refused; only credentialed base URLs are still refused, with an error that names provider and model (#5434). - Session cost no longer sits at `unverified_live_pricing` when live pricing cannot be verified (control-plane 503, Models.dev capabilities-only overlays): provider-docs bundled fallback rates for the DeepSeek V4 family on Fireworks / OpenCode Zen restore a usable figure, live per-provider rows still win, and `kimi-k3` stays unpriced until a published rate exists (#5241; harvested from #5402). - Release assets: `release.yml` asset-freshness checks compare against the release job's own `started_at`, so job-level reruns of the npm step are no longer poisoned by earlier uploads (#5429). - macOS CI: the `agent_focus_pty` auto-review receipt test waited on a worker that had already completed and raced the rail's focus; it now holds the child's wrap-up and waits for a settled live row (refs #5056, #5403). - DeepSeek V4 pricing follows the published peak/off-peak tiers (peak 01:00–04:00 and 06:00–10:00 UTC; off-peak is half of peak) for `deepseek-v4-flash` and `deepseek-v4-pro` in USD and CNY, resolved from each turn's recorded time; the stale single-tier rows understated cost up to ~4×. Because every direct DeepSeek first-party rate is now time-windowed, the scorecard fails closed (`missing_recorded_time`) on an undated DeepSeek turn instead of guessing a tier (#5470; #5241 follow-up, verified against api-docs.deepseek.com on 2026-08-17). - SSE UTF-8 split across HTTP/2 DATA frames now fails closed in every streaming dialect: a shared strict decoder, tail flush, and `decode_failed` propagation (`InvalidSseUtf8`) replace the per-dialect approximations, with byte-chunk decoder tests (#5374; supersedes draft #5404). - CI: `release_four_read_only_fleet_roles_launch_with_canonical_prompts` answered Fleet children with SSE while they call the blocking JSON path; the parse failure was retried and double-counted the worker on slow macOS runners (#5471; refs #5056). - Context: every web tool surface (`Web`, `web_search`, `web.run`, `fetch_url`) now uses the noisy-result soft limit, so large fetches are compacted like shell output instead of consuming the ordinary hard limit (#5474, thanks @h3c-hexin). - Routing: a lowercase saved selector such as `glm-5.2` resolves against the owning Z.ai / DeepSeek catalog row (case-fold fallback, only when exactly one provider-owned wire id matches) instead of being classified as another provider's bare model (#5475, thanks @h3c-hexin; diagnosis by @asto18089 in Pinvou/CodeWhale#14). - Model catalog brought current as of 2026-08-17 against the official pricing pages: gpt-5.6-terra / gpt-5.6-luna rates, `claude-sonnet-5` keeps $2/$10 (the announced September increase was withdrawn), `claude-opus-5` added, `kimi-k3` and `kimi-k2.7-code-highspeed`, `MiniMax-M2.7-highspeed`, Mistral first-party rows, xAI `grok-4.5` / `grok-4.3` with long-context tiers, Gemini and Qwen limits, and RedNote's `dots3-note` preview as an OpenRouter row (no first-party API exists yet) — every number carries its source and a pinned test (#5485). - Website: copy on codewhale.net rewritten in plain declarative sentences — one idea per sentence, numbers from the generated facts, no self-narration — with a voice sheet at docs/design/WEB_VOICE.md (#5483). - CI: the release workflows no longer restore npm/cargo caches after checking out a caller-supplied SHA — the CodeQL cache-poisoning Highs #88–#107 are closed with a contract test over the workflow files (#5463). - Compact TUI rows below 60 columns no longer reserve a hidden session-metrics strip, so narrow terminals reclaim the row instead of clipping the transcript (#5486). - Ghostty's truecolor underwater field now uses a dedicated synchronized 60 FPS lane instead of the legacy 30 FPS compatibility cap, with continuous caustic fades replacing visibly stepped color changes. - Live reasoning's advertised `Space:expand` action now runs before the composer's first-character paste-burst hold, while spaces in an active paste remain payload. The newest reasoning preview also spends only genuinely free viewport rows before truncating instead of stopping at the fixed 10/12-row fallback on roomy terminals. - Strict `cargo doc` builds no longer fail on bare URLs in rustdoc comments; the remaining links are explicit Markdown targets (#5489). ### Changed - The model-facing `agent` tool advertises exactly 12 fields — `action`, `prompt`, `type`, `profile`, `name`, `agent_id`, `message`, `until`, `detached`, `worktree`, `write_roots`, `resume_from` — down from 33 (#5324, refs #5123). Budgets (`max_steps`, `wall_time_secs`, `max_depth`), routing overrides (`model`, `model_strength`, `thinking`), worktree-path knobs, the deliberate/spawn-contract fields and the wait/status/interrupt extras moved off the advertised schema. Every removed field stays parse-accepted and honored unchanged (same contract as `token_budget`), so saved transcripts, ACP/MCP clients and Fleet configs replay as-is; the #5426/#5435 containment clamps are untouched. Child budgets now resolve from role defaults (60/120 turns, 1800 s wall time, unchanged clamps) and new `[subagents]` keys `default_max_steps` / `default_wall_time_secs`. Because the tool catalog is part of the session-pinned prompt prefix (docs/CACHE.md), upgrading re-fills the KV prefix once per session. - TUI prose — user messages, assistant answers, and reasoning/thinking — now wraps at the full content width on wide terminals, matching tool/status cells, instead of stopping at a 105-column rail that left a dead right margin on ultrawide displays (#5436). - Configured skill prompts are stable across session roots and operating systems: only custom configured roots hide their physical path, ordinary workspace/global skills keep a discoverable privacy-safe path, warning replacements are boundary-aware (including non-UTF-8 Unix paths), and Windows separators render as `/`. The skills prompt is also 50 bytes leaner without raising a runtime-contract ceiling (#5492, #5473). - Auto-router classifier requests accept `[auto.router] timeout_secs`, while preserving the existing default when the key is absent (#5494). - Every `ci.yml` job now has an explicit 10–90 minute timeout appropriate to its workload, bounding stale assigned runners instead of inheriting GitHub's six-hour default (#5495). - The docs shell and shared web components now route localized copy through the typed dictionary spine; these are two incremental phases of #5337, not completion of the full epic (#5488, #5490). - Dependency: rusqlite 0.40.2 (#5391). - Documentation: stale A/B/C-tier references, provider defaults, module descriptions, and line anchors now match the current code (#5481). ### Added - `[transcript] prose_measure` (positive integer, optional): caps prose wrap at N columns for owners who want a bounded reading measure on ultrawide terminals. `0` or absent keeps the full width; negative or non-integer values are rejected with a clear config error. Tool, diff, and status cells never inherit the cap (#5436). - Localization: README translations for Français, Deutsch, 繁體中文, हिन्दी, Türkçe, Italiano, Polski, العربية and Català join the existing nine (#5451); codewhale.net routes fr, de, ca, hi, tr, it, pl and ar (with `dir="rtl"` plumbing) as partial locales (#5453). - Docs: README Integrations section (incl. the DeepSeek Harness `dsh` plugin path, docs/INTEGRATIONS_DSH.md) localized across all READMEs; RFC keeping the deterministic-first auto-review hybrid (#5427); Claude Code parity reference for agents/workflows/plugins/skills (docs/design/CLAUDE_CODE_PARITY.md); config.example.toml / SUBAGENTS.md / TOOL_LIFECYCLE.md brought back in line with the code (#5447). - `dsh` integration: the Codewhale palette is applied through the bundle profile via dsh's documented `overrideTokens` (on by default; `codewhale integrations dsh update --skin false` turns it off), replacing the 0.9.8 exported-CSS skin that dsh's inline body variables overrode (docs/design/DSH_BUNDLE_SKIN.md, docs/INTEGRATIONS_DSH.md) (#5469). - `dsh` integration: an ambient ocean scene behind the DSH web UI — slow whale silhouettes, a school of `><>` glyph fish, bubbles — drawn on a canvas under a translucent veil of the Codewhale palette, plus an explicit responsive `WHALE BROTHERS / CODEWHALE × DEEPSEEK HARNESS` lockup; light and dark, ~30 fps capped, paused when hidden, a static frame under `prefers-reduced-motion`; on by default with the skin, `codewhale integrations dsh update --ocean false` turns it off (#5484). - Fleet: agent shadowing is visible — a roster-row badge, a Layers block in agent detail, and a `doctor` "Fleet roster layers" section (JSON `operate_fleet.roster.multi_layer`), in all 15 TUI locales. Layer collapse and `[fleet.profiles]` migration stay for 0.9.10 (#5098). - Sandbox: bwrap containers get the `--dev/--proc/--tmpfs` essentials plus configurable extra roots (`bwrap_ro_roots` / `bwrap_dev_roots`) so toolchains that live outside the workspace stay reachable read-only (#5410). - Tests: `crates/tui/tests/README.md` states the keyless assembled-journey rule and maps the Auto-Review guardian acceptance items to the engine journeys that exercise them (#5361). - OrcaRouter's default endpoint is classified as an aggregator billing surface, so pricing and session-cost reporting use the correct billing posture instead of treating it as a first-party provider (#5493). - Dependencies: ratatui 0.30.2, thiserror 2.0.20. ### Removed - `dsh` integration: the exported-CSS skin file and its "skin export" status line (superseded by the bundle-applied `overrideTokens` skin, #5469). ## Contributors - hexin (@h3c-hexin) — a concrete route/offering output limit outranks the 8,192-token compatibility guess for an uncatalogued model (#5461, closes #5460); web tool results use the noisy soft limit (#5474); owned direct model casing resolves safely (#5475); and configured-skill prompts stay stable across ephemeral roots and operating systems (#5492, #5473). - Gabriel-Degret (@Gabriel-Degret) — configurable auto-router classifier timeout (#5494; first contribution). - @asto18089 — diagnosed the Z.ai `glm-5.2` casing collision and wrote the first provider-scoped fix in Pinvou/CodeWhale#14 (carried upstream in #5475). - Reports and reproductions that shaped this release: @hardy922 (context- window honesty, #5239), @redstar (bwrap extra roots, #5410), @all-lopezg (SSE UTF-8 garbling on DeepSeek Flash, #5374), @alitvak69 (unverified live pricing, #5241), and @wuisabel-gif (the macOS filtered-suite hang investigation on #5056). See [CHANGELOG.md](https://github.com/Hmbown/CodeWhale/blob/main/CHANGELOG.md) for full notes and [docs/CHANGELOG_ARCHIVE.md](https://github.com/Hmbown/CodeWhale/blob/main/docs/CHANGELOG_ARCHIVE.md) for older releases.