Pre-launch security review 2026-10-27 (two of its findings, plus hygiene):
- mcp: a server-supplied list ttlMs had no floor, so ttlMs 0 made the
catalog stale on every 5s tick, and revalidation runs discovery while
holding the MCP pool lock. Any configured server could keep every MCP
operation waiting. Catalog TTLs are now clamped to at least 60s.
Still open: running discovery outside the lock, and rate-limiting
list_changed-driven revalidation.
- runtime_api/git: validated_patch sliced the first byte off each @@
range token, which panicked on a multi-byte character and fired the
process panic hook. It now strips the expected -/+ sign and refuses
anything else as a malformed @@ line.
- .gitignore: ignore private key and certificate files, with an
exception for the existing test-only fixture key.
Verified: scripts/dev-test.sh runtime_api/git.rs git_ -> 146 tests run:
146 passed (includes git_routes_drive_a_real_workspace_repo and
git_write_preconditions_reject_stale_state); scripts/dev-test.sh mcp.rs
mcp:: -> 405 tests run: 405 passed. No new tests, per repo policy.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
FreeBSD stays a source-only target, with no prebuilt asset and no
release-matrix row (founder decision 2026-10-25, item 14). This change
fixes the claims the issue sweep found to be false or stale:
- packaging/freebsd/README.md said x86_64-unknown-freebsd "is validated in
CI ... on the release/0.9.5 branch". No job does this:
`git grep -i freebsd -- .github scripts` matches only a YAML comment. The
README now says no CI job checks the target and gives the cargo check
command to run on a FreeBSD host.
- The README pointed to crates/tui/build.rs for the rquickjs bindgen fix.
1582ba9653/5eb0385e8f touch only crates/workflow-js/Cargo.toml, which
holds the target_os = "freebsd" bindgen dependency. It now names that
file.
- The README now states the Rust minimum, 1.89 (Cargo.toml rust-version),
and its verification block no longer says ">= 1.88". The matrix list now
says Linux musl arm64, which is the target the matrix builds, not gnu.
- The release-artifacts.yml build-job comment no longer claims a FreeBSD
cargo check. It now says FreeBSD has no prebuilt asset, no npm binary and
no CI check.
- "OpenBSD" is dropped from the support-table row in docs/INSTALL.md and
docs/zh_hans/INSTALL.md. workflow-js has no rquickjs bindgen entry for
openbsd, and no OpenBSD build has been verified.
Ignore the vendor Ratatui target directory produced by its separate-workspace
test command; generated output is preserved in the SSD cache, not committed.
Docs, ignore rules and a YAML comment only; no product behaviour changes, so no CHANGELOG
bullet. Verified by read-only greps against the worktree. No FreeBSD compile was
attempted.
Verified as one frozen batch at 7db526a725 plus consensus patch
sha256 d6418055436eaada55f4cbedc954a0eeeb51d9d922716a3588006cf7932fab45:
- scripts/with-hermetic-test-home.sh scripts/dev-cargo.sh nextest run
-p codewhale-tui -p codewhale-localization --lib --locked:
15343 run, 15341 passed, 2 failed, 25 skipped; build 3m41s.
The two fixed-width rendered-fixture failures came from the long SSD
TMPDIR wrapping paths mid-needle. Same source/binary, shorter SSD TMPDIR,
only those two tests rerun: 2 passed, 15312 skipped. Distinct passing
coverage across both runs: 15289 TUI + 54 localization tests.
- scripts/with-hermetic-test-home.sh scripts/dev-cargo.sh test
--manifest-path vendor/codewhale-ratatui/Cargo.toml --locked --all-targets:
145 passed, 0 failed (128 library and 17 example tests).
- fmt and diff checks passed; changelog sync passed; runtime boundary PASS
(120 closure modules); dead-code budget 212; blocking-call budget 543
across 165 files; locale parity 2583 keys in all 15 packs.
- The vocabulary guard initially failed on an already-published advertised
legacy alias. Both refuters confirmed the docs-only correction; the
unchanged guard then passed. Web prebuild and check-facts passed.
Before peer reconciliation, only .gitignore, docs/MODES.md and generated web
documentation changed after native tests; frozen compiler inputs were identical.
Published peer commits aa45bf84ef/485382f81d then advanced main. Their exact
diff was integrated, preserving their ancestry and regenerating web docs.
Focused reconciliation nextest (TUI ops/runtime_info/spawn and CLI cloud
callers): 117 passed, 0 failed, 15698 skipped; source remained frozen
(104 TUI, 13 CLI). Command/filter and source SHA256
are retained in coordination/land-0103-20261025/reconciliation-test-run.json.
Final integrated tree f297b67c73 is checked against the regenerated commits.
macOS ld emitted its __eh_frame size warning. No hosted CI, FreeBSD/Linux
compile, paid provider call, install, deploy, or release is claimed.
This does not resolve#1097: the npm prebuilt and pkg port asks remain open.
Refs #1097
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Reconcile the complete contributions from #6832 (@aboimpinto), #6867
(@hodeswildsmith455-boop), and #6805 (@LIghtJUNction) with the current
Engine, provider identities, reviewed-plugin policy, and task lifecycle.
Original contributor histories are recorded by subsequent resolved merges.
Fix the already integrated contributor cases: snapshot corruption is an
explicit unavailable/error result (#6817), malformed locales cannot select
an incidental script (#6860), image metadata uses the exact uploaded bytes
and respects available decoders (#6858), automation deletion waits for
actual scheduler reconciliation (#6864), and blocking trust/skill reads stay
off the async executor (#6869). Preserve #6857's compaction regression.
Extend #6872's human-wait lifecycle guard to approval/elevation cards;
retire only the matching ended parent request and refresh activity only
after a delivered decision. Enforce configured finite approval deadlines in
the Engine, including deadline/cancellation races and durable receipts.
Serialize Native Windows ACL admission/retirement across Core processes
with a logon-scoped kernel mutex, preserving exact SID/object validation.
Add an actual child-process lock test; serialize DSH host tests in the
existing extension-host lane. Windows execution proof remains hosted CI.
Reconcile the vendored computer-use plugin with canonical main a656f67455fc
while preserving Core's 0.12.1 embedding contract. Canonical b47/a656 tree
passed Ubuntu/macOS/Windows source and package gates, including 28/28
Windows-focused tests and the controlled desktop fixture; this is separate
from the new Engine head's CI verdict.
Partial adaptation of the discovery-cache priority portion from PR #6393
by @AdityaVG13 (original ac33dd49db). Preserve the best match under count
and byte limits without importing the unfinished echolocation/fork design;
the broader draft remains open.
Validation:
- npm test: 1286 passed, 0 failed, 7 skipped; web 767/767.
- npm run check:web: lint, typecheck and production build passed.
- Affected Rust selection: 801/803 initially passed; the two fixture/lifecycle
expectation failures were corrected and each passed a focused rerun.
- Additional focused Rust: approval 28/28, discovery cache 11/11,
OrcaRouter synthetic catalog 3/3, and 33/33 lifecycle/API/routing checks.
- Final CI-repair selection: 37/39 initially passed; the BMP feature-proxy
and feature-registry summary failures were corrected; both corrected tests passed (2/2, 0 failures).
- Qualified Clippy: six packages, all targets/all features, passed with
the CI style allowances. Portable no-default-feature check passed;
portable policy verifier 6/6 passed; formatting and diff checks passed.
- Runtime contract: 55 measured metrics passed after explicit remeasurement;
all 21 structural identities were unchanged. Twelve byte/token-estimate
budgets account for bounded child-wait disclosure and contributor locale
descriptions; no runtime field/prompt was removed to lower the budget.
- Persistence budget was not qualified locally: the checker requires a
clean tree and this shared checkout retains an unrelated operator file.
Clean hosted CI, fresh stamped build and real DeepSeek TUI acceptance
remain required before the integration PR can merge to main.
Refs #6872, #6843, #6795.
Co-authored-by: Paulo Aboim Pinto <[email protected]>
Co-authored-by: hodeswildsmith455-boop <[email protected]>
Co-authored-by: LIghtJUNction <[email protected]>
Co-authored-by: AdityaVG13 <[email protected]>
Signed-off-by: CodeWhale Bot <[email protected]>
Define a Quick Start section in integrations/weixin-bridge/README.md modeled on
integrations/wecom-bridge/DEPLOYMENT.md, and then implement the behavior that
section describes. The README previously pointed at a non-existent
/opt/codewhale/weixin-bot-bridge path, gave no runtime startup command, and named
an env file that nothing reads; a first-time user could not get the bridge
running, and once it did run the first incoming message failed with EACCES and
was dropped without an actionable error.
README:
- Add Quick Start with the two-terminal flow (start `codewhale serve --http`,
then the bridge) and a single-terminal launcher, following the WeCom
deployment guide's shape.
- Add "在微信中验证": send /status, and document both real outcomes — the
authorized reply and the refusal that carries the user_id needed for pairing.
- Document the message dedupe (`user_id:message_id`) so re-testing uses a new
message.
- Correct the fabricated /opt/codewhale/weixin-bot-bridge path and env filename,
and note that the bridge reads process.env rather than a .env file.
Implement the definition:
- Default WEIXIN_THREAD_MAP_PATH inside WEIXIN_STATE_DIR. Setting only
WEIXIN_STATE_DIR left the thread map at /var/lib/codewhale-weixin-bot-bridge,
so every incoming message failed on write; the exception was swallowed by the
getUpdates catch and the message was silently dropped.
- Create the state dir in saveSyncBuf, matching saveAccount. The poll cursor can
be the first persisted write on a fresh install.
- Probe thread-map writability at startup and exit with a readable message
instead of failing later inside the message loop.
- Log the resolved thread map path next to the state dir.
Make the login QR scannable in place:
- Add src/qr.mjs, a zero-dependency byte-mode QR encoder (versions 1-10, ECC
level L) rendered with half-block glyphs, matching the Rust side's Dense1x2
renderer (crates/tui/src/runtime_api.rs). The bridge keeps its no-npm-deps
property.
- Keep printing the URL below the QR so a terminal that mangles half-block
glyphs still has a path through.
Single-terminal launcher:
- scripts/dev-up.sh plus `npm run bridge` start the runtime and the bridge in
one terminal, generate a shared CODEWHALE_RUNTIME_TOKEN, wait for /health,
and clean up the runtime on Ctrl-C.
Ignore bridge state and re-include bridge launchers:
- integrations/*-bridge/.state/ holds the live bot token (account.json) and the
poll cursor.
- `*.sh` was hiding integrations/*/scripts/, which would have shipped a
package.json pointing at a file that never landed.
Verification:
- npm --prefix integrations/weixin-bridge run check
- npm --prefix integrations/weixin-bridge test (12 passed)
- npm run bridge logged in by QR and replied to /status from a real WeChat
account; the thread map and poll cursor landed under WEIXIN_STATE_DIR.
- Terminal QR output decoded back to the exact login URL with OpenCV (9/9
payloads, including UTF-8).
Co-Authored-By: DeepSeek-V41-Flash <[email protected]>
Consolidate the canonical pet telemetry, world, score, replay and checkpoint
sources with portable web, Rust, Swift and Kotlin hosts. Embed the same core
in foreground Watch, preserve unknown coverage and native checkpoint files,
and supply reproducible build and QA instructions.
The whale is the home form of a field of dots. Richer work-driven forms are
follow-up work, not a claim that this foundation completes the product.
Validation:
- Fresh source archive: pet typecheck/build, 33 tests passed, 0 failed.
- Fresh source archive npm test: 66 package + 12 SDK + 446 web passed, 0 failed.
- npm run check:web: passed production build with public GitHub release fetch.
- TS/Rust/Swift: 190 matching checkpoints; standalone ratatui build passed.
- Packaged Apple checkpoint/storage/host workflows: 8 passed, 0 failed.
- Legacy local Whalesong consumer check: 306 passed, 0 failed.
Full Rust suite, hosted CI, authenticated live attachment and release
qualification remain separate, unclaimed evidence. See pet/QA.md.
Refs #6109
Remove the Buildkite-only pipeline and step scripts after repository webhook removal and pipeline archival. Keep GitHub Actions, generic CI detection, and existing test coverage intact.
Validation: hermetic test-home checks 8 passed, 0 failed; shell syntax and diff checks passed. No Rust product implementation changed in this commit. Hosted CI and release readiness remain separate.
Remove ten internal critique/receipt documents and two unused images.
Consolidate the duplicate cloud-agent snapshot definition into computer/
with all consumers repaired, preserving image pins and executable content.
Document repository owners, the shared Engine, and tracked generated assets.
Validation:
- Web tests: 440 passed, 0 failed across 49 files.
- Web docs, tokens (64), locales, lint and TypeScript: passed.
- All 19 README languages: 22 local media references valid.
- Edited guides: 48 local links valid; no deleted-path references remain.
- Docker instructions and Rust non-comment content unchanged; packaging,
licenses, notices, brand and repository guidance retained unchanged.
- git diff --check: passed.
Incomplete gates, reported rather than counted as passes:
- Root npm test and npm run check:web: missing package scripts.
- Web check:facts: baseline drift in cloud-facts crate inventory and Codex
authentication label; all facts inputs and generated facts unchanged.
- Next production build: failed fetching four Google Fonts offline
(ENOTFOUND fonts.googleapis.com).
No Rust linking, provider calls, deployment, or public push.
The extension had never successfully started a turn. `startTurn` accepted
only HTTP 200/202 while the runtime's `start_thread_turn`
(crates/tui/src/runtime_api.rs:4613-4632) returns `StatusCode::CREATED` as
its ONLY success path, so every send failed. `git log -- src/api.ts` is a
single commit: this was never a regression, it shipped that way and was
never run end to end.
api.ts (send path):
- Status handling now tests a RANGE (`isOk`: >= 200 && < 300) through one
`ensureOk` helper routed through every call site, rather than enumerating
codes at eleven of them. 201 is accepted because it is 2xx, not because it
is special-cased — the same shape the embedded web client already used at
crates/tui/src/runtime_web/app.mjs:873, which is why that client worked
against the same runtime this one choked on.
- The runtime's JSON `error.message` is surfaced on every route; previously
only startTurn passed it through.
- 409 is typed: a second send while a turn is live is "already running", and
interrupting when nothing streams is "nothing to stop", not an error.
Security (extension.ts, runtime.ts, secrets.ts):
- SecretStorage now wins over the settings token, matching what secrets.ts,
the manifest and the README all already promised. Previously a repo-local
.vscode/settings.json could supply a bearer AND retarget `runtimeHost`,
and the token rode every request — opening a repo was enough.
- The runtime token is passed to the terminal via environment instead of
`--auth-token` in argv, which was visible in shell history and `ps`.
- status.ts nonce uses a CSPRNG, matching chat.ts.
Chat correctness and accessibility (chat.ts, transcript.ts):
- Transcript prefers `detail` over the 280-char `summary`, so reload shows
the reply instead of a stub.
- `operation_key` is reused on retry, so a timeout and resend no longer
creates two turns; the dead SSE stream is cleared so reconnect can fire.
- The composer keeps its text until the turn is accepted.
- Tool paths are parsed out of `metadata.tool_input` and treated as
untrusted. The durable fix is runtime-side and is NOT taken here.
- Focus styling and roles/labels added; there were none.
Chrome (package.json, extension.ts):
- Chat is contributed to the secondary sidebar with an activity-bar
fallback, gated on `codewhale.noSecondarySidebar`, which is set at
activation from `vscode.version` (>= 1.106). One ChatView instance serves
both view ids and `reveal()` focuses whichever resolved.
- `engines.vscode` stays `^1.96.2` and the threshold is enforced at runtime,
matching the shipping Codex extension; raising the floor would have cut
off 1.90-1.105 users and made the fallback unreachable for nothing.
CI and dev loop (ci.yml, .gitignore, .vscode/):
- CI runs the extension tests. Nothing ran them before, which is how a send
path that could not work stayed green.
- launch.json/tasks.json give a working F5 host. The root `.gitignore`'s
bare `.vscode/` silently swallowed them, so a negation was added — without
it these files exist locally and vanish on commit.
Gates:
cd extensions/vscode && npx tsc --noEmit -> clean
cd extensions/vscode && npm test -> tests 42, pass 42, fail 0
(baseline before this was 25)
manifest/provider coherence: every declared view id has a provider;
no provider lacks a manifest entry; context key set at activation.
Not done, deliberately: the Runtime view still exists, so this is not yet a
single-view Agents panel. Removing it spans extension.ts, status.ts and two
commands; a half-removal is worse than either state. Gate item 5 — a human
driving one real turn in an Extension Development Host — remains unproven.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01D4rk4NXwyy6wmvii9Lp84P
Signed-off-by: CodeWhale Bot <[email protected]>
Cargo publication of v0.9.12 stopped at codewhale-tui after 18 crates:
its 16 include_str! paths reached outside the package root, so the
verified tarball could not compile. Move the existing plugin into the
TUI package and update every source, test, CI, documentation, and ignore
reference. Keep one canonical bundle, with all 16 embedded runtime files
byte-identical to the v0.9.12 release payload.
Validation:
- Original cargo publish --locked -p codewhale-tui: FAIL, 16 missing-file
errors; Cargo refused the upload.
- Corrected cargo package --locked --allow-dirty -p codewhale-tui: PASS,
including compilation of the unpacked library and binary.
- npm test in crates/tui/plugins/computer-use: 31 passed; 0 failed.
- Embedded payload comparison: 16/16 original files identical in source
and in the verified Cargo tarball.
- cargo fmt --all -- --check: PASS.
- Coordination npm test && npm run check:web gate: unavailable here;
this Rust repository defines neither root script (both report Missing
script). No broad-suite or hosted-CI pass is claimed.
This is a local packaging repair based on dcd4c200f7. It does not move
the published v0.9.12 tag or alter the already-published release binaries.
Founder ruling R3: codewhale-cu is the canonical computer-use plugin, and it
ships inside the product rather than as a sibling repository. This merges
/Volumes/VIXinSSD/CW/codewhale-cu into plugins/computer-use in the engine's
real bundle format (Agent Plugins v1 plugin.json + sibling mcp.json,
net.codewhale extension) — the format the incoming tree already targeted.
Deleted, with reasons:
- plugins/computer-use/server/server.py + test_server.py (697 lines): a
stdlib-only macOS/Linux MCP server offering screenshot, click, type_text,
press_key, screen_size — and no scroll on macOS. The Node implementation
supersedes it on every axis (38 tools, four platforms, accessibility-first
observation with pixel fallback, recording, ssh/hdc remote computers), so
keeping both would ship two computer-use servers behind one plugin name.
- The invented codewhale-cu.json packaging format and install.mjs never come
across: the engine discovers, reviews, and installs the bundle itself.
- Smoke receipts stay out of the tree (gitignored) — they are per-run local
evidence, not source.
The bundle's own suites now run in CI beside the chat bridges, which already
run dependency-free `node --test` bundles; they cover the manifest contract,
the registry, the exec/ssh transport, the four backends, and the MCP stdio
protocol. The in-repo Rust guard test moves with the bundle: node/server.mjs
instead of python3/server.py, both skills present, and every mcp.json arg
proven to resolve inside the plugin root.
The codewhale-apps binding (packages/desktop-use, PR #181, 40033659) is
repointed deliberately in the same slice, per R3: it imports
<plugin>/src/transport.mjs, which the merge preserves, so only the default
checkout path changes (CODEWHALE_CU_PLUGIN_PATH overrides it). That repo's
suite is green at 7/7 against the new location.
Storage and protocol identifiers are untouched on purpose: the ~/.codewhale-cu
state directory, the remote agent path, CODEWHALE_CU_STATE_DIR, and the MCP
serverInfo name all keep their spelling — those change only through an
explicit migration.
Gates: cargo fmt --all -- --check clean; cargo clippy --workspace
--all-targets --locked -D warnings clean; actionlint on ci.yml reports the
same 12 pre-existing shellcheck notes as HEAD (all in codes CI ignores) and
none in the new step. Lanes: tui 11656 passed/13 skipped, tui-integration
280/0, tui-cucumber 16/0, cli 339/0, config 634 passed/1 skipped, lane 67/0.
Plugin suite: 31 tests run, 31 passed, 0 failed.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_013r9fgwt1HYymrB7iZGSkCm
GROK_TUI_SETTINGS_HANDOFF.md slipped in with #5655 (71253d5656): an
agent-session handoff naming local worktree paths and lane strategy,
referenced nowhere. Preserved in the private ops repo as
HANDOFF-GROK-TUI-SETTINGS-20260829.md; removed here.
.playwright-mcp/ is untracked local output that was one careless
'git add .' from publication.
Signed-off-by: CodeWhale Bot <[email protected]>
Co-authored-by: CodeWhale Bot <[email protected]>
The previous commit added .buildkite/pipeline.yml but not the scripts it
invokes. `.gitignore` line 59 ignores `*.sh` repo-wide, with negations for
`!scripts/**` and `!.github/scripts/**`; `.buildkite/**` had none, so
`git add .buildkite` staged the YAML and silently dropped all three scripts.
Buildkite proved it:
$ .buildkite/steps/lint.sh
/bin/bash: line 1: .buildkite/steps/lint.sh: No such file or directory
🚨 Error: The command exited with status 127
Add the negation in the same shape as the existing two rather than inlining
the commands into YAML: kept as scripts they stay `bash -n`-checkable and
shellcheck-able, which is how the `Workflow lint` job already treats
`.github/workflows`.
Signed-off-by: CodeWhale Bot <[email protected]>
Hosted Chat Completions backends (Baseten, Groq, Cerebras) land as
Compatible setup templates, not ProviderKind variants. MCP manager copy
names the server, the failure, and one recovery command. Idle metrics omit
zeros. Working chrome says "in the current". Nine uncompiled
runtime_contract files are gone. Dead-code budget 448 -> 372.
docs/TOOL_SURFACE.md carried four claims the runtime's own tests contradict:
1. "The default-active policy contains exactly these ten names" listing
`update_plan`. `DEFAULT_ACTIVE_NATIVE_TOOLS`
(crates/tui/src/core/engine/tool_catalog.rs:44-58) has eight entries and
`update_plan` is not among them — it appears nowhere in tool_catalog.rs. The
policy is nine (those eight plus synthetic `tool_search`), eight with memory
disabled. `update_plan` is registered (crates/tui/src/tools/plan.rs:401) but
reachable only through `tool_search`; the tool table now says so.
2. "A memory-disabled or Moraine-fallback runtime". There is no Moraine
fallback — docs/MEMORY.md:11-13 records the removal, and
crates/tui/src/prompts.rs:2445-2449 is a test asserting MEMORY_GUIDANCE must
not contain the word.
3. A "Replay-only aliases" table promising "saved transcripts, sessions, and
recorded automation replay without migration" for 23 names, 16 of which are
asserted REMOVED at crates/tui/src/tools/registry.rs:2066-2088 ("{retired}
must stay removed") and 6 more at :2290-2304 ("{alias} must be removed").
Split into a "Removed spellings" section (with the registry.rs:313-316 note
that resolve has no fuzzy step, so those calls fail rather than dispatch) and
a "Replay-only aliases" section holding only what is still registered:
apply_patch, task_*, github_*, automation_*, rlm_*, checklist_*/todo_*.
4. A "Release verification" block whose three cargo filters name tests that do
not exist (`rg` finds those three strings only in that doc). `cargo test`
exits 0 with "0 passed; N filtered out" on a filter that matches nothing, so
a release engineer following it got three green checkmarks having verified
nothing. Replaced with the real names —
`shell_surface_contains_only_the_canonical_bash_tool` (registry.rs:2290) and
`runtime_task_families_expose_only_canonical_tools` (registry.rs:2333) — plus
the receipt test, and a warning about the silent-pass failure mode.
docs/RUNTIME_SIMPLIFICATION_DESIGN.md repeats errors 1 and 3 and is designated
authoritative by docs/TOOL_LIFECYCLE.md:3-7, but carries no status marker. Given
a status banner naming both divergences and pointing at TOOL_SURFACE.md; the
"Rejected alternatives" provenance is worth keeping, so not deleted.
docs/SUBAGENTS.md:
- "a bounded queue of up to 200 running plus queued sub-agents by default" —
`MAX_SUBAGENT_ADMISSION` is 1024 (crates/tui/src/config/subagent_limits.rs:21),
which is what docs/TOOL_SURFACE.md:182 already said. The 64/128 concurrency
figures on the same page were correct and are untouched.
- The memory section described a `memory.md` that does not exist and omitted the
`scope` parameter. crates/tui/src/tools/remember.rs:165 states the legacy
single-file path was removed in v0.9.4; writes go through
`NativeMemoryStore::remember(scope, workspace_id, note)` (remember.rs:77-108).
config.example.toml documented two key sets that do not exist. Neither struct has
`deny_unknown_fields`, so both were silently discarded rather than rejected:
- `[advisor] max_tool_pairs` / `system_prompt`. `AdvisorConfigToml`
(crates/config/src/lib.rs:2369-2394) has enabled, max_tool_calls (default 10,
clamped 1-50 — the doc said 8, max 32), rate_limit_secs, dedup_window_secs,
and model. `model` was undocumented; now it is.
- `[fleet.profiles.*.permissions] allow_tools` / `deny_tools`.
`FleetProfilePermissions` (lib.rs:1966-1977) has allow_shell, trust,
approval_required. `rg 'allow_tools|deny_tools' crates/` finds nothing. The
example value was `"exec_shell"`, itself a removed tool name.
docs/CONFIGURATION.md: deleted the "Parsed but currently unused" section. Its one
entry, `tools_file`, is not parsed by anything — the field was removed in
346bfe3b6 and the doc bullet was orphaned. Repo-wide `rg` finds the string only
in that section, and nothing links a #parsed-but-currently-unused anchor.
docs/TTC_DESIGN.md said implementation "is deferred beyond v0.9.0". The `verify`
tool shipped and is default-on (crates/tui/src/tools/verify.rs,
features.rs:262, registry.rs:1040-1041 with verify_tool_enabled defaulted true).
Retitled as landed-in-part; capability (B) is still genuinely deferred, so the
doc stays. Its interface line said `with_verify(critic)`; the real signature is
`with_verify_tool(client, model)` (registry.rs:886).
docs/skills/README.md advertised `gh-plan-issues`, deleted in 18de2ebc0, and
credited these skills to "the v0.8.61 release" at a 0.9.4 release.
docs/architecture/provider-model-settings-v091.md pinned
`provider_is_configured` to config.rs:8625-8669; it is at :10160 and that region
is now unrelated code. Replaced with the symbol name, since config.rs is under
active edit.
docs/architecture/command-dispatch.md:133 claimed EPIC-002 was "ready for PR".
The PR (#3706) merged and #2870 closed 2026-08-01. Line 145 was an empty
"Current Evidence (Draft)" heading with no content; removed.
.gitignore: `git check-ignore -v` attributes .claude/settings.json,
scheduled_tasks.lock, worktrees/, and *.local.* to the blanket `.claude/` at
line 126, not to the specific rules above them. Dropped the redundant ones and
annotated why the HANDOFF_/CODEMAP_ patterns are deliberately kept.
Land the contributor's user-command dispatch precedence, shadowing, and error-semantics work after validating the later successful link gate on the exact head.
Rewrite the README in plain developer language — what it is, install, use,
what it does, how to contribute — with details linked out to docs and
codewhale.net. The contributor-culture section stays substantive: feedback
is a gift, harvested PRs keep credit, first-contribution paths explicit.
Translate it into 简体中文, 日本語, Tiếng Việt, 한국어, and (new) Español
and Português so every complete UI locale has a README. Each translation
carries a source stamp, and scripts/check-readme-translations.py — wired
into CI — fails whenever the English README changes without translations
following, or when code blocks, links, or section structure drift.
Machine translations follow each pack's terminology; flagged for native
review.
Make the repo self-explaining where the work happens: crates/tui/AGENTS.md
(shell grammar contract, l10n rules, PTY QA traps), crates/tui/locales/
AGENTS.md (pack parity discipline, translation conventions, how to add a
locale), web/AGENTS.md (derived facts, gate list). The blanket AGENTS.md
gitignore now carves out these maintained files.
Rewrite the 0.8.68 changelog section to cover the complete candidate —
the full underwater shell, streaming/repaint work, the exec JSONL fix,
the 104-key localization layer, harvests, and doc-status work — and
resync the packaged mirror.
Extract shared derivation logic into web/scripts/facts-lib.mjs and
create a check-facts.mjs CI gate that fails when web/lib/facts.generated.ts
is stale relative to the workspace sources.
- facts-lib.mjs: single-source-of-truth derivation shared by
derive-facts.mjs (prebuild) and check-facts.mjs (gate)
- derive-facts.mjs: slimmed to ~63 lines, imports from facts-lib.mjs
- check-facts.mjs: re-derives facts and compares against committed file;
exits non-zero when version, providers, crates, sandboxBackends,
defaultModel, nodeEngines, toolCount, or license have drifted
- web/package.json: add npm run check:facts script
- .github/workflows/web.yml: run check:facts after prebuild in lint job
- web/lib/check-facts.test.ts: 9 vitest tests covering stale version
(0.8.62 vs 0.8.64), provider drift, multi-field detection, edge cases
Closes#3415
Co-authored-by: Hanmiao Li <[email protected]>
Remove public benchmark docs/scripts and the shipped SWE-bench CLI surface from the CodeWhale repo; benchmark work belongs outside this release repo.
Trim public docs that routed users into private maintainer runbooks, remove stale deleted-doc links, tone down release-facing copy, update CodeWhale crate descriptions, and expose the residue ledger as /debt while keeping quiet legacy dispatch compatibility.
Verification:\n- cargo fmt --all -- --check\n- git diff --check\n- ./scripts/release/check-versions.sh\n- cargo check -p codewhale-tui --bin codewhale-tui --locked\n- cargo test -p codewhale-tui --bin codewhale-tui --locked command_registry\n- cargo test -p codewhale-tui --bin codewhale-tui --locked every_command_alias_dispatches_to_a_handler\n- cargo test -p codewhale-cli --locked
Harvest #3009 for the v0.8.59 release lane. Adds a paired Terminal-Bench harness for CodeWhale and Codex, a Codex Harbor adapter, generated-result ignore protection, and benchmark docs.
Maintainer amendments keep explicit zero-valued metrics, regenerate parent task names, write refreshed summaries in regenerate mode, and allow transcript paths outside the repo.
Fixes#2952.
Harvest the HarmonyOS/OpenHarmony port from PR #2634 and make it publish-safe by target-gating unsupported host dependencies out of the OHOS TUI graph. Self-update is disabled on OHOS, PTY shell mode reports unsupported, and Starlark execpolicy parsing returns an explicit unsupported-platform error until upstream starlark/rustyline/nix support catches up.
Add OHOS SDK setup docs and launcher scripts, install the rustls ring provider for rustls-no-provider entrypoints, and keep the packaged codewhale-tui OHOS graph free of starlark, rustyline, [email protected], portable-pty, and arboard.
Validation: cargo fmt --all -- --check; git diff --check; git diff --cached --check; cargo check -p codewhale-cli --locked; cargo check -p codewhale-app-server --locked; cargo check -p codewhale-tui --locked; cargo test -p codewhale-cli --locked update::tests::; cargo test -p codewhale-release --locked; cargo test -p codewhale-tui --locked background_tty_command_has_controlling_terminal; cargo test -p codewhale-tui --locked clipboard; cargo package -p codewhale-tui --allow-dirty --no-verify --locked; packaged OHOS cargo tree checks. OHOS target check still requires a loaded OpenHarmony SDK/sysroot and currently stops in ring with missing assert.h when CC/CFLAGS/linker are unset.
Harvested from PR #2634 by @shenjackyuanjie.
Co-authored-by: shenjackyuanjie <[email protected]>
Splits repo-level guidance into two clear artifacts and deprecates the
confusing WHALE.md concept (overlapped with AGENTS.md):
- AGENTS.md is the canonical cross-agent project-instructions file.
- .codewhale/constitution.json is the CodeWhale-specific repo authority /
prioritization policy (when local sources conflict, which to trust first; what
to verify before claiming done). Rendered into the system prompt as a
higher-authority <codewhale_repo_constitution> block; takes precedence over a
legacy WHALE.md.
WHALE.md migration (compat-preserving):
- AGENTS.md now ranks above WHALE.md in both project and global discovery; with
both present, AGENTS.md wins.
- WHALE.md is still read as a legacy fallback, but now emits a deprecation
warning and is never created or recommended (init.rs no longer suggests it).
- Discovery/docs updated; the global CodeWhale Constitution in prompts/base.md
is unaffected (different thing).
constitution.json:
- New RepoConstitution (serde, all fields optional, unknown fields ignored,
schema_version checked). Discovered at .codewhale/constitution.json in the
workspace or any parent up to the git root. Malformed JSON warns, never panics.
- Loaded after the auto-generate fallback so it can't be clobbered.
.gitignore: ignore .codewhale/ contents at any depth EXCEPT the committed
constitution.json (a directory exclude can't be negated, so **/.codewhale/* +
negation). init.rs writes the same pattern for new repos. Dogfood: this repo's
.codewhale/constitution.json added.
find_git_root made pub(crate) and reused (no duplicate loader).
Tests: AGENTS-over-WHALE precedence, WHALE legacy-read-with-warning,
constitution render + system-block surfacing, malformed-constitution warning,
gitignore-keeps-constitution. cargo test -p codewhale-tui --bins → 3946 passed;
clippy clean.
Targets codex/v0.8.53.
* feat(tui): add command palette voice input
* feat(rlm): expose active session objects
* fix(tui): do not restore slash commands as retry drafts
* fix(config): expose voice input settings rows
* fix: sync ActiveTurnState.auto_approve when remember is set
When a user checks 'Remember for this tool' and approves a tool call,
remember_thread_auto_approve() only persisted thread.auto_approve to disk
but did not update the in-memory ActiveTurnState for the current turn.
This meant subsequent tool calls within the same turn would still require
manual approval, making the remember checkbox appear non-functional.
Now remember_thread_auto_approve() also sets
ActiveTurnState.auto_approve = true, so active_turn_flags() returns
the correct value and the approval_decision() logic auto-approves
remaining tool calls in the current turn.
(cherry picked from commit 2ccf048c89)
* test(runtime): cover remembered auto approve on active turn
---------
Co-authored-by: Ben Gao <[email protected]>
#2011: migrate app state to ~/.codewhale
- Add CodeWhalePaths: codewhale_home(), legacy_deepseek_home(),
resolve_state_dir(), ensure_state_dir() in codewhale-config
- Config: resolve_config_path supports CODEWHALE_CONFIG_PATH env,
default_config_path prefers ~/.codewhale/config.toml
- Project overlay: checks .codewhale/config.toml before .deepseek/
- Sessions: default_sessions_dir uses resolve_state_dir with fallback
- Workspace trust: writes to CodeWhale home via ensure_state_dir
- Init: ensure_deepseek_gitignored adds both .codewhale/ and .deepseek/
- .gitignore: adds .codewhale/
#2010: session artifact hygiene
- /save without path now writes to managed sessions dir instead of cwd
- Boot-time session prune via cleanup_old_sessions (MAX_SESSIONS=50)
- sessions_dir() public accessor for checkpoint path resolution
Fix: load_recent_checkpoint now uses manager.sessions_dir() instead
of hardcoding ~/.deepseek/sessions/checkpoints/
Add a new Volcengine (Volcano Engine Ark) provider for accessing
DeepSeek-V4-Pro and DeepSeek-V4-Flash via the Volcengine Coding API.
Changes:
- Add ProviderKind::Volcengine to config crate with default base_url
pointing to Volcengine Coding API (api/coding/v3)
- Add DeepSeek-V4-Pro and DeepSeek-V4-Flash models to the agent
model registry under Volcengine provider
- Add ApiProvider::Volcengine to TUI with full picker/dropdown support
- Wire up CLI --provider, config get/set/unset, and secrets resolution
- Add environment variable aliases: VOLCENGINE_API_KEY, ARK_API_KEY
- Ignore local dev scripts (*.cmd, backup/)
Add a release follow-up job that updates the Homebrew tap from the checksum manifest when a tap token is configured.
The job now skips before checkout/download/update when neither HOMEBREW_TAP_PAT nor RELEASE_TAG_PAT is configured, so missing tap credentials do not fail an otherwise successful release.
Closes#1602.
Co-authored-by: Zhiping <[email protected]>
Co-authored-by: Oliver-ZPLiu <[email protected]>
Follow-up to the previous commit that removed two leaked handoff
files from `.claude/`. The actual removal landed, but the
`.gitignore` rules that would prevent a future accidental re-add
were left in the working tree by mistake.
Adds:
.claude/HANDOFF_*
.claude/CODEMAP_*
.claude/handoff_* (case-insensitive belt-and-suspenders)
.claude/codemap_*
so `git add .claude/HANDOFF_v0.8.32_*` etc. is silently dropped at
add time instead of slipping through review.
Verified with `git check-ignore`:
.gitignore:89:.claude/handoff_* .claude/HANDOFF_test_scratch.md