feat: Codewhale 0.9.12 shell, brand, fleet, and Operate (mega) - #5826
Conversation
Design MODEL-ROUTING-CATALOG-20260901 §10, slice F1. A fleet model is a Pod
member: the selected Pod file's operator route plus every member row that
pins an exact provider + model; the roles a model fills are the member rows
that pin it. No second store.
- crate::fleet::members: fleet_models / add_fleet_model / remove_fleet_model
/ toggle_fleet_model + change_receipt; Config::fleet_members(workspace) is
the read seam for the operator-awareness slice (F2).
- /pod models | add <provider> <model> [role…] | remove <provider> <model>
(also via the /fleet alias). A model the configured provider does not
serve is rejected; the first add creates and selects a user-global Pod
named 'My fleet'.
- /model picker: ⇧F adds or removes the row's exact route; fleet models
lead the list labelled 'fleet · <roles>', ahead of ⇧P pins and providers.
- /models prints the fleet before the provider list ('Your fleet is the
session model only' when empty).
- PickerActionFleet message in all 15 locales; docs/FLEET.md 'Your fleet
as models'.
Tests: scripts/dev-test.sh tui fleet::members groups::core::fleet
model_picker format_helpers — Summary 37 tests run: 37 passed, 11834
skipped.
Signed-off-by: CodeWhale Bot <bot@codewhale.net>
cargo clippy -p codewhale-tui --all-targets -- -D warnings -A clippy::too_many_arguments -A clippy::uninlined_format_args -A clippy::unnecessary_map_or: no findings. Signed-off-by: CodeWhale Bot <bot@codewhale.net>
…ion\n\n- Reject unconfigured provider ids in "/pod add" before writing, reusing\n the existing provider_is_configured_for_active predicate and custom\n provider table checks.\n- Add App.config snapshot so commands can consult the loaded config.\n- Update the stale DEFAULT_FLEET_NAME doc comment to mention ⇧F.\n- Sync crates/tui/CHANGELOG.md.
Dependabot #5801 bumped react-dom to 19.2.8, whose peer range requires react 19.2.8; the lockfile still resolved react 19.2.6, so 'npm ci' in web/ failed ERESOLVE on main and on every branch that merged it (Lint & Type Check red). Align react to 19.2.8; install verified clean. Signed-off-by: CodeWhale Bot <bot@codewhale.net>
Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Hunter Bown <hmbown@gmail.com>
Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Hunter Bown <hmbown@gmail.com>
Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Hunter Bown <hmbown@gmail.com>
Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Hunter Bown <hmbown@gmail.com>
Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Hunter Bown <hmbown@gmail.com>
Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Hunter Bown <hmbown@gmail.com>
Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Hunter Bown <hmbown@gmail.com>
… into devin/1788323051-0912-mega
…o devin/1788323051-0912-mega
Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Hunter Bown <hmbown@gmail.com>
Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Hunter Bown <hmbown@gmail.com>
Field, chrome, panel, plate and raised surfaces move onto the brand navy (#070C1D → #142352 → #1A2C63); interaction blue becomes the ombre sky #6AA6DC, light-mode action the ombre cobalt #1535B2; ice/cyan/border/tool tints follow. web/app/tokens.css regenerated via scripts/export-design-tokens.py. Co-Authored-By: Hunter Bown <hmbown@gmail.com>
Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Hunter Bown <hmbown@gmail.com>
…ite + docs Space Mono (OFL) outlined wordmark rebuilt via scripts/build-wordmark.py, wired as --font-display through next/font/google; body stays IBM Plex Sans, code stays JetBrains Mono. Nav loses the issue strip, strapline, Discord badge and second filled CTA; home loses the ticker, seals and tilt figure; docs shell hero collapses to a one-line band; footer uses the inverted wordmark. Public noun is fleet (/fleet, codewhale fleet, /docs/fleet canonical; /pod, codewhale pod, /docs/pod remain compatibility aliases) across docs/, site dictionaries, vocabulary contract and public-surface facts. No-Issue: 0.9.12 website lane
…emos; AA meta text
Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Hunter Bown <hmbown@gmail.com>
Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Hunter Bown <hmbown@gmail.com>
…add PRODUCT.md/DESIGN.md
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_7a9142c7-0927-4293-bd53-676de6b91e7f) |
|
Claude finished @Hmbown's task in 2m 14s —— View job Claude is reviewing this PR
|
- The context-cap posture test drew at 100 columns, where a backend-less platform (linux CI paints 'files: workspace (unenforced)') sheds the cap hint first, so the warning count read 0. Draw at 140 columns, where the hint survives with the notice present; verified locally. - The pointer queue proof retries the [↑] click once, re-finding the affordance first: under runner load a redraw can shift cells between the find and the click, so the first SGR gesture lands nowhere.
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_9666fa15-c454-493b-b5b9-8aa0e3b3d9f6) |
|
Claude finished @Hmbown's task in 1m 24s —— View job Claude is reviewing this PR
|
…s; pointer baseline - The Pod->Fleet sweep grew every mode's tool-schema surface by 58 bytes (+14 tokens). The receipts are re-measured and the one-way ceilings in scripts/runtime-contract-budget.json are raised to them as the explicit maintainer decision the gate asks for (the rename is the founder's 2026-09-01 vocabulary call). - The README screenshot embed changed README.md; the 18 translated READMEs re-stamp (the embed is language-neutral HTML - no prose changed, so no retranslation was needed). - The pointer queue baseline is captured while the composer is empty: the pending preview row hides while a draft sits in the composer, so the pre-click depth read None and the growth proof could not fire.
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_5e608671-644b-48b1-89ae-0fbd4892783e) |
|
Claude finished @Hmbown's task in 4m 28s —— View job Claude is reviewing this PR
|
The qa_harness Instant wrapper does not implement Div, and the retry's single read raced the app processing the second gesture: poll to the full deadline, re-click once at the half-way point.
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_10ccf061-78c4-41a1-9ef7-66ef038cfcbb) |
|
Claude finished @Hmbown's task in 6m 45s —— View job Claude finished reviewing this PR
|
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_bd65ee7b-4fb0-41f5-b1f1-68622ebb14cd) |
|
Claude finished @Hmbown's task in 1m 22s —— View job Claude finished reviewing this PR
|
|
Claude finished @Hmbown's task in 1m 7s —— View job Claude finished reviewing this PR
|
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_54ea7729-4f55-4609-a9c3-537ea22ada89) |
- workflow::AgentType::Plan serializes as the canonical 'planner'
('plan'/'awaiter' stay accepted aliases), matching the FleetRole
vocabulary the mega PR declares.
- Web: the vocabulary docs metadata, the vocabulary module header, and
the docs-map topic description say Advisor (the public advisory term)
instead of the retired Consultant spelling.
- Polish home dictionary: restore 'Podwodna powłoka terminala' — the
fleet-vocabulary sweep had merged 'Fleet' into the compound word
'Podwodna' (underwater), producing the non-word 'fleetwodna'.
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_86101471-b0d8-4021-8f97-9b45ea0fbcdf) |
|
Claude finished @Hmbown's task in 1m 10s —— View job Claude finished reviewing this PR
|
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_08035bb5-ee29-4377-bfed-a3ddb392e128) |
|
Claude finished @Hmbown's task in 49s —— View job Claude finished reviewing this PR
|
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_7d60c4d2-f69b-4f09-8d62-cc56d9c636ca) |
|
Claude finished @Hmbown's task in 59s —— View job Claude finished reviewing this PR
|

No-Issue: this is the 0.9.12 integration wave (launch card, brand trace, fleet vocabulary, Operate goal loop, DashScope descriptor) tracked in #5573; it supersedes #5815/#5817/#5819/#5822.
What changed for the user
Launch is our own card. Opening
codewhalenow shows a thin top line(
⑂ branch path), then a centred bordered card: the whale mark at left(kitty image in kitty-class terminals, braille dots elsewhere, wordmark text
under ascii-safe),
Codewhalebold + version, one announcement line onlywhen it is true (
⚠ no model connected · run /provider, or MCP news), andthe menu New worktree / Resume session / Changelog / Quit with their real
chords right-aligned. Enter runs the highlighted entry, Up/Down move it, and
typing goes straight to the composer. The card dissolves on the first
keystroke or command (≤240 ms, instant under reduced motion) into the working
screen: top line gains
⋮ MCP n/m, the transcript starts with a◆ session_startreceipt, and the composer's bottom rule carriesmodel (effort) · permission. Posture bar + metrics line appear only once asession exists.
Brand, traced. Wordmark SVGs traced from the founder's raster, navy
app icon / favicon / OG / manifest, site colours exported from one token
file (
scripts/brand/trace-brand.py --check).One vocabulary.
fleetis the public term;Podis retired from copy(
/fleetcanonical,/podalias). Role tokens are canonical everywhere:general / explore / implement / test / advisor (+ planner / reviewer /
custom). The workflow wire accepts the pre-rename spellings as load-time
aliases and serializes canonical names.
Operate pushes toward parallel work. A real prompt in Operate becomes a
goal through the same
create_goalpath the /goal command uses; a singleappend-only contract message tells the model it is the operator; the goal
seals through the deferred
update_goaltool with verification evidencebefore the turn ends.
Qwen 3.8 through the catalog authority. Alibaba Model Studio (DashScope)
joins the data-driven provider descriptors: international compatible-mode
endpoint,
DASHSCOPE_API_KEY, live/v1/modelsdiscovery — never ahard-coded id. Live verification with a real key from the founder's
environment (never printed):
The live lists carry
qwen3.8-flashandqwen3.8-max; there is noseparately-dated
0901id on either live endpoint tonight, so the exactlive ids stand (the descriptor's default model is a bootstrap hint only).
Chrome facts, one owner each. Metrics line
(
model · ctx NN% · $cost · ttft · tok/s · ↓ tokens … Ctrl+/ help) andposture bar (
▶▶ ask (Shift+Tab) · work (Tab) · … Esc to interrupt … /rc)under the composer. Double-tap Enter during a turn sends the queued message
now; Ctrl+Enter steers. The bottom view cycles agents → tasks → background →
files → notepad → context → git → price (Ctrl+Tab / Ctrl+Shift+Tab, plus a
fallback chord), with clickable tabs and
/rail <view>.Perf (hot paths). No more per-delta
format!of the whole tool-inputbuffer into a verbose-only log (O(n²) per tool call); fast-reject the
28-marker trailing-prefix probes for deltas without
</[(per-token winon every stream); reuse the identity collapsed-cell map across frames.
Founder decisions recorded
Shell = Claude Code's structure with our mark ("minimalist like Claude but a
shit ton of features"); launch = grokbuild's card structure with our whale
— "find a happy medium and make our own codewhale version", not a clone.
All recorded as Round 5 in
codewhale-ops/design/SHELL-DESIGN-20260901.md(§2.12), andDESIGN.md'sshell direction now matches (card, not dock/hero).
Gates (exact CI flags, real results)
All run on this branch head with CI's exact flags:
cargo fmt --all -- --check— clean (FMT_OK).scripts/dev-cargo.sh clippy --workspace --all-targets --all-features --locked -- -D warnings -A clippy::uninlined_format_args -A clippy::too_many_arguments -A clippy::unnecessary_map_or—Finishedwith 0 errors.RUST_MIN_STACK=16777216 scripts/dev-cargo.sh nextest run --workspace --all-features --locked --profile ci—Summary [ 212.813s] 14420 tests run: 14419 passed (3 leaky), 1 failed, 15 skipped. The one failure,exec_persistent_service::failed_exec_kills_pending_service_and_exits_nonzero, hit its 120 s wall-time guard while two other gates ran concurrently on this machine; re-run solo:PASS [ 3.014s] … Summary [ 3.024s] 1 test run: 1 passed, 12216 skipped.scripts/dev-cargo.sh test --workspace --all-features --locked --doc— 21/21 result linesok, 0 failed../scripts/release/check-versions.sh --range-audit-advisory—Version state OK: workspace=0.9.11, npm=0.9.11, npm-binary=0.9.11, lockfile in sync.(exit 0; the range-audit note is advisory on already-merged commits, per the flag).scripts/check-tui-product-vocabulary.sh— exit 0.python3 scripts/check-dead-code-budget.py—[dead-code-budget] 422 attributes, budget 425 (3 under).(under budget).python3 scripts/brand/trace-brand.py --check— exit 0.npm ci && npm run lint && npx tsc --noEmit && npm test && npm run check:tokens && npm run build— lint 0 errors, tsc clean,Tests 385 passed (385),design tokens up to date (1 file(s), 42 tokens), build succeeded. (The previously documented pre-existing README-screenshot failure is fixed here: the brand header redesign had dropped theassets/screenshot.webpembed the contract pins; it is re-embedded.)Launch-card goldens were re-blessed for the card (
startup_*,startup_first_run_80x24,startup_surfacing_80x24,startup_ink_*), and the golden files were read after blessing — the card, top line, and composer rule render as specified at 40x10 (shed), 80x24, 100x30, 120x32, and 160x40.What was left, in plain words
git_rows,notepad_rows(the.codewhale/notes.mdeditor), the rosterper-agent cost column, and compact tool rows did not fit tonight. The
eight-view cycle, tabs, and
/railall land; four of the eight viewsrender real data (agents, tasks, background, context), the rest are
honest empty states.
that leftover was already satisfied by the frame slice.
Also left for follow-up, noted by the issue triage: refreshing
assets/screenshot.webpto show the new launch card (the contract pinsdimensions, so a fresh capture is a deliberate follow-up), and re-landing
the three stranded items the triage recorded (control socket #5594, the
#5588 neutrality slice
9ffec9b90, and FEAT-019 memory commands).What was left, in plain words
git_rows,notepad_rows(the.codewhale/notes.mdeditor), the rosterper-agent cost column, and compact tool rows did not fit tonight. The
eight-view cycle, tabs, and
/railall land; four of the eight viewsrender real data (agents, tasks, background, context), the rest are
honest empty states.
that leftover was already satisfied by the frame slice.
🤖 Generated with Claude Code
Known non-required check state
Codewhale reviewfails structurally on this PR: the review bot fetches thePR diff through
gh pr diff, which GitHub caps at 300 files — this PRmodifies far more. It is an infrastructure cap, not a review verdict; the
bot's own log says
PullRequest.diff too_large. Every other review lane(Copilot inline findings — all fixed in this branch — Claude review, Devin
review) ran.