Delete full-screen PTY assertions and large inline UI test modules that froze copy, geometry, and implementation shape. Keep production code intact and retain runtime, safety, integrity, protocol, and process-boundary coverage for later surgical review.
Signed-off-by: Hunter Bown <hmbown@gmail.com>
Seal intentional config fixtures, isolate unsealed config/state/skills paths from the developer home, serialize persistent-service cases under nextest and libtest, and give the PDF success path a realistic timeout while retaining its short timeout regression.
Also treat removed or empty home variables as unsealed so tests cannot fall back into the user profile.
Verified with 477 config tests, 7 test-support tests, 27 config-persistence tests, 12 provider-key tests, 5 PDF tests, 3 nextest and 3 libtest persistent-service tests, workflow wiring checks, formatting, and diff checks.
Signed-off-by: Hunter Bown <hmbown@gmail.com>
The zip already shipped codewhale.bat (where wt, then the exe). NSIS
only copied the exes, so a Start Menu launch still used the raw binary
(#1854). Install the same launcher into bin, pin a current-user
shortcut at it, and delete both on uninstall.
Verified: node --test scripts/release/assemble-release-assets.test.js
(7/7) and makensis compiled a test installer.
Test bankruptcy is a scheduling problem, not a rotten suite. With one
concurrency group per branch, GitHub cancelled pending main runs when
the next merge queued — 31 of the last 40 main CI runs never finished.
Key non-PR runs by SHA so each commit actually gets a result. PRs still
cancel superseded heads.
Add a 15-minute Safety gate job for command_safety / auto_review /
authority / sandbox / execpolicy. The 71-minute macOS Test job stays
until a summary job exists for protect-main; nothing was deleted.
Also align the persistence-backlog argv contract with the --all-features
flag that stopped that check from rebuilding the workspace.
`check-persistence-backlog-budget.py` runs its measurement through
`cargo test -p codewhale-tui --lib` with default features, but the step
before it on the same runner is
`cargo nextest run --workspace --all-features --locked`. This crate's
`--all-features` adds `web` and `long-running-tests` on top of the default
`tui,json,toml`, so the two are a different feature unification and Cargo
rebuilds the crate and everything downstream of it rather than reusing what
was just compiled.
It is the second-largest step in the macOS leg: 10 minutes of a 71-minute
job, for a test that runs in well under a second. Measured locally, the same
command against a warm tree of the *other* feature set takes 9.5s when the
features match and 132s when they do not — the delta is entirely the rebuild.
Aligning the flag makes the measurement reuse the nextest artifacts. The
measured test is unchanged and still runs `--exact --ignored
--test-threads=1`, which is what the receipt's determinism depends on.
Version surfaces moved together: workspace Cargo.toml, all 21 crate
dependency pins, Cargo.lock (workspace crates only — zero external changes),
CHANGELOG slice with the 0.9.10 section and compare link, crates/tui
CHANGELOG sync, web facts (derive-facts), npm/codewhale, npm/runtime-sdk,
extensions/vscode, and the remote-smoke default tag.
check-versions.sh: 0 errors. This is the candidate label only — no tag, no
package publication, no release creation.
The #5465 wedge was dev-cache.sh putting ~6 GB build dirs on a volume with
6.5 GiB free and running it to ENOSPC. Add a free-space probe: warn when the
volume holding the cache root has less than CODEWHALE_DEV_CACHE_MIN_FREE_GIB
free, name the cold-build cost (~6 GB), and point at the escape hatches
(CODEWHALE_CACHE_ROOT, the volume-preference envs). Dev tooling only; no
product behavior changes.
Delegate capability mutations through authoritative App operations, bridge portable RegisterCommand metadata into the TUI registry, and enforce monotonic migration-frontier transitions against the baseline revision.
Use Node's bounded recursive-removal retries so delayed Windows handle release after concurrent wrapper downloads does not fail an otherwise successful smoke. Persistent cleanup errors still reject after the finite retry window.
No-Issue: owner-directed v0.9.9 Windows release-smoke hardening
Normalize model-facing warning separators, preserve discoverable paths for ordinary workspace roots, and keep custom configured roots private. Trim redundant prompt prose so the stricter behavior remains below the existing contract ceiling.\n\nVerified with 216 focused skills tests and the 55-metric runtime-contract gate.\n\nNo-Issue: follow-up corrections for #5492.
The configured-skills stability change swaps a 33-char fixture skills root
for the 19-char <configured-skills> token in the representative skill-stage
warning, so every stage from skill onward re-hashes (identities are digests
of the normalized prompt text).
Identities re-measured via scripts/measure-runtime-contract.py on the
hermetic representative fixture (tempdir workspace + pinned HOME/SHELL;
path/platform normalization makes the normalized text host-independent).
Byte ceilings are unchanged: the change shrinks the prompt and one-way
ceilings pass decreases automatically. This is the maintainer re-base the
budget comment calls for when a prompt change is deliberate.
No-Issue: budget identity re-base for #5473 / #5492.
Task 3.5/3.6 - live bidirectional frontier/source verification.
- Structural Rust item parser (pure stdlib): free functions, inherent
methods, trait-impl methods with qualified item paths (module layout
derived); brace/paren/generic aware; comment+string blanking
- Concrete-App detection on first parameter type (&mut App /
&mut crate::tui::app::App)
- Bidirectional frontier check: pending group covers all its handlers;
documented split requires ALL slices pending with handlers; stale
removal (handler remains but group not pending), stale entry (pending
group with no handler), and partial split all fail with diagnostics
- Selector resolution: checked-in selector records resolve to exactly
one source item with a concrete-App signature; missing/ambiguous fail
- 8 new hermetic source-scan fixtures (47 total): parse free/trait/
inherent, non-App ignored, missing file, matching frontier, cheating
removal, stale entry, live source agreement
Verified: test_check_command_migration_manifest.py 47/47 OK; live gate
PASS (frontier exactly matches source; all nine groups pending);
fmt/contract/boundary/clippy all green.
Generated with Claude Code
All 19 open actions/cache-poisoning/poisonable-step alerts (#88-#106) sit in
release.yml, release-candidate.yml and release-artifacts.yml: jobs interpolated
the caller SHA into ref/caches and let setup-node's implicit npm cache key on
run identity. Now caller source_sha is pinned against github.sha by a pin job
(refusing any retarget), checkout and build identity use GITHUB_SHA through
env indirection instead of template interpolation, rust-cache keys use stable
prefix-key values, and setup-node's implicit package cache is off where it
cannot be keyed safely.
Also carries the CodeQL #107 fix from the same lane: catalog_models_dev.py
prints remote limit values as numbers/null/redacted only and drops query and
fragment material from source URLs before logging.
Harvested from #5401 (workflow+script files; CHANGELOG edit intentionally
excluded here and lands with the release branch; GHSA advisory text split to
a later PR as advised).
No-Issue: CodeQL alert remediation (alerts #88-#107); no single user-facing issue tracks these
Signed-off-by: Hunter Bown <hunter@hmbown.com>
The idle mark drew a flat gold slab with its fluke floating six columns
clear of the body and a four-cell rule leaving the flank at eye height —
it read as a bar with a shape drifting past it, not an animal.
Redraw it from the Whale Teams / Signal Cut roster (CWC 2026-08-15):
head-left with a blunt nose, a swept dorsal on an arched back, a tail
stock that stays body mass and rises into the attached crown fluke, and
one cyan current cut along the belly. The fluke's notch now sits directly
above the rising stock tip, so the tail is part of the whale.
The glyph vocabulary is the one whales::art already uses for the six role
portraits, so the empty-state hero and the /fleet roster are one animal at
two scales. The spout and belly cut resolve through
whales::WhaleInk::from_theme(..).current, which lifts brand cyan #48D7FF
to the secondary-chrome contrast floor per theme; previously the spout
took each theme's accent_secondary and the belly was body gold.
Pure render: no prompt, tool catalog, or session-context change, so the
KV-cache prefix is untouched.
- classic block width 24 -> 17 columns, uwu 21 -> 16
- docs/design/WHALE_TEAMS_TUI_ART.md records the translation decisions
- scripts/preview-whale-art.py renders before/after in true colour, plain
text, and a terminal-cell PNG, reading the art out of underwater.rs
Ship README translations for the TUI packs that had no README, plus
Turkish, Italian, Polish, and Arabic. Include Catalan as the remaining
shipped TUI pack. Cross-link every language switcher, restamp all
translations against the updated English README, and register the new
files in both check-readme-translations.py lists.
Job-level reruns (gh run rerun --failed) bump the run-level run_started_at
past the asset upload timestamps, so every rerun of a failed downstream job
failed the freshness gate with 'asset set is stale' even though the assets
belong to that exact run and SHA (cost three attempts on the v0.9.8 publish).
findReleaseWorkflowRun now carries the successful release job's started_at
on the returned run record; assertReleaseAssetsFresh compares asset
updated_at against that job baseline, falling back to run_started_at /
created_at only when the job baseline is unavailable. The local
verify-release-assets.sh path delegates freshness to the same verifier, so
operator repairs after reruns are protected too.
Regression tests: rerun-shifted run_started_at with an unchanged job
started_at is judged fresh; assets older than the release job are still
rejected.
The pinned session prefix (c15558458) added the <context_update> sentence to
BASE_PROMPT, so the representative base stage grew 5848 -> 6084 bytes and
every stage digest changed; the host-side Workflow/Goal verbs and the honest
child posture grew the tool catalog (active 16531 -> 16602 bytes, full
71473 -> 72371). Both are deliberate v0.9.8 lane changes, so re-measure the
budget from the release train (scripts/measure-runtime-contract.py) and
record the raise in the _comment, as the previous two v0.9.8 raises did.
Identity name sets are unchanged.
A merge commit that lands a contributor's PR (`git merge --no-ff`) keeps
the contributor as author of the merged commits, which is exactly the
credit the gate asks for. When that merge also carries a
`Harvested from PR #N by @login` line for the auto-close workflow, the
checker now looks at the authors of `first-parent..merge` before
demanding a duplicate Co-authored-by trailer on the merge commit itself.
Non-merge harvested commits and merges that do not carry the contributor's
commits are unchanged. Covered by a new unit test.
Cargo still writes CACHEDIR.TAG (and sometimes final artifacts) under
./target when build-dir is split, so the old auto-mode treated a
freshly-isolated worktree as warm on the second command and recompiled
everything into a second tree. auto now always isolates;
CODEWHALE_DEV_CACHE=local is the explicit stay-in-./target opt-out.
dev-cache.test.sh: all 22 checks pass on this tree.
scripts/dev-test.sh only mapped an area onto cargo test -p; a new
worktree still compiled into a private cold ./target. Add
scripts/dev-cache.sh and scripts/dev-cargo.sh so the measured isolated
build-dir topology is actually applied.
New worktrees get CARGO_BUILD_BUILD_DIR under
${CODEWHALE_CACHE_ROOT:-${XDG_CACHE_HOME:-$HOME/.cache}/codewhale}
with Cargo's {workspace-path-hash} (passed as --config so the
template expands). sccache wraps rustc only when incremental is
already off; a missing binary is a printed fallback, not an error.
Cargo older than 1.91 falls back to a per-workspace CARGO_TARGET_DIR.
Already-set CARGO_TARGET_DIR / CARGO_BUILD_BUILD_DIR / RUSTC_WRAPPER
are left alone. Defaults contain no machine-local path.
dev-test.sh now routes every workspace crate, prefers cargo-nextest
when installed (CODEWHALE_DEV_NEXTEST=0 forces libtest), and exports
RUST_MIN_STACK=16MiB when unset. nextest retries stay 0. Hermetic
checks: scripts/dev-cache.test.sh (22) and scripts/dev-test.test.sh
(27), passing under both /bin/sh and dash.
Harvested unchanged from lane local/5249-iteration-cost (commit f82d53db9,
CodeWhale Bot): `scripts/dev-test.sh <area|path> [filter]` maps a
workspace area or a source path to the narrowest `cargo test -p` run for
it (`crates/tui/src/elapsed.rs` → `cargo test -p codewhale-tui --lib
--locked -- elapsed::`), and `--list` prints the table. Developer aid
only; no product behavior. crates/tui/AGENTS.md and the root AGENTS.md
point at it.
Assemble the reviewed 0.9.8 candidate on top of the Kimi bundle importer:
- Subtle crown-shaped whale fluke in the underwater scene with Unicode
and ASCII fallbacks; exact bold Codewhale branding and clearer
empty-state and composer text.
- Local-first onboarding: Ollama and a keyless LM Studio preset in the
provider picker; GitHub MCP and pinned Chrome DevTools MCP setup
recommendations.
- Kimi plugin parsing and import command with managed Computer Use
import support, hash-bound approval, disabled/untrusted installation,
post-copy manifest validation with rollback, and truthful unsupported
ZIP handling.
- Localization of every new string across all shipped locale packs.
- Fail-closed Antigravity (Cloud Code) system-prompt behavior with a
localized user-facing message in the turn loop and preview.
- Correct workshop byte-budget installation on HTTP/Web runtime startup
and reload.
- Repairs for stale PTY fixtures and non-hermetic test seams; canonical
CODEWHALE_CONFIG_PATH writes with DEEPSEEK_CONFIG_PATH kept as a
read-only compatibility alias.
Frozen candidate content: tracked diff sha256
dfe3254480547de65483c899dac0a21865c02005ce9cc4f91bd2afdd7964b1f3,
kimi_import.rs sha256
8b81d4f0b143c1966b8a35e8251cde472a61573dced5986b3e6889f606eefc7b.
Configurable read/tool-result ceilings grew every production tool
surface by 371 schema bytes / 93 estimated tokens. Explicit
maintainer raise so the v0.9.8 land can pass Lint. Identities
unchanged.
Privileged release workflows no longer attach rust-cache, sccache, or
npm caches to a workflow_dispatch checkout (CodeQL #88-#106). Catalog
drift no longer prints raw bundled/upstream blobs (#107).
Internal path-dependency versions, package locks, the tui CHANGELOG
slice and its root compare link, provider label facts for Google and
Antigravity, and the remote-smoke default tag. scripts/release/check-
versions.sh --require-dated-release passes locally.
The source-structure budget failed every legitimate feature: it counted
owned Rust lines and module sizes and refused growth until a JSON ceiling
was hand-edited. The edit was done by the same author who wrote the code,
so the required "review" was self-review - ceremony with no protection.
Behavior-measuring gates stay: dead-code (#[allow] totals), runtime
contract (hermetic metric tests), persistence backlog (RSS + request
contract), fmt/clippy/tests. Those measure what the product does; the
source-structure ratchet measured how big the diff was.
Removed: CI step, check script, baseline JSON, and the checker's unit
tests. Historical budget-acceptance notes remain in past CHANGELOG
entries and git history.
Directed by Hunter after the ratchet blocked landing the #5311
activation-policy slice.
After read-only external consent, Codewhale may read DEEPSEEK_API_KEY
from the exact granted $DSH_HOME/.credentials.yaml. The file is never
written or refreshed. Process env and Codewhale-owned keys still win.
Not DeepseekCN.
Evidence: dsh YAML parser tests, default path helper, consent wiring.
Source-structure budget covers the new module and thinking-ladder growth.
A billed max_tokens stop followed by a transport error fails closed
instead of continuing into a second request. Clean output-limit stops
still continue. Mid-size windows keep the 65K internal reservation so
compaction does not collapse when the catalogue documents a matching
output ceiling.
Hosted V4 and Moonshot K3 tests now expect the documented request
ceilings. Read-only bash schema includes the Ask escalation fields.
Runtime-contract and source-structure budgets cover the already-landed
child-receipt schema growth (+1496 bytes) and /rc line growth.
Evidence: eight focused tui lib tests pass locally, including the
previous six macOS/Windows CI failures and truncated_response_continues_turn.
Raise the aggregate owned-Rust ceiling from 692588 to the observed 692616 lines after restoring the spawn-route and Work-row receipt seam. Package, binary, large-module-count, and maximum-module ceilings do not change.
Record the measured post-reconciliation ceilings: 692588 owned Rust lines and a 17785-line largest module.
The package, binary, and large-module ownership sets remain unchanged.
Signed-off-by: CodeWhale Bot <bot@codewhale.net>
Add a read-only drift subcommand that compares bundled model and provider-offering context/output limits with models.dev, reports removed upstream IDs, and exits non-zero on limit drift.
The command performs no writes and is not wired as a mandatory CI gate in this change.
Signed-off-by: CodeWhale Bot <bot@codewhale.net>
Integrate the merged Auto-Review guardian after main advanced during the release wave. Preserve its current budget provenance; the combined DS4 tree passes at 691,562 owned Rust lines under the shared ceiling.
Signed-off-by: CodeWhale Bot <bot@codewhale.net>
Resolve the source-structure budget conflict after the ordered community PR wave. The combined tree requires the 17,745-line maximum-module receipt while remaining below the shared 692,000-line aggregate ceiling.
Signed-off-by: CodeWhale Bot <bot@codewhale.net>
The merge brought #5364's growth into this tree; the inherited 690031 ceiling
no longer covers the combined source. Re-measured on the refreshed base:
690274 owned Rust lines.