v0.9.0

Hmbown/Codewhalev0.9.0Jul 16, 2026by github-actions[bot]

AI Summary

Codewhale v0.9.0 replaces the default terminal shell with the underwater interaction system, makes Operate message-first, and hardens Fleet/Workflow. It rebrands to 'Codewhale'.

Key Highlights

  • Underwater interaction system with ambient life and new TUI renderer.
  • Operate is now a message-first multitask surface.
  • First-class Provider lake with live catalog discovery.
  • Workflow runs are now durable with typed receipts.
  • Korean (ko) UI locale is fully supported.

Breaking Changes

  • Removed the deprecated `deepseek` and `deepseek-tui` binary shims.
  • Removed the deprecated `deepseek` and `deepseek-tui` npm package.
  • YOLO mode is deprecated (maps to Act + Full Access).

New Features

  • Underwater TUI renderer.
  • Operate message-first mode.
  • Provider lake facade.
  • Workflow durability.
  • Hotbar sources for MCP tools and skills.

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 binaries)

```bash
npm install -g codewhale
```

The wrapper downloads the matched runtime binaries from this Release and places them in the same directory.

### 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.0
```

The image ships the `codewhale` dispatcher, `codew` shim, and `codewhale-tui` runtime. The `latest` tag is also updated on release.

### Cargo (Linux / macOS)

```bash
cargo install codewhale-cli codewhale-tui --locked
```

Both crates are required — `codewhale-cli` produces the `codewhale` dispatcher and `codew` shim, while `codewhale-tui` produces the interactive runtime that the dispatcher delegates to. Installing only one crate will fail at runtime with a `MISSING_COMPANION_BINARY` error.

### Manual download — platform archives (recommended)

Each archive below contains the `codewhale` dispatcher, `codew` shim, and `codewhale-tui` runtime, 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` | — |

**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`, `codew.exe`, and `codewhale-tui.exe` under `%LOCALAPPDATA%\Programs\CodeWhale\bin` and adds that directory to the current-user PATH.
- Extract `codewhale-windows-x64.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** binaries attached below (`codewhale-<platform>`, `codew-<platform>`, and `codewhale-tui-<platform>`) — the npm wrapper and the in-app `codewhale update` download the matched runtime binaries, whereas the `.tar.gz` / `.zip` archives above are the recommended manual download and additionally bundle an install script. 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

# Linux — individual binaries
sha256sum -c codewhale-artifacts-sha256.txt

# macOS
shasum -a 256 -c codewhale-bundles-sha256.txt
shasum -a 256 -c codewhale-artifacts-sha256.txt
```

## What's in v0.9.0

Codewhale v0.9.0 replaces the default terminal shell with the underwater
interaction system, makes Operate message-first, and hardens the Fleet,
Workflow, routing, accounting, and release surfaces that support day-to-day
agent work. The release also expands localization and gives the public site a
quieter, docs-first community foundation. Its provider work replaces the old
hand-maintained picker boundary with live ProviderLake discovery and adds the
largest curated model-and-pricing expansion in the project so far.

### Fixed — final integration

- Redact configured, environment, file-backed, and bare active credentials
  from every tool result before it crosses any model-provider wire protocol;
  retrieved spillover content is sanitized again at that boundary. The
  `read_file` tool also refuses CodeWhale configuration, backup, and
  credential-store paths, preventing routine tool use from exposing those
  local files.
- Keep immediate TUI submit failures inside the shell: custom-provider route
  preflight and closed-mailbox errors now restore the exact composer draft and
  selected skill for retry, with a sticky visible error instead of exiting.
- Anchor automatic compaction thresholds to the route's spendable input
  budget after output reservation and safety headroom, so large-output and
  tight self-hosted routes compact before provider context rejection. The TUI
  pre-send gate and warning copy now use the same token threshold as the
  engine. Preserve the 262K Kimi route's usable input budget and use the
  documented 32K default generation budget instead of mirroring the context
  window as output (#4293 by @SamhandsomeLee, #4368 by @bruce6135, and #4378
  by @mvanhorn).
- Fail closed instead of reporting base-rate dollar estimates for direct OpenAI
  GPT-5.4/5.4 Pro, GPT-5.5 (including dated snapshots), and GPT-5.6
  Sol/Terra/Luna requests above 272K input tokens. Exact tiered accounting
  remains deferred to the generalized pricing schema; smaller 5.4 variants,
  GPT-5.5 Pro, Codex subscription, and foreign-provider routes are unchanged
  (#4317).
- Retire `deepseek-chat` and `deepseek-reasoner` before they reach DeepSeek's
  first-party OpenAI or Anthropic wire APIs, migrating both to the documented
  `deepseek-v4-flash` replacement while preserving legacy non-thinking /
  thinking intent when no explicit reasoning tier is set. Aggregator, Wanjie
  Ark, self-hosted, and custom endpoint model ids remain provider-owned (#4320).
- Make Operate a message-first multitask surface: ordinary prompts work without
  a Workflow, direct parent tools follow the same approval, sandbox, shell,
  ask-rule, and repository protections as Act, and follow-ups can queue while
  work is active. Bounded background workers remain preferred for independent,
  parallel, isolated, or long-running work; child handoffs cannot inherit
  standing Full Access, and each dispatch produces one durable completion
  receipt.
- Let personal Fleet profiles in `CODEWHALE_HOME/agents` travel across
  repositories while project profiles in `.codewhale/agents` override them.
  Saving refreshes the live roster, and the UI now says explicitly that profile
  availability does not expand workspace, trust, or filesystem authority.
- Move file-mention discovery onto one bounded, generation-safe background
  worker so a slow filesystem read cannot freeze composer input. Exact paths
  resolve on send; fuzzy matches stay in the completion popup instead of
  silently attaching an arbitrary same-name file (#4365 by @WavesMan, with the
  initial bounded-walk approach from #4367 by @LeoLin990405).
- Keep the opt-in `remember` tool in the model-visible first-turn catalog so
  durable preference capture works without requiring a model to discover a
  tool it cannot yet know exists (#4373 by @Angel-Hair and #4377 by
  @mvanhorn).
- Make `review` handle a staged snapshot relative to a base ref by comparing
  the branch merge-base tree with the index. This preserves committed and
  staged branch work, excludes unstaged edits, and avoids the invalid
  `git diff --cached <base>...HEAD` form.
- Honor each MCP server's advertised discovery capabilities before calling
  optional tools, resources, templates, or prompts; keep optional probes
  independently bounded and fail-soft (#4308 by @nsfoxer).
- Make offline `scorecard` pricing provider-aware: `turn_end` records carry the
  effective route and a non-secret billing surface, runtime exports and
  supported aliases ingest cleanly, legacy/unknown routes remain explicitly
  unpriced, and route-scoped cache and recorded-time pricing replace model-only
  guesses. Historical runtime aggregates use each turn's recorded time;
  costless catalog routes fail closed while exact provider-owned hand-price
  rows remain available. StepFun PAYG and Step Plan usage now stay distinct
  without persisting raw endpoint URLs, so subscription quota is never reported
  as token spend (#4335). Completion-only shell, manual-compaction, and purge
  events remain visible to `turn_end` observers as explicitly non-model
  lifecycle records. This builds on the scorecard introduced by @findshan in
  #3388.
- Preserve named custom-provider identity across TUI sessions, `exec --resume`,
  runtime threads, exports, cache and Workflow receipts. Restores resolve the
  saved provider against live configuration before creating a client, never
  infer a provider from the model ID, and fail closed when the named route was
  removed, invalid, or ambiguous (#4334).
- Bind credentials to the endpoint that owns them. Environment-selected custom
  hosts can no longer inherit saved provider keys, keyring entries, OAuth, or
  ambient provider variables; only an explicitly source-marked CLI key may
  follow an explicit CLI endpoint override. `auth_mode = "none"` also strips
  credential-shaped custom headers consistently in the TUI and app server,
  while keyless loopback routes remain usable as local runtimes.
- Make hosted runtime threads deterministic and provider-exact: serialize
  thread, turn, and event mutation; keep cancellation ownership with the host;
  preserve the selected provider through every durable turn; terminalize
  exceptional streams once; and prevent the runtime manager from silently
  dispatching unclaimed goal continuations or child turns.
- Treat required user confirmation as a real goal blocker instead of a failed
  goal, and explain how to recover when a previously cached approval is denied.
  Cached-denial recovery is also committed as a settled transcript receipt, so
  tool completion or a later status update cannot erase it from scrollback or
  accessibility output. The notice now describes matching, process-scoped
  denials truthfully across all shipped locales; approval audits honor
  `CODEWHALE_HOME`, and expired status toasts cannot remain trapped behind a
  persistent entry. Both states remain visible and actionable instead of
  looking like unexplained model or tool failure (#4374 and #4375 by
  @Angel-Hair, with the final hardening in #4385 by @nightt5879).
- Make Fleet launch and teardown deterministic: route flags are placed before
  `exec`, workers are contained in owned Unix sessions or Windows Job Objects,
  and cancellation reaps surviving descendants with bounded escalation before
  manager state settles. Fence progress, terminal status, verification
  receipts, and evidence by durable attempt generation so a stale process can
  never complete or overwrite a restarted attempt; terminal state and receipt
  now commit atomically, stale-heartbeat decisions use a full lease CAS,
  exhausted-retry alerts are exactly once, and crash-truncated ledger tails are
  quarantined before the next append. Standalone CLI and Runtime API restart
  controls now drive the replacement attempt through a real executor to its
  terminal receipt, while per-run manager ownership prevents concurrent
  controllers from launching the same attempt twice.
- Keep the stopship Workflow fixture bounded to measured 24k-per-turn role
  budgets and a 360k aggregate. Authored child step and wall-time limits now
  reach the live runtime, including launch-queue wait; promoted evidence stays
  intact between roles, tool-free handoff consumers omit tool fields on the
  provider wire, and a terminal `BLOCK` fails the Workflow instead of producing
  a successful Lane receipt. Free-form descriptions no longer fabricate write,
  shell, or network risk; unknown structured risk remains fail-closed.
- Keep repository trust affirmative and explicit: only `1`/`Y` are advertised
  as acceptance keys, while Enter remains non-affirmative and explains the
  required choice.
- Replace literal legal and doctrinal metaphors in Simplified Chinese setup and
  `/constitution` copy with direct collaboration terminology reviewed by a
  native speaker (#4369 by @hmr-BH).
- Keep the transcript reviewable while an inline approval card is active:
  Page Up/Down, modified arrows, Home/End, and the mouse wheel now move through
  the visible evidence without changing or dismissing the pending decision
  (#4371 by @amuthantamil).
- Match generated worker names to the active UI language while preserving
  explicit user names, and tighten the 89x50 shell rhythm across Fleet rows,
  choice dialogs, transcript boundaries, and the idle composer.
- Put docs content and search before the full index on small screens, reduce
  mobile dead space, and keep the public community copy focused on issues,
  pull requests, and international contributors.

### Changed — the underwater shell

- Replace the default TUI shell with the underwater interaction system: one
  renderer owns the header, top work strip, transcript ledger, composer, and
  footer, with explicit compact/normal/wide tiers and no legacy sidebar or
  dashboard in the default path. The legacy composition survives only behind
  the internal `classic` treatment.
- Add a distinct pre-session launch screen — new session, new worktree (with
  inline naming and real lane provisioning), scoped resume count, changelog,
  quit — with reliable non-colliding keys and row/keyboard parity.
- Render turns as a ledger: user message, short narration, settled tool
  receipts, and exactly one live row. Fast tool bursts land directly as
  batch receipts (no spinner churn), completed receipts stay inspectable,
  failures hold a coral receipt with stderr one `v` away, and one shared
  tool rail replaces nested card borders.
- Make completion a one-shot exhale: `working -> finishing -> done` in the
  footer only, with no transcript repaint, no lingering loop, and no stale
  cancel action in the completed state.
- Rebuild the secondary rooms on one hairline grammar — config, setup,
  sessions, help, context, theme, model/route, Fleet, file attach — each
  with a title hairline, row objects with focus/selection/mouse parity,
  one panel-owned scroll rail, and wrapped action footers.
- Make `/model` a model-first atomic route picker across configured
  providers: provider and model switch together on apply, and every row
  prints the resolved model. `/theme` gains a live preview with truthful
  Esc revert across all 12 shipped themes.
- Add a live context inspector (Alt+C) backed by the current route: exact
  system/messages/free token buckets, a proportional map, drill-down into
  the detail pager, and no frozen session while it is open.
- Project Workflow runs as an in-stream run map: a collapsed one-line card
  that unfolds into per-lane rows with role, resolved model, worktree,
  elapsed track, and per-member running/waiting/failed/cancelled/done
  states, plus gates and a debrief built only from real run data. Child
  transcripts never flood the parent shell.
- Unify Fleet into roster/setup/workers rooms: the operator is pinned first
  with the live session route, members show resolved route truth (inherit /
  fast lane / pinned), and the workers tab is a control surface with
  row-local open/stop and real lifecycle counts.
- Distinguish repository-law approvals from ordinary approvals: the
  constitution prompt names its authority, source, matched rule, and target,
  and Full Access never bypasses it. Ordinary approvals render as a still
  coral band above the visible transcript.
- Keep streaming honest and cheap: provider-unit deltas replace per-grapheme
  queueing, the transcript is top-anchored so appended lines stop shifting
  settled rows, ambient animation stops during real work, and ordinary
  completion no longer triggers full-screen clears (verified by render-diff
  logs: suffix updates of tens of cells while streaming, zero periodic
  full repaints).
- Give every underwater treatment ambient life: ombre breathes its water
  column while flat and Terminal-owned keep the idle fish and bubble
  (foreground-only for Terminal), a typed treatment setting replaces string
  comparisons, reduced motion freezes life legibly, `fancy_animations =
  false` stills the chrome, and typing scatters the fish immediately. Fish
  keep a one-cell gap from occupied text; the whale remains the single brand
  mark and returns to stillness between caustic sweeps.
- Bring the whale mark to life with a soft diagonal caustic sweep, then let it
  genuinely rest. Active markers now share a smoother 8 Hz clock after the
  existing earned-motion delay, while reduced motion, hidden/off-screen views,
  modal ownership, and compact-terminal redraw budgets remain authoritative.
  The motion is adapted from the Apache-2.0 Grok Build interaction language,
  not copied as a global pulse or high-frequency receipt cascade.
- Keep compact terminals operable: `/config` and `/resume` collapse
  secondary chrome before sacrificing their selectable rows at 40x12 and
  60x16, bodies budget for the footer's real wrapped height, and the
  selection stays visible through resizes.
- Route footer notices through the classified toast system so informational
  acknowledgements (for example "Auto-compaction enabled") expire instead of
  becoming permanent idle chrome, while warnings and errors hold as sticky
  notices until their window passes.
- Complete the `CODEWHALE_ASCII_SAFE=1` decorative tier: the whale mark,
  context meter, braille state markers (mapped by dot density so the working
  bubble still reads as a rising fill), bubbles, rails, and role/lane glyphs
  all narrow to semantic ASCII while user, model, and CJK text passes
  through untouched. Verified by whole-surface rendered-buffer sweeps.
- Repair the Help catalog to match handler truth (`Alt+G`, `Alt+Shift+G`,
  `Alt+[`, `Alt+]`, `Alt+L`, `Alt+?`), and give theme, Help, model, and
  config rows direct mouse paths with the same activation as Enter.

### Changed — integrated runtime and TUI

- Make worker delegation route-aware and identity-safe: workers receive a
  small role-scoped system prompt instead of stale parent/model boilerplate,
  faster routes resolve through the configured provider, and opening a worker
  shows its complete available transcript. Remove `token_budget` from the
  ordinary model-facing Agent schema so agents do not micromanage ad-hoc
  launches; explicit legacy calls remain readable for compatibility.
- Mature `/config` interaction for enumerated and boolean settings with
  pickers/toggles, mouse-wheel scrolling, stable focus, and configured-provider
  selection. Startup mode is now only Agent or Plan; legacy `operate`/`yolo`
  settings migrate to Agent with permission posture represented separately.
- Show where effective permission policy comes from and keep profile,
  environment, project, managed, and requirements-controlled posture read-only
  in the in-session editor. Runtime presets edit only proven user-owned root
  settings and no longer persist temporary environment overlays.
- Restore the original four-line whale mark and make ambient ocean motion
  coherent across the full scroll surface: one continuous ombre, eased fish
  that face their direction of travel, fish in otherwise blank scrollback, and
  explicit reduced-motion and animation controls.
- Keep model reasoning in the transcript rather than the Tasks strip, retain
  the live header status indicator, separate worker and success colors, and use
  the same rail grammar for both work-strip and transcript scrollbars.
- Present the default Z.AI Coding Plan route, including child routes, as
  subscription quota instead of estimated per-token dollars. No undocumented
  account endpoint is called by this change.

### Added

- Thinking Machines Lab's Inkling through Together using the exact wire model
  `thinkingmachines/inkling`, with `inkling` and `together-inkling` aliases and
  exact `none` / `minimal` / `low` / `medium` / `high` / `max` reasoning
  values. Codewhale does not invent a context window, price, or offline picker
  claim while the provider's public catalog metadata remains inconsistent.
- Expand the verified offline catalog with Claude Sonnet 5, Claude Fable 5,
  GPT-5.3 Codex, and Qwen3.7 Plus, including time-aware Sonnet 5 introductory
  pricing and explicit cache rates. Refresh stale GLM-5.1, Kimi K2.6, Trinity,
  Qwen3.6, Nemotron, Anthropic, GLM-5.2, Kimi K2.7 Code, GLM-5 Turbo, and
  GPT-5 Codex price or limit rows; keep Xiaomi MiMo explicitly unpriced where
  the provider's token plan and pay-as-you-go surfaces cannot be distinguished.
- MiniMax Messages provider support for MiniMax-M3 and MiniMax-M2.7, with
  OpenAI-compatible and Messages routes, regional endpoint guidance, request
  coverage, catalog limits, and tier-aware pricing (PR #4354 by @octo-patch).
- Dynamic MCP server infrastructure and an approval-gated tool that lets the
  model start a configured MCP server from chat context. Harvested from
  #3869 and #3866 by @bistack with authorship preserved.
- Parent `--disallowed-tools` restrictions now flow into sub-agents and Fleet
  workers by default, including deny-wins, wildcard, catalog-filtering, and
  multi-generation inheritance coverage. Harvested from #4096 by @JayBeest
  (#4042).
- Korean (ko) UI locale with full key parity and onboarding/setup wiring
  (PR #4347 by @moduvoice).
- Localize the entire underwater layer: 104 new UI strings — launch menu,
  phase words, mode/permission chips, footer hints, session picker, context
  inspector, route and theme pickers, Fleet roster, workflow status, sidebar
  work strip, repository-law approval copy, and file-attach titles — wired
  through MessageIds and translated into ja, zh-Hans, es-419, pt-BR, vi,
  and ko. Every complete pack now holds exact raw key parity with English
  (856 keys), enforced by new tests that the old English-fallback gate could
  not perform. The permission chip maps from typed state, so localization
  can never silently collapse it. Machine-authored translations follow each
  pack's existing terminology and are flagged for native review.
- Anthropic adapter: sanitize top-level `oneOf`/`anyOf`/`allOf` in tool
  input schemas so affected tools no longer fail the whole request with
  HTTP 400 (PR #4346 by @qinlinwang).
- Anthropic pricing: bill cache-write tokens at published rates
  (PR #4348 by @knqiufan, #4318).
- NetBSD: generate QuickJS bindings at build time so `codewhale-workflow-js`
  compiles (PR #4349 by @ci4ic4).
- Real-PTY release gates for six-worker fan-out liveness with Esc cancel,
  multi-terminal route isolation, queued steering via terminal-safe Ctrl+G
  (with Ctrl+S retained where the terminal forwards it), the one-shot
  completion footer, and per-theme ANSI output for every shipped palette.

### Fixed

- Make release publication complete and source-anchored: every build checks out
  the resolved tag commit, tag movement is rejected before GHCR, GitHub
  Release, Homebrew, Cargo, or npm writes, and registry helpers require a clean
  checkout exactly matching the remote tag. Manual recovery runs are
  exact-tag-only and execute the same parity gate as automatic tag pushes.
- Publish a coherent distribution set: both checksum manifests now contain
  usable public basenames and cover the full 29-asset matrix; GHCR, Homebrew,
  GitHub archives, and the Linux x64 CNB mirror carry `codewhale`, `codew`, and
  `codewhale-tui`. The CNB shortcut now fails clearly outside Linux/OpenHarmony
  x64 instead of promising assets that the mirror does not build.
- Preserve task text when a skill is invoked through dollar, unified-slash, or
  explicit skill syntax, while keeping bare skill invocations and management
  subcommands intact (PR #4372 by @nightt5879, co-authored by @CCChisato;
  #3915).
- Honor MCP server discovery capabilities: require advertised or legacy
  `tools/list`, keep optional resource/template/prompt probes independently
  bounded and fail-soft, and format descriptions Unicode-safely (#4308,
  harvested with co-authorship from @nsfoxer).
- Age-evict terminal sub-agent worker records from the state ledger so
  long-lived, high-fan-out sessions do not keep rewriting multi-megabyte
  terminal history (#4217; root-cause and fix direction from @yekern).
- Resolve the sub-agent completion/cancellation race with one terminal-state
  claim: cancellation suppresses late mailbox/parent/UI delivery, while a
  completed result remains publicly running until its notification is safely
  delivered.
- Keep Workflow panel controls from stealing ordinary composer letters. Enter,
  Delete, Up/Down, and Esc own panel actions; typed characters return focus to
  the composer and start the message normally.
- Preserve the composer prompt gutter from the first typed character through
  wrapping, scrolling, cursor placement, and mouse hit-testing so the `>` does
  not disappear or make input appear to jump.
- Emit terminal-native OSC 8 metadata for rendered URLs without placing escape
  payload bytes in the measured text, keeping long links visible, selectable,
  and clickable in supporting terminals.

- Keep headless structured output terminal-clean: `codewhale exec` engines
  no longer emit interactive terminal-title/taskbar OSC sequences, so
  `--output-format stream-json` stdout stays parseable, escape-free JSONL.
  Interactive TUI sessions keep their terminal chrome.
- Localization honesty: the parity gate was blinded by its own English
  fallback — two keybinding rows (`KbCyclePermissions`, `KbCycleThinking`)
  were missing from all five "complete" packs and now ship translated; the
  Operate-mode copy that drifted in English was retranslated in every pack
  (including zh-Hant's slice); three MessageIds absent from
  ALL_MESSAGE_IDS are visible to tests again; and the `/config`
  theme/locale hints and the invalid-locale error derive from the shipped
  registries instead of stale hand lists that advertised 4 of 12 themes
  and 4 of 8 locales.
- The setup wizard's constitution step no longer claims a "55-line core"
  in any language (the bundled core is larger today); the guided draft says
  "the bundled core stays active" instead.
- In-app selection copy is rail-clean and now regression-tested: copied
  transcript text excludes the `▎ ╎ │ ●` decorations via cache metadata
  (#4208 — thanks @eugenicum for the report and code-aware fix direction;
  terminal-native selection with mouse capture off remains a product
  decision on the proposed `rail_style` option).

### Docs

- Stamp every 0.9-era roadmap document with an explicit status (current,
  historical, superseded, principle-only, or future RFC), correct trackers
  that recorded unshipped work as done, and describe what remains after
  v0.9.0 in `docs/AGENT_RUNTIME.md`.
- Add `docs/rfcs/UNIFIED_PROVIDER_LOGIN.md`: one `codewhale auth login`
  surface for Anthropic, OpenAI Codex, and xAI, with the Anthropic adapter
  gated on verifying flow permissions before any constants are adopted.
- Refresh `docs/ACCESSIBILITY.md` for treatment-independent ambient life
  and the completed ASCII tier.

### Changed — runtime foundations

- Make the advertised Android/Termux release target buildable by generating
  QuickJS bindings against the Android NDK instead of expecting an upstream
  pre-generated `aarch64-linux-android` binding file, and give Android CLI/TUI
  HTTP clients a preconfigured rustls root store (Mozilla WebPKI roots) so
  standalone Termux processes stop panicking inside
  `rustls-platform-verifier`'s JVM expectations (#4236, #4242).
- Rebalance the bundled Constitution after the v0.8.67 prompt ablation: keep
  the procedural policy tail in mode-specific layers, while restoring concise
  behavioral guidance for momentum, causal investigation, constraint-first
  decisions, mechanism-backed guarantees, and clean continuity.
- Wire live catalog cache into provider/model pickers without dropping stale or
  prior rows after TTL expiry / refresh failure (#4139). Remove the dead
  `OFFERING_SEEDS` hand table so the bundled Models.dev catalog is the sole
  seed source; pickers show a compact `stale` / `cache failed` chrome chip when
  the Models.dev layer is past TTL or last refresh failed.
- Make `work_update` the sole model-facing To-do / Work progress tool (#4132).
  `checklist_*` and `todo_*` remain registered as hidden compat aliases for
  transcript replay; `update_plan` stays Strategy metadata/context/route, not
  a second checklist. Mode/approval prompts nudge the single surface.
- Demote the bundled Models.dev snapshot to an offline/stale fallback after
  live catalog refresh (#4188). ProviderLake precedence is live Models.dev >
  bundled seed > legacy hardcoded completion names; pickers, inventory, and
  subagent validation stay catalog-backed, and Codewhale-only providers keep
  defaults when Models.dev has no rows.

### Added
- Wire xAI device-code OAuth into `codewhale auth xai-device`, the TUI
  `/auth xai-device` command, and guided provider setup, with comment-preserving
  auth-mode persistence and loopback exchange coverage (#4257).
- Add GPT-5.6 Sol, Terra, and Luna to the OpenAI API route, including their
  1.05M context metadata, 128K output limits, pricing, and `max` reasoning
  effort. Add Meta Model API as a first-class OpenAI-compatible provider for
  Muse Spark 1.1 with 1M context, tool/reasoning metadata, provider aliases,
  and both `META_MODEL_API_KEY` and Meta's `MODEL_API_KEY` credential names.
- Catalog automation: `scripts/catalog_models_dev.py` refreshes secret-free
  Models.dev / OpenRouter listings and validates the offline seed snapshot
  (`snapshot --check`) without ever persisting API keys (#4117).
- `/model` picker cycles six catalog views with `A` (Configured → Catalog →
  Recent → Coding → Cheap → Long context) and richer row metadata from the
  live/bundled catalog (context, max output, tools, reasoning, price/M,
  freshness). Discoverability views do not auto-apply a surprising route
  (#4115).

- Workflow runs are now durable: every run appends to a
  `.codewhale/workflow-runs.jsonl` journal and hydrates on startup, so
  `workflow status` survives restarts; runs left `running` by a dead process
  are recovered as failed (#4011). The transcript renders workflow tool
  output as a run card (status, goal, children, progress, verification)
  instead of a generic one-liner (#4038), and `workflow` accepts a `verify`
  flag that runs post-completion verification gates and fails the run when
  gates fail (#4013).
- Hotbar sources for MCP tools and skills: MCP tool slots prefill the
  composer (execution stays behind the normal tool-approval flow) and skill
  slots activate through the existing `$skill` alias (#2068, #2069).
- Mode & permission surface: Tab cycles Plan → Act → Operate; Shift+Tab
  cycles the Agent permission posture (Ask / Auto-Review / Full Access) with
  a footer permission chip; Ctrl+T cycles reasoning effort and Ctrl+Shift+T
  opens the live transcript overlay. Operate is the orchestration mode
  (delegate, wait, inspect, dispatch) and raises sub-agent fan-out while
  focusing the Agents sidebar.
- Provider lake facade: the provider/model pickers, hotbar, and model
  inventory now enumerate configured providers' models from the bundled
  catalog (with an `A` toggle to browse the full catalog), replacing the
  hardcoded per-provider model table (#3830 follow-up).
- Added Cursor-integrated-terminal dogfood evidence for the published v0.8.67
  release, covering installed binary provenance, release/publication checks,
  headless runtime smoke, setup QA, and remaining manual visual TUI checks.
- README and README.zh-CN now point users to the community-maintained
  CodeWhale for VS Code GUI frontend while clarifying that this repository's
  `extensions/vscode/` scaffold remains the read-only Phase 0 viewer (#4035).

### Fixed

- Sub-agent waiting no longer peek→sleep polls: `agent(action="wait")` joins
  children, unchanged peeks are throttled (~30s) with an anti-polling nudge,
  and mode prompts teach the join primitive (#4097). Harvested from PR #4098
  by [@Mr-Moon121](https://github.com/Mr-Moon121) (Jeffrey Luna).
- `/provider` picker remembers catalog/configured view and highlighted row
  across reopen, matching `/model` picker memory.
- Mode picker roster is exactly Act / Plan / Operate (no Multitask, no
  numeric `4`/`5` gaps). Legacy `yolo`/`4` remain invisible one-way
  permission shorthand for Act + Bypass.

- Fleet setup is a role/profile roster editor, not a provider-scoped model
  picker: the Model step lists routes from every configured provider (not
  only the active one), a picked route's provider is persisted explicitly in
  the saved profile TOML (`provider = "..."`, never inferred from the model
  id), and the loader/route resolver read that field back out verbatim. The
  draft-preview save keypress no longer competes with a separate pager's
  `g`/`G` scroll bindings — the exact TOML preview now renders inline on the
  same Review step that saves it (#4093).
- `codewhale fleet run` and interactive in-process Fleet launches now honor a
  profile-pinned provider/model route instead of merely recording it on the
  receipt. Headless workers receive the non-secret `--provider` and `--model`
  pair; TUI workers resolve the same explicit route in process. Credentials
  still come from the worker's environment, provider is never inferred from a
  model id, and unpinned workers continue to inherit the run route (#4093,
  #4193).
- The Fleet setup `m` model-assisted redraft no longer drops a picked
  cross-provider route: the provider/model the operator chose are re-pinned
  onto the drafted profile (a model draft is always `provider: None`), so
  saving it keeps the explicit route instead of persisting an ambiguous,
  provider-scoped profile (#4093).
- Saving a Fleet profile now fails with a clear message when it pins a
  provider that has no configured credentials, using the same
  configured-provider check the model picker uses (#4093).
- Workflow correctness: completion polling fails closed instead of
  fabricating success when a sub-agent reports no terminal status; cancel
  interrupts the JS VM (cancel handle + abort) and blocks further spawns;
  and `budget.spent()` reports real manager-scope usage instead of always 0.
- Sub-agent spawns validate the model↔provider pair before dispatch:
  inherited/faster routes remap foreign models to the provider's catalog
  default, and explicit pins fail fast with a diagnostic instead of an
  upstream model-not-found error.
- TUI stability: engine event drains break every 8–16 events / 8 ms to keep
  input live (#1830, #2317, #1198); the terminal input pump restarts after
  stall recovery on macOS/Linux too; the startup raw-mode probe no longer
  leaks raw mode on timeout; recovery snapshots persist every 45 s during
  long turns and the offline queue persists on every push (#1830);
  queue/steer paths surface toasts while streaming (#2317, #1338); and
  modal submit errors re-open the modal instead of being swallowed (#1198).
- Core/state: paused jobs persist as paused across restarts; unarchive
  updates the in-memory cache; tool dispatch has a timeout; MCP
  notifications no longer receive responses; corrupted checkpoints surface
  errors instead of loading empty state; the session index compacts instead
  of growing unbounded; and recording thread-goal usage no longer
  self-deadlocks the state store.
- Runtime compaction summaries are now persisted into `/v1` thread records so
  engine reloads and restarts preserve compacted context. Contributed by
  MXAntian (@MXAntian) (#4091).
- The TUI leaves xterm alternate-scroll mode off when mouse capture is disabled,
  preserving native terminal text selection in light-theme/no-mouse-capture
  sessions. Contributed by Nightt (@nightt5879) (#4088, #4026).
- The public `/api/github/feed` endpoint is now forced dynamic on Cloudflare so
  it returns live GitHub activity instead of a build-time empty feed.

### Security

- Require bearer authentication for `/v1/chat/completions`, compare tokens in
  constant time, return accurate 4xx/5xx statuses, bound request bodies and SSE
  frames, redact secrets from stdio `config get`, and reliably reap the runtime
  child during shutdown.
- Keep trust precedence and secret persistence fail-closed: user ExecPolicy
  rules outrank agent-layer rules, chained commands cannot propose unsafe
  trusted-prefix amendments, and config and secret writes are atomic with
  filesystem synchronization on every supported platform.

### Changed

- Tool-hang watchdog trimmed from 15 minutes to 10 (#1862); approval modal
  footer hints use a higher-contrast tier (#3380); status/mode copy is
  disclosed once across header, footer, cards, and sidebar instead of
  repeated per layer.
- Removed the unused `tui::whale_routes` taxonomy module and its tests.
  Contributed by Darrell Thomas (@DarrellThomas) (#4041, #3852).

### Deprecated

- YOLO mode: `--yolo`, `default_mode = "yolo"`, and the hotbar YOLO action
  now map to Act + Full Access permissions via a compatibility shim and
  show a one-shot deprecation notice. Removal is deferred beyond v0.9.0 so
  this release does not break existing scripts without a dedicated cutover.

### Removed

- Remove the deprecated `deepseek` and `deepseek-tui` binary shims in this
  breaking release. `codewhale`, `codew`, and `codewhale-tui` are the supported
  entry points; existing DeepSeek provider support and legacy config/session
  migration remain intact.

### Known issues

- Android/Termux arm64 remains a preview in v0.9.0. The target, asset wiring,
  updater selection, dependency graph, and source-build path have automated or
  static coverage, but shell/PTY/config/TUI startup and runtime behavior remain
  unverified on a real device (#4236, #4242). Do not use a GNU/Linux arm64
  archive in Termux.

## Contributors

Thank you to the international community whose code, reports, reviews, and
reproductions shaped v0.9.0:

- [@amuthantamil](https://github.com/amuthantamil),
  [@bistack](https://github.com/bistack),
  [@bruce6135](https://github.com/bruce6135),
  [@CCChisato](https://github.com/CCChisato),
  [@ci4ic4](https://github.com/ci4ic4),
  [@cyq1017](https://github.com/cyq1017), and
  [@DarrellThomas](https://github.com/DarrellThomas).
- [@eugenicum](https://github.com/eugenicum),
  [@findshan](https://github.com/findshan),
  [@gaord](https://github.com/gaord),
  [@hmr-BH](https://github.com/hmr-BH),
  [@hongqitai](https://github.com/hongqitai), and
  [@idling11](https://github.com/idling11).
- [@JayBeest](https://github.com/JayBeest),
  [@knqiufan](https://github.com/knqiufan),
  [@LeoLin990405](https://github.com/LeoLin990405),
  [@moduvoice](https://github.com/moduvoice),
  [@mvanhorn](https://github.com/mvanhorn),
  [@Mr-Moon121](https://github.com/Mr-Moon121), and
  [@MXAntian](https://github.com/MXAntian).
- [@Angel-Hair](https://github.com/Angel-Hair),
  [@nightt5879](https://github.com/nightt5879),
  [@nsfoxer](https://github.com/nsfoxer),
  [@octo-patch](https://github.com/octo-patch),
  [@qinlinwang](https://github.com/qinlinwang),
  [@SamhandsomeLee](https://github.com/SamhandsomeLee), and
  [@taixinguo](https://github.com/taixinguo).
- [@WavesMan](https://github.com/WavesMan),
  [@wuisabel-gif](https://github.com/wuisabel-gif), and
  [@yekern](https://github.com/yekern).

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.