| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
fix: isolate extension-host ownership and bind approval grants Recover the interrupted Phase 1 implementation from the preserved 23-file patch after checkpointing its isolated-engine regression. Give each engine its own attachment to the process-wide host, reconcile the reviewed union, and install only that engine's tools. Publish a completed scan only when the entire attachment set still matches, so a workspace change cannot activate or publish stale owners. Bind extension approval and session-grant keys to the plugin identity and reviewed content receipt. Cover approval-gated code-mode execution and preserve the ungated refusal. Share the regular .mjs/.js entry rule between discovery and activation, report invalid entries in review, and correct extension-host/skill authoring guidance while retaining the previous bundled skill generation. Validation on the final source tree: - Focused Rust host/engine/approval/plugin/skill tests: 532 passed, 0 failed, 1 ignored subprocess entry point (exercised by process tests), 13297 filtered. CODEWHALE_EXT_HOST_TESTS=1 required real Node fixtures; no provider calls. - npm test: 636 passed, 0 failed (68 wrapper, 16 SDK, 50 host, 502 web). - npm run check:web: exit 0; facts, docs, tokens, lint, types and production build passed. Existing canonical Git objects supplied the partial clone's missing history without changing generated dates. - cargo fmt --all -- --check and git diff --check passed. The earlier interrupted red-check never completed and is not claimed as evidence. Phase 2 supervision/restart work is not included; existing experimental platform sandbox limitations remain documented. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014ZwqatxgVFxHvovngywnks Signed-off-by: Hunter B <hmbown@gmail.com> | 8 小时前 | |
refactor(split): codewhale-runtime crate and boundary ratchet (RS-0..RS-7) (#6586) * ci(split): RS-0 runtime -> UI boundary ratchet and a hermetic step that cannot pass empty First rail of the runtime/TUI crate split. - scripts/split/module_graph.py: module graph of crates/tui/src and crates/runtime/src with a comment/string-masking lexer and grouped `use crate::{...}` expansion. Computes the runtime closure from the eight seed modules (plus everything already in crates/runtime, plus test-only support modules its tests use) and counts, per module pair: prod / test references into UI code (tui, commands, remote_control, context_report, composer_*, private lib.rs items), "late" references into modules that move after the core (exec_agent, route_preferences), UI-library uses (ratatui, crossterm, codewhale_tui, codewhale_palette), and intra-doc links into UI code. - scripts/runtime-boundary-baseline.json: prod 84, test 95, late 2, uilib 13, doc 1 across 101 closure modules. Any rise or new pair fails with file:line; a drop the baseline did not record also fails (`--update` lowers it and refuses to raise). - scripts/check-command-crate-boundaries.py is now table-driven (BoundaryRule: package, metadata|tree dependency mode, forbidden packages, source scan) and runs the ratchet. `tree` mode reads `cargo tree -p`, which resolves features per package; `cargo metadata` unifies them and would see palette's ratatui feature the TUI enables. The runtime entry lands with the crate (RS-2). - ci.yml hermetic safety step: `cargo test ... -- auto_review authority sandbox` becomes `cargo nextest run --no-tests=fail -E 'test(auto_review) | test(authority) | test(sandbox)'`, and the job installs nextest. After the modules move, the old step would have matched 0 tests and passed. Tests: python3 scripts/test_check_command_crate_boundaries.py -> Ran 19 tests, OK (11 existing + 8 new: tree mode, lexer masking, grouped imports, late/uilib edges, runtime-crate closure, rise/drop, checked-in baseline). python3 scripts/check-command-crate-boundaries.py -> PASS. No Rust changed; no cargo build run for this commit. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h * docs(split): RS-1 record the runtime split sequence and its three departures docs/design/TUI_DECONSTRUCTION.md gains the runtime split sequence (rails, crate with live code, cut upward edges one blocker per slice, rename-only core move, then the client contract) and records where it departs from the older order in the same file, with why each is safe: 1. config moves inside the runtime's strongly connected component instead of leaving first (#6034/#6143 become internal runtime work); 2. loop convergence is not a precondition for moving the engine, because run_subagent and Engine::run_turn move into the same crate; 3. the moves use one root path alias in the TUI lib.rs, deleted at the end, instead of rewriting every caller in the moving change. It also states that the engine, turn loop and tools go into codewhale-runtime (no separate codewhale-engine), why the runtime cannot live in crates/core (command-contract depends on core), and that the TUI stays the only terminal-output owner behind the host_terminal port. docs/ARCHITECTURE.md points at that sequence in its boundary note and corrects crates/secrets's ownership (it also owns the shared sanitizer and redaction). Docs only; no build or test run. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h * refactor(split): RS-2 create codewhale-runtime with 19 live leaf modules `git mv` of the 19 leaf modules that reference nothing outside the batch in production or test code and touch no UI library (7,149 lines): session_tree native_memory goal_loop context_budget continual_harness skill_state tool_history_repair retry_status llm_response_cache sleep_guard media_originals regex_cache elapsed workspace_discovery hashing fast_hash prompt_zones safe_label model_context. - crates/runtime (codewhale-runtime): publishable (version.workspace, no `publish = false`), `[lints] workspace = true`, the TUI's crate-level `#![allow(clippy::uninlined_format_args)]` copied, no build.rs (nothing in the batch needs one). Listed in scripts/release/crates.sh after config/core/memory/models and before tui. The first crates.io publication of the new name happens at the next release run; that is a release-owner decision before this merges. - TUI: 19 `mod` lines replaced by one private alias block `use codewhale_runtime::{...};`, so no TUI file's content changes. examples/zz_perf_probe.rs uses `codewhale_runtime::session_tree` instead of a `#[path]` include. - Visibility widened only where the compiler asked (scripts/split/widen.py, lints capped to warnings during the loop, final pass with lints on): 25 items `pub(crate)` -> `pub` (fast_hash aliases, llm_response_cache API, regex_cache::compile_user_regex, safe_label API and safe_error_text, tool_history_repair receipt, workspace_discovery helpers, hashing), and 12 `expect(dead_code)` / `cfg_attr(not(test), expect(dead_code))` attributes removed because exported items are no longer dead. No security-module items in this batch. - `test-support` feature: retry_status's per-thread test state and readers, SafeLabel::is_redacted and the WorldState diff renders move from `cfg(test)` to `cfg(any(test, feature = "test-support"))`, all `pub`; the TUI enables it from [dev-dependencies] only. - Exported-only fixes: five rustdoc links from public `safe_error_text` to private items became code spans; `WorldState::len` gets a local `allow(clippy::len_without_is_empty)` instead of new API. - Path sweep (scripts/split/move-modules.py): docs, AGENTS.md, check-blocking-calls-budget.json key, check-runtime-contract-budget.py fragment path, dev-test.sh examples; dev-test.sh gains a `runtime` area. - Boundary checker: codewhale-runtime rule in `tree` mode (cargo tree -p, per-package features) forbidding codewhale-tui/cli, ratatui*, crossterm, ansi-to-tui and kit crates, plus a source scan of crates/runtime/src. Ratchet unchanged: prod 84, test 95, late 2, uilib 13, doc 1. Verification (local): - widen.py final pass: cargo check -p codewhale-runtime -p codewhale-tui --lib --tests --examples with lints on: 0 errors. - cargo check -p codewhale-runtime --all-targets (standalone features): ok. - cargo test -p codewhale-runtime --lib: 127 passed; 0 failed. - cargo clippy -p codewhale-runtime --all-targets --all-features -D warnings: clean. - RUSTDOCFLAGS=-Dwarnings cargo doc -p codewhale-runtime --no-deps: clean. - cargo tree -p codewhale-runtime -e normal,build: 0 ratatui/crossterm/tui. - python3 scripts/test_check_command_crate_boundaries.py: 21 tests OK; check-command-crate-boundaries.py: PASS. - validate-crate-publish-order.test.sh: passed. - check-blocking-calls-budget.py: 717 sites, within budget. Not run locally: TUI test execution (the TUI test binary build hit ENOSPC on the shared volume; TUI tests are type-checked only), TUI clippy, check-runtime-contract-budget.py measurement (it builds the TUI tests). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h * refactor(palette): RS-3 make ratatui an optional default feature The headless runtime needs palette's theme-setting and hex normalizers (settings.rs) and RGB tokens (logging.rs), but palette pulled in ratatui unconditionally. `ratatui` is now a default feature; without it the crate is the renderer-free core: - ids.rs (new): ThemeId with from_name/name/display_name/tagline, SELECTABLE_THEMES, normalize_theme_name, USER_THEME_PREFIX, normalize_user_theme_selector, normalize_theme_setting, and a `(u8, u8, u8)` hex parser `parse_hex_rgb` behind normalize_hex_rgb_color (same `#rrggbb` output as before). - rgb.rs (new): the 161 `*_RGB` tuple tokens, split out of tokens.rs with their comments; tokens.rs keeps the 103 `Color` roles. - Behind `#[cfg(feature = "ratatui")]`: adapt, contrast, detect, grammar, osc11, themes (UiTheme, ThemeId::ui_theme, parse_hex_rgb_color, hex_rgb_string), tokens, user_theme, and the crate tests. - The public API with default features is unchanged (lib.rs re-exports the same names), so codewhale-tui needs no edit. The runtime will depend on `codewhale-palette = { default-features = false }` when settings/logging move (RS-14). - Ratchet: codewhale_palette is no longer a UI library for the runtime closure; uilib 13 -> 10 (settings.rs's 3 palette uses drop out). Verification (local): - cargo check -p codewhale-palette --no-default-features --all-targets: ok. - cargo test -p codewhale-palette: 81 passed; 0 failed. - cargo clippy -p codewhale-palette --all-targets -D warnings (default and --no-default-features): clean. - RUSTDOCFLAGS=-Dwarnings cargo doc -p codewhale-palette --no-deps --no-default-features: clean. - cargo check -p codewhale-tui --lib --tests: ok. - python3 scripts/test_check_command_crate_boundaries.py: 21 tests OK. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h * refactor(split): RS-4 the host_terminal port, with raw mode as its first use Runtime code toggled crossterm raw mode directly around interactive children in three places (tools/shell.rs x2, shell_dispatcher.rs), each with its own copy of a restore guard. That is the only crossterm use left in the runtime closure's production code. - codewhale_runtime::host_terminal: the one port for terminal side effects. `HostTerminal` trait (suspend_raw_mode / resume_raw_mode), a first-wins `OnceLock` install, a no-op host when nothing is installed, and `suspend_raw_mode()` returning a `RawModeSuspension` guard that resumes only if raw mode was on (issue #1690 semantics). RS-7 adds the notification-delivery methods to the same trait. - The three call sites use `crate::host_terminal::suspend_raw_mode()`; the three hand-written guard structs are deleted. - tui/ui/terminal.rs: `TuiHostTerminal` implements the port with crossterm; `install_host_terminal()` is called at the top of `run_with_args`, so every mode the binary runs (interactive, exec, serve) keeps today's behavior. Stdio hosts can later be launched without it. - integration harness: `use codewhale_runtime::host_terminal;` at the harness root, like `tool_parser`, for its `#[path]` shell_dispatcher. - Ratchet: uilib 10 -> 1 (tools|crossterm 7 -> 1, the remaining one is a roster_routes test; shell_dispatcher|crossterm 3 -> 0). Verification (local): - cargo test -p codewhale-runtime --lib: 128 passed; 0 failed (adds host_terminal::tests::no_host_suspension_is_a_no_op). - cargo clippy -p codewhale-runtime --all-targets --all-features -D warnings: clean. - RUSTDOCFLAGS=-Dwarnings cargo doc -p codewhale-runtime --no-deps: clean. - cargo check -p codewhale-tui --lib --tests --examples (incl. the integration harness): ok. - python3 scripts/split/module_graph.py: PASS after --update. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h * refactor(split): RS-5 split the voice capture core out of commands::voice runtime_api/voice.rs (the `/v1/voice` routes) imported `crate::commands::voice`, a UI module, for recorder detection, ASR choice and the headless dictation cycle. - New runtime-side module `crate::voice` (774 lines) holds everything that is not a slash command: recorder detection and `is_available`, WAV encoding, `record_audio`, the send-suffix contract (`SEND_PHRASES`, `split_send_suffix`), chat-completions transcription (provider, Groq, local whisper), voice-control, ASR selection, and the headless `dictate_once` / `DictateMode` / `DictateError` / `DictationOutcome`, with their tests (vendor pin, WAV header, send suffix, recorder probe). It uses `config` and `client`, so it moves into codewhale-runtime with the core (M1). - `commands::voice` keeps the three slash commands, the recording status line, `VoiceCaptureOutcome` and `capture_and_transcribe` (it drives the composer while the user speaks), importing the core from `crate::voice`. Seven core functions become `pub(crate)` for that loop; nothing else changes. - runtime_api/voice.rs imports `crate::voice`. - Ratchet: prod runtime_api|commands 10 -> 9. Verification (local): cargo check -p codewhale-tui --lib --tests: ok. The moved tests live in the TUI test binary, which was not linked locally (shared volume at ~8 GB free); they are type-checked only. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h * refactor(split): RS-6 move the context-window formatter down into utils fleet/capability_badges.rs (runtime) imported `tui::model_picker::format_picker_context_window`, a pure formatter. - It moves to `crate::utils::format_context_window` (same body: `1M`, `1.05M`, `262K`, `500`); the picker's 10 call sites and the badges' 6 (including its `1M/1.05M/262K/500` assertions) call it there. - Not merged with `agent_roster::format_tokens` (`1.2k`): that labels usage, not window size, and merging would change output. - Ratchet: prod fleet|tui 1 -> 0. Verification (local): cargo check -p codewhale-tui --lib --tests: ok. The badge and picker tests are in the TUI test binary, which was not linked locally (shared volume at ~8 GB free); type-checked only. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h * refactor(split): RS-7 notification policy down, delivery behind host_terminal Runtime code imported `tui::notifications` and friends: the `notify` tool (tools/notify.rs), native notification preparation (runtime_api/notification_delivery.rs) and headless exec (exec_agent.rs). Per the plan's second review, delivery (OSC 9/99/777 escapes, taskbar and title sequences, stdout writes) stays in the TUI, the one terminal-output owner; only policy moves down. - New runtime-side module `crate::notify`: `git mv` of tui/notification_payload.rs -> notify/payload.rs, tui/notification_audio.rs -> notify/audio.rs, tui/sound_policy.rs -> notify/sound_policy.rs, plus the pure policy that was in tui/notifications.rs: `Method`, `DeliveryOutcome` (+ receipts), `NotificationGate`, `AttentionCondition` and its grace rule, `native_attention_allowed`, and `settings_projection` (now takes `&NotificationsConfig`). It uses `config`, so it moves into codewhale-runtime with the core. - `sanitize_stream_chunk` moves to `codewhale_secrets::sanitize` beside `strip_ansi_into`; the payload and notifications call it there and tui/ui/frame.rs re-exports it for the event loop, which does not change. - host_terminal port gains `notify_model(title, body) -> receipt`, `set_terminal_focused`, and `apply_notification_settings(&NotificationsConfig)` (no-op / "no terminal host" receipt when nothing is installed). The TUI host delegates to `tui::notifications::{notify_model, set_terminal_focused, apply_settings}`; `settings(&Config)` is now a thin wrapper over `apply_settings`, so its ~40 UI call sites are unchanged. - tools/notify.rs calls the port; its emission-chain test (method=off silences the sink) moves to tui::notifications tests, where the chain lives. exec_agent.rs calls the port. - notification_delivery.rs uses `crate::notify`; it still calls `tui::notifications::notify_with_sinks` with null sinks, because that function mixes the policy with transport selection. Known limitation, written in notify/mod.rs: splitting transport out of notify_with_sinks is the remaining step (1 prod runtime_api|tui reference left). - Ratchet: prod 82 -> 75 (runtime_api|tui 5 -> 1, tools|tui 11 -> 8), test 95 -> 89 (tools|tui 19 -> 14, config|tui 10 -> 9). Plan note: RS-7 was scoped to wait for R3/R7 (exec_agent.rs) and #6569 (tui/ui/frame.rs); this branch touches those files and will need a rebase after they land. Verification (local): - cargo check -p codewhale-tui --lib --tests --examples: ok. - cargo test -p codewhale-runtime --lib: 128 passed; 0 failed. - cargo test -p codewhale-secrets --lib: 76 passed; 0 failed; 1 ignored. - cargo clippy -p codewhale-runtime -p codewhale-secrets --all-targets --all-features -D warnings: clean. - RUSTDOCFLAGS=-Dwarnings cargo doc -p codewhale-runtime --no-deps: clean. The notification tests are in the TUI test binary, which was not linked locally (shared volume at ~8 GB free); type-checked only. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h * wip: unfinished review fix-up (interrupted by the session usage limit) Uncommitted edits from the fix-up stage, saved so nothing is lost. Not compiled or tested after these edits; the next pass reviews and finishes them. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h * ci(split): run the ratchet's baseline-ref step under bash; wip fix-up reviewed The boundary step uses `[[ =~ ]]` to skip an all-zero push `before` SHA, so it names `shell: bash` instead of relying on the runner default. This also closes the review of 7c8319eb1 (the interrupted fix-up): its edits were compiled and tested here unchanged, and are kept as they are: - the ratchet compares the committed baseline with the PR base (`--baseline-ref`), so a hand-raised JSON fails CI; - `super::` chains that reach the crate root count as references; - `cargo tree --target all` so cfg(windows) deps are checked too; - the thread-scoped retry state moves from `test-support` to its own `test-thread-scoped-state` feature, debug-assertions only; - RawModeSuspension resumes on the host that suspended it; - palette `ids` tests run without the ratatui gate. Ratchet proven to fail (then reverted): - new `use crate::tui::...` in tools/notify.rs: FAIL, prod tools|tui 8 -> 9 - same edge via `super::super::tui::...`: FAIL, 8 -> 9 - baseline hand-raised to 9 with `--baseline-ref HEAD`: FAIL ("the baseline was raised relative to HEAD") - `use ratatui::...` in crates/runtime/src: FAIL (source-scan) Ratchet on a snapshot of this branch merged with origin/main: PASS. Evidence (local): - cargo check -p codewhale-runtime --locked: ok - cargo check -p codewhale-palette --no-default-features --locked: ok - cargo check -p codewhale-tui --locked: ok, 0 warnings - cargo test -p codewhale-runtime -p codewhale-palette --lib: 130/0 and 84/0 - cargo test -p codewhale-tui --lib -- host_terminal notif retry_status tools::shell: 296 passed, 0 failed, 2 ignored - scripts/test_check_command_crate_boundaries.py: 23/0 - scripts/check-command-crate-boundaries.py --baseline-ref origin/main: PASS - validate-crate-publish-order (crates.sh, includes codewhale-runtime before codewhale-tui): ok; its test script: passed Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h * test(split): pin the notify tool's no-host receipt; document retry-state feature reach Review follow-up on the runtime split (both reviews: ship, no blocker or major findings). - tools::notify: the_model_sees_success_whatever_the_host_did now asserts the exact receipt "notification not sent: no terminal host: done". The old assertion only checked for "done", so a tool that ignored host() and always said "sent" would still have passed. Also fixes the stale capabilities comment (delivery goes through the terminal host now). - runtime::retry_status: documents that Cargo feature unification lets test-thread-scoped-state reach the debug `codewhale` binary under `cargo test --workspace`; release and optimized builds never get it. Behavior note for the series (RS-7): hosts that never install the terminal host (e.g. in-process `cli dispatch`) now get "notification not sent: no terminal host" from the notify tool instead of OSC bytes on stdout. Evidence: - cargo test -p codewhale-tui --lib -- tools::notify: 7 passed; 0 failed. - cargo fmt --all; git diff --check: clean. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h * ci(split): move voice blocking-call budget with the code; list runtime crate in web facts Lint (blocking-calls ratchet): RS-5 moved the synchronous voice transcription core from commands/groups/core/voice.rs to src/voice.rs. The 6 std::fs sites (temp WAV write / sidecar read / cleanup) moved unchanged, so the budget key follows them: voice.rs gets std_fs 6 and the now-clean commands/groups/core/voice.rs entry is dropped. Total site count stays 718 across 202 files; no new debt. --update also tightened fleet/exact.rs (clean on main, std_fs 2 -> 0) and re-sorted the runtime/media_originals.rs entry. Lint & Type Check (web): check:facts failed because the committed facts.generated.ts predates the new `runtime` crate. Regenerated with derive-facts.mjs. Local checks: check-blocking-calls-budget.py within budget (718 sites, 202 files); test_check_blocking_calls_budget.py 11/11 OK; check-facts OK; check-cloud-facts OK; check:latest-release OK; check:tokens OK; derive-changelog current (6 releases); check-versions.sh --range-audit-advisory OK; cargo fmt --check clean; git diff --check clean. Not run locally: web lint/tsc/build/check:docs (no web node_modules in this checkout; PR touches no other web files). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h * fix(web): read palette RGB tokens from rgb.rs after RS-3 RS-3 moved the *_RGB consts from crates/palette/src/tokens.rs to rgb.rs, so check:tokens failed with "no palette RGB consts found". The exporter and the three docs that name the token source now point at rgb.rs. tokens.css changes only its generated-from comment; all 142 token values are identical. Checks: export-design-tokens.py --check: up to date (1 file, 142 tokens). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h * test(core): keep engine tests off exec_agent/runtime_chat_relay for the runtime ratchet Merging origin/main brought two core engine test edges into modules outside the runtime closure: #6517 asserted the isolated-chat prompt via crate::runtime_chat_relay::dedicated_chat_system_prompt(None), and the Auto-Review question fix built the headless catalog via crate::exec_agent::exec_disallowed_tools(None). The RS-0..RS-7 ratchet counts test edges as `late` (they block the crate move like prod edges), so test_checked_in_baseline_holds failed: late core|exec_agent 1 -> 2 and late core|runtime_chat_relay 0 -> 1 (new pair). Both intents are kept without the edges: the engine test asserts the shared ISOLATED_CHAT_SYSTEM_PROMPT (the relay test already pins dedicated_chat_system_prompt(None) to that constant), and the headless half passes the explicit deny list (exec_agent tests already pin exec_disallowed_tools(None) to it). Baseline unchanged. Local: scripts/test_check_command_crate_boundaries.py 23/23 OK; check-command-crate-boundaries.py --baseline-ref origin/main PASS (prod 75, test 89, late 2, uilib 1, doc 1); focused cargo tests 4/4 passed (question_tool_survives..., isolated_runtime_chat_provider_request..., isolated_chat_prompt_drops..., headless_exec_withholds...); other Lint-job python gates green; cargo fmt --all --check and git diff --check clean. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h --------- Co-authored-by: CodeWhale Bot <bot@codewhale.net> Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> | 3 天前 | |
fix(extension-host): close the review findings before the phase-1 PR Two adversarial reviews of 31f55b824 returned fix_then_ship. This applies the proven findings. Approval identity (HIGH): approval keys, card summaries and the approval / auto-review category are derived from the tool name, so a plugin tool named `web_fetch` shared `fetch_url`'s `net:<host>` session grant and ran with no card. `registry::core_special_case` now probes those classifiers and refuses any name they special-case (web_fetch, exec_wait, exec_interact, task_shell_start, read_*/get_*/list_*, ...), on top of the native and prefix rules. macOS sandbox (MEDIUM): the host now cannot read any entry of the Codewhale homes (runtime, ~/.codewhale, legacy ~/.deepseek) except extension-host/, plugins/ and builtin-plugins/ (existing entries by enumeration, known stores by name even before they exist, under both path spellings), nor the Codex home (auth.json) or the DSH home (.credentials.yaml). /plugin now says "no direct network" and that other files, such as project .env files, are not protected. Orphans (MEDIUM): the host leads its own process group (Unix) and kills it at stdin EOF; a watchdog worker thread kills it when the parent changes, even while a plugin blocks the event loop. Also: plugin enable/disable/revoke (TUI and runtime API) reconcile the host at once; the core-service refusal no longer depends on the caller (ctx.root.provide); the tools shim prototype is frozen and the approval card and /plugin disclose when plugins share the host; stderr is read in bounded chunks; Node probing skips relative PATH entries and runs with an empty environment; the flag-off /plugin text is byte-identical again; copy no longer claims every call asks for approval. Fixture tests now install through plugins/install. The design is copied to docs/design/TS_EXTENSION_HOST.md with an as-built section. Evidence (local, macOS arm64, Node 22.20.0): - extension-host `npm test`: 50 passed, 0 failed; `npm run typecheck` clean; `npm run build` reproduces dist/ byte-for-byte. - The 4 new host tests fail on the previous bundle (16 passed, 4 failed) and pass on this one (20 passed, 0 failed). - `CODEWHALE_EXT_HOST_TESTS=1 cargo test -p codewhale-tui --lib -- extension_host engine::tests::extension process_tree dependencies::tests::node commands::groups::plugins`: 47 passed, 0 failed, 0 ignored. The new name-refusal test fails with the probe disabled. - `cargo check -p codewhale-tui --locked --tests`, `cargo fmt --check`, `git diff --check`, check-blocking-calls-budget: clean (supervisor.rs std_fs budget 1 -> 3: the new sites run only under spawn_blocking via plan_launch). - Spawn + handshake + activation 78-95 ms; host RSS 61-63 MB with the watchdog thread (53 MB before). Not verified: Windows build (the msvc cross-check stops in ring's C build on this machine), Linux, hosted CI, hyperfine. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h | 3 天前 | |
fix(computer-use): one recordings directory and backend-level capture path tests Cause: browser-cdp.mjs and trajectory.mjs kept their own recordings directory (under the state dir) while the desktop backends used recordings.mjs (under the home dir), so captures could land in two places when CODEWHALE_CU_STATE_DIR was set. Only recordingsOutputPath itself was tested; no test drove a backend's screenshot or zoom with an outside path, so a backend falling back to the raw path would not have been caught. zoom checked for a previous raster before the output path. Fix: recordingsDir() in recordings.mjs is the only definition (default stateDir()/recordings, which is ~/.codewhale-cu/recordings unless the state dir is moved) and browser-cdp and trajectory import it. darwin, linux and win32 zoom validate the caller's output path before anything else runs. Tests: per-backend cases in tests/recordings-path.test.mjs for darwin, linux, win32 and harmonyos: screenshot and zoom with a path outside the recordings directory or a non-image extension fail with bad_args, write nothing and run no command. With the backends' recordingsOutputPath calls replaced by the raw path: 4 failed; with only zoom's call replaced: 3 failed. - node --test tests/recordings-path.test.mjs: tests 9, pass 9, fail 0 - (cd crates/tui/plugins/computer-use && npm test): tests 392, pass 376, fail 0, skipped 16 - scripts/check-bundled-plugin-claims.py: match Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> | 2 天前 | |
Merge pull request #6753 from Hmbown/fix/skill-package-inputs fix(skills): preserve package identity through install and review | 12 分钟前 | |
fix(skills): preserve package identity through install and review Reuse one frontmatter reader for discovery, profiles and install. Preserve owner executable intent in archives, keep local receipts out of package input, include all payload files and relative paths in bounded digests, and refuse global cache work when a home directory is unavailable. Validation: production cargo check passed; 330 focused Rust tests and 16 CLI install integration tests passed, 0 failed/ignored; npm test 636 passed, 0 failed; npm run check:web passed. Linux exercises the non-UTF8 filename fixture because APFS refuses creating it. Hosted CI pending. Signed-off-by: Hunter B <hmbown@gmail.com> | 5 小时前 | |
refactor(split): codewhale-runtime crate and boundary ratchet (RS-0..RS-7) (#6586) * ci(split): RS-0 runtime -> UI boundary ratchet and a hermetic step that cannot pass empty First rail of the runtime/TUI crate split. - scripts/split/module_graph.py: module graph of crates/tui/src and crates/runtime/src with a comment/string-masking lexer and grouped `use crate::{...}` expansion. Computes the runtime closure from the eight seed modules (plus everything already in crates/runtime, plus test-only support modules its tests use) and counts, per module pair: prod / test references into UI code (tui, commands, remote_control, context_report, composer_*, private lib.rs items), "late" references into modules that move after the core (exec_agent, route_preferences), UI-library uses (ratatui, crossterm, codewhale_tui, codewhale_palette), and intra-doc links into UI code. - scripts/runtime-boundary-baseline.json: prod 84, test 95, late 2, uilib 13, doc 1 across 101 closure modules. Any rise or new pair fails with file:line; a drop the baseline did not record also fails (`--update` lowers it and refuses to raise). - scripts/check-command-crate-boundaries.py is now table-driven (BoundaryRule: package, metadata|tree dependency mode, forbidden packages, source scan) and runs the ratchet. `tree` mode reads `cargo tree -p`, which resolves features per package; `cargo metadata` unifies them and would see palette's ratatui feature the TUI enables. The runtime entry lands with the crate (RS-2). - ci.yml hermetic safety step: `cargo test ... -- auto_review authority sandbox` becomes `cargo nextest run --no-tests=fail -E 'test(auto_review) | test(authority) | test(sandbox)'`, and the job installs nextest. After the modules move, the old step would have matched 0 tests and passed. Tests: python3 scripts/test_check_command_crate_boundaries.py -> Ran 19 tests, OK (11 existing + 8 new: tree mode, lexer masking, grouped imports, late/uilib edges, runtime-crate closure, rise/drop, checked-in baseline). python3 scripts/check-command-crate-boundaries.py -> PASS. No Rust changed; no cargo build run for this commit. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h * docs(split): RS-1 record the runtime split sequence and its three departures docs/design/TUI_DECONSTRUCTION.md gains the runtime split sequence (rails, crate with live code, cut upward edges one blocker per slice, rename-only core move, then the client contract) and records where it departs from the older order in the same file, with why each is safe: 1. config moves inside the runtime's strongly connected component instead of leaving first (#6034/#6143 become internal runtime work); 2. loop convergence is not a precondition for moving the engine, because run_subagent and Engine::run_turn move into the same crate; 3. the moves use one root path alias in the TUI lib.rs, deleted at the end, instead of rewriting every caller in the moving change. It also states that the engine, turn loop and tools go into codewhale-runtime (no separate codewhale-engine), why the runtime cannot live in crates/core (command-contract depends on core), and that the TUI stays the only terminal-output owner behind the host_terminal port. docs/ARCHITECTURE.md points at that sequence in its boundary note and corrects crates/secrets's ownership (it also owns the shared sanitizer and redaction). Docs only; no build or test run. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h * refactor(split): RS-2 create codewhale-runtime with 19 live leaf modules `git mv` of the 19 leaf modules that reference nothing outside the batch in production or test code and touch no UI library (7,149 lines): session_tree native_memory goal_loop context_budget continual_harness skill_state tool_history_repair retry_status llm_response_cache sleep_guard media_originals regex_cache elapsed workspace_discovery hashing fast_hash prompt_zones safe_label model_context. - crates/runtime (codewhale-runtime): publishable (version.workspace, no `publish = false`), `[lints] workspace = true`, the TUI's crate-level `#![allow(clippy::uninlined_format_args)]` copied, no build.rs (nothing in the batch needs one). Listed in scripts/release/crates.sh after config/core/memory/models and before tui. The first crates.io publication of the new name happens at the next release run; that is a release-owner decision before this merges. - TUI: 19 `mod` lines replaced by one private alias block `use codewhale_runtime::{...};`, so no TUI file's content changes. examples/zz_perf_probe.rs uses `codewhale_runtime::session_tree` instead of a `#[path]` include. - Visibility widened only where the compiler asked (scripts/split/widen.py, lints capped to warnings during the loop, final pass with lints on): 25 items `pub(crate)` -> `pub` (fast_hash aliases, llm_response_cache API, regex_cache::compile_user_regex, safe_label API and safe_error_text, tool_history_repair receipt, workspace_discovery helpers, hashing), and 12 `expect(dead_code)` / `cfg_attr(not(test), expect(dead_code))` attributes removed because exported items are no longer dead. No security-module items in this batch. - `test-support` feature: retry_status's per-thread test state and readers, SafeLabel::is_redacted and the WorldState diff renders move from `cfg(test)` to `cfg(any(test, feature = "test-support"))`, all `pub`; the TUI enables it from [dev-dependencies] only. - Exported-only fixes: five rustdoc links from public `safe_error_text` to private items became code spans; `WorldState::len` gets a local `allow(clippy::len_without_is_empty)` instead of new API. - Path sweep (scripts/split/move-modules.py): docs, AGENTS.md, check-blocking-calls-budget.json key, check-runtime-contract-budget.py fragment path, dev-test.sh examples; dev-test.sh gains a `runtime` area. - Boundary checker: codewhale-runtime rule in `tree` mode (cargo tree -p, per-package features) forbidding codewhale-tui/cli, ratatui*, crossterm, ansi-to-tui and kit crates, plus a source scan of crates/runtime/src. Ratchet unchanged: prod 84, test 95, late 2, uilib 13, doc 1. Verification (local): - widen.py final pass: cargo check -p codewhale-runtime -p codewhale-tui --lib --tests --examples with lints on: 0 errors. - cargo check -p codewhale-runtime --all-targets (standalone features): ok. - cargo test -p codewhale-runtime --lib: 127 passed; 0 failed. - cargo clippy -p codewhale-runtime --all-targets --all-features -D warnings: clean. - RUSTDOCFLAGS=-Dwarnings cargo doc -p codewhale-runtime --no-deps: clean. - cargo tree -p codewhale-runtime -e normal,build: 0 ratatui/crossterm/tui. - python3 scripts/test_check_command_crate_boundaries.py: 21 tests OK; check-command-crate-boundaries.py: PASS. - validate-crate-publish-order.test.sh: passed. - check-blocking-calls-budget.py: 717 sites, within budget. Not run locally: TUI test execution (the TUI test binary build hit ENOSPC on the shared volume; TUI tests are type-checked only), TUI clippy, check-runtime-contract-budget.py measurement (it builds the TUI tests). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h * refactor(palette): RS-3 make ratatui an optional default feature The headless runtime needs palette's theme-setting and hex normalizers (settings.rs) and RGB tokens (logging.rs), but palette pulled in ratatui unconditionally. `ratatui` is now a default feature; without it the crate is the renderer-free core: - ids.rs (new): ThemeId with from_name/name/display_name/tagline, SELECTABLE_THEMES, normalize_theme_name, USER_THEME_PREFIX, normalize_user_theme_selector, normalize_theme_setting, and a `(u8, u8, u8)` hex parser `parse_hex_rgb` behind normalize_hex_rgb_color (same `#rrggbb` output as before). - rgb.rs (new): the 161 `*_RGB` tuple tokens, split out of tokens.rs with their comments; tokens.rs keeps the 103 `Color` roles. - Behind `#[cfg(feature = "ratatui")]`: adapt, contrast, detect, grammar, osc11, themes (UiTheme, ThemeId::ui_theme, parse_hex_rgb_color, hex_rgb_string), tokens, user_theme, and the crate tests. - The public API with default features is unchanged (lib.rs re-exports the same names), so codewhale-tui needs no edit. The runtime will depend on `codewhale-palette = { default-features = false }` when settings/logging move (RS-14). - Ratchet: codewhale_palette is no longer a UI library for the runtime closure; uilib 13 -> 10 (settings.rs's 3 palette uses drop out). Verification (local): - cargo check -p codewhale-palette --no-default-features --all-targets: ok. - cargo test -p codewhale-palette: 81 passed; 0 failed. - cargo clippy -p codewhale-palette --all-targets -D warnings (default and --no-default-features): clean. - RUSTDOCFLAGS=-Dwarnings cargo doc -p codewhale-palette --no-deps --no-default-features: clean. - cargo check -p codewhale-tui --lib --tests: ok. - python3 scripts/test_check_command_crate_boundaries.py: 21 tests OK. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h * refactor(split): RS-4 the host_terminal port, with raw mode as its first use Runtime code toggled crossterm raw mode directly around interactive children in three places (tools/shell.rs x2, shell_dispatcher.rs), each with its own copy of a restore guard. That is the only crossterm use left in the runtime closure's production code. - codewhale_runtime::host_terminal: the one port for terminal side effects. `HostTerminal` trait (suspend_raw_mode / resume_raw_mode), a first-wins `OnceLock` install, a no-op host when nothing is installed, and `suspend_raw_mode()` returning a `RawModeSuspension` guard that resumes only if raw mode was on (issue #1690 semantics). RS-7 adds the notification-delivery methods to the same trait. - The three call sites use `crate::host_terminal::suspend_raw_mode()`; the three hand-written guard structs are deleted. - tui/ui/terminal.rs: `TuiHostTerminal` implements the port with crossterm; `install_host_terminal()` is called at the top of `run_with_args`, so every mode the binary runs (interactive, exec, serve) keeps today's behavior. Stdio hosts can later be launched without it. - integration harness: `use codewhale_runtime::host_terminal;` at the harness root, like `tool_parser`, for its `#[path]` shell_dispatcher. - Ratchet: uilib 10 -> 1 (tools|crossterm 7 -> 1, the remaining one is a roster_routes test; shell_dispatcher|crossterm 3 -> 0). Verification (local): - cargo test -p codewhale-runtime --lib: 128 passed; 0 failed (adds host_terminal::tests::no_host_suspension_is_a_no_op). - cargo clippy -p codewhale-runtime --all-targets --all-features -D warnings: clean. - RUSTDOCFLAGS=-Dwarnings cargo doc -p codewhale-runtime --no-deps: clean. - cargo check -p codewhale-tui --lib --tests --examples (incl. the integration harness): ok. - python3 scripts/split/module_graph.py: PASS after --update. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h * refactor(split): RS-5 split the voice capture core out of commands::voice runtime_api/voice.rs (the `/v1/voice` routes) imported `crate::commands::voice`, a UI module, for recorder detection, ASR choice and the headless dictation cycle. - New runtime-side module `crate::voice` (774 lines) holds everything that is not a slash command: recorder detection and `is_available`, WAV encoding, `record_audio`, the send-suffix contract (`SEND_PHRASES`, `split_send_suffix`), chat-completions transcription (provider, Groq, local whisper), voice-control, ASR selection, and the headless `dictate_once` / `DictateMode` / `DictateError` / `DictationOutcome`, with their tests (vendor pin, WAV header, send suffix, recorder probe). It uses `config` and `client`, so it moves into codewhale-runtime with the core (M1). - `commands::voice` keeps the three slash commands, the recording status line, `VoiceCaptureOutcome` and `capture_and_transcribe` (it drives the composer while the user speaks), importing the core from `crate::voice`. Seven core functions become `pub(crate)` for that loop; nothing else changes. - runtime_api/voice.rs imports `crate::voice`. - Ratchet: prod runtime_api|commands 10 -> 9. Verification (local): cargo check -p codewhale-tui --lib --tests: ok. The moved tests live in the TUI test binary, which was not linked locally (shared volume at ~8 GB free); they are type-checked only. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h * refactor(split): RS-6 move the context-window formatter down into utils fleet/capability_badges.rs (runtime) imported `tui::model_picker::format_picker_context_window`, a pure formatter. - It moves to `crate::utils::format_context_window` (same body: `1M`, `1.05M`, `262K`, `500`); the picker's 10 call sites and the badges' 6 (including its `1M/1.05M/262K/500` assertions) call it there. - Not merged with `agent_roster::format_tokens` (`1.2k`): that labels usage, not window size, and merging would change output. - Ratchet: prod fleet|tui 1 -> 0. Verification (local): cargo check -p codewhale-tui --lib --tests: ok. The badge and picker tests are in the TUI test binary, which was not linked locally (shared volume at ~8 GB free); type-checked only. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h * refactor(split): RS-7 notification policy down, delivery behind host_terminal Runtime code imported `tui::notifications` and friends: the `notify` tool (tools/notify.rs), native notification preparation (runtime_api/notification_delivery.rs) and headless exec (exec_agent.rs). Per the plan's second review, delivery (OSC 9/99/777 escapes, taskbar and title sequences, stdout writes) stays in the TUI, the one terminal-output owner; only policy moves down. - New runtime-side module `crate::notify`: `git mv` of tui/notification_payload.rs -> notify/payload.rs, tui/notification_audio.rs -> notify/audio.rs, tui/sound_policy.rs -> notify/sound_policy.rs, plus the pure policy that was in tui/notifications.rs: `Method`, `DeliveryOutcome` (+ receipts), `NotificationGate`, `AttentionCondition` and its grace rule, `native_attention_allowed`, and `settings_projection` (now takes `&NotificationsConfig`). It uses `config`, so it moves into codewhale-runtime with the core. - `sanitize_stream_chunk` moves to `codewhale_secrets::sanitize` beside `strip_ansi_into`; the payload and notifications call it there and tui/ui/frame.rs re-exports it for the event loop, which does not change. - host_terminal port gains `notify_model(title, body) -> receipt`, `set_terminal_focused`, and `apply_notification_settings(&NotificationsConfig)` (no-op / "no terminal host" receipt when nothing is installed). The TUI host delegates to `tui::notifications::{notify_model, set_terminal_focused, apply_settings}`; `settings(&Config)` is now a thin wrapper over `apply_settings`, so its ~40 UI call sites are unchanged. - tools/notify.rs calls the port; its emission-chain test (method=off silences the sink) moves to tui::notifications tests, where the chain lives. exec_agent.rs calls the port. - notification_delivery.rs uses `crate::notify`; it still calls `tui::notifications::notify_with_sinks` with null sinks, because that function mixes the policy with transport selection. Known limitation, written in notify/mod.rs: splitting transport out of notify_with_sinks is the remaining step (1 prod runtime_api|tui reference left). - Ratchet: prod 82 -> 75 (runtime_api|tui 5 -> 1, tools|tui 11 -> 8), test 95 -> 89 (tools|tui 19 -> 14, config|tui 10 -> 9). Plan note: RS-7 was scoped to wait for R3/R7 (exec_agent.rs) and #6569 (tui/ui/frame.rs); this branch touches those files and will need a rebase after they land. Verification (local): - cargo check -p codewhale-tui --lib --tests --examples: ok. - cargo test -p codewhale-runtime --lib: 128 passed; 0 failed. - cargo test -p codewhale-secrets --lib: 76 passed; 0 failed; 1 ignored. - cargo clippy -p codewhale-runtime -p codewhale-secrets --all-targets --all-features -D warnings: clean. - RUSTDOCFLAGS=-Dwarnings cargo doc -p codewhale-runtime --no-deps: clean. The notification tests are in the TUI test binary, which was not linked locally (shared volume at ~8 GB free); type-checked only. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h * wip: unfinished review fix-up (interrupted by the session usage limit) Uncommitted edits from the fix-up stage, saved so nothing is lost. Not compiled or tested after these edits; the next pass reviews and finishes them. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h * ci(split): run the ratchet's baseline-ref step under bash; wip fix-up reviewed The boundary step uses `[[ =~ ]]` to skip an all-zero push `before` SHA, so it names `shell: bash` instead of relying on the runner default. This also closes the review of 7c8319eb1 (the interrupted fix-up): its edits were compiled and tested here unchanged, and are kept as they are: - the ratchet compares the committed baseline with the PR base (`--baseline-ref`), so a hand-raised JSON fails CI; - `super::` chains that reach the crate root count as references; - `cargo tree --target all` so cfg(windows) deps are checked too; - the thread-scoped retry state moves from `test-support` to its own `test-thread-scoped-state` feature, debug-assertions only; - RawModeSuspension resumes on the host that suspended it; - palette `ids` tests run without the ratatui gate. Ratchet proven to fail (then reverted): - new `use crate::tui::...` in tools/notify.rs: FAIL, prod tools|tui 8 -> 9 - same edge via `super::super::tui::...`: FAIL, 8 -> 9 - baseline hand-raised to 9 with `--baseline-ref HEAD`: FAIL ("the baseline was raised relative to HEAD") - `use ratatui::...` in crates/runtime/src: FAIL (source-scan) Ratchet on a snapshot of this branch merged with origin/main: PASS. Evidence (local): - cargo check -p codewhale-runtime --locked: ok - cargo check -p codewhale-palette --no-default-features --locked: ok - cargo check -p codewhale-tui --locked: ok, 0 warnings - cargo test -p codewhale-runtime -p codewhale-palette --lib: 130/0 and 84/0 - cargo test -p codewhale-tui --lib -- host_terminal notif retry_status tools::shell: 296 passed, 0 failed, 2 ignored - scripts/test_check_command_crate_boundaries.py: 23/0 - scripts/check-command-crate-boundaries.py --baseline-ref origin/main: PASS - validate-crate-publish-order (crates.sh, includes codewhale-runtime before codewhale-tui): ok; its test script: passed Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h * test(split): pin the notify tool's no-host receipt; document retry-state feature reach Review follow-up on the runtime split (both reviews: ship, no blocker or major findings). - tools::notify: the_model_sees_success_whatever_the_host_did now asserts the exact receipt "notification not sent: no terminal host: done". The old assertion only checked for "done", so a tool that ignored host() and always said "sent" would still have passed. Also fixes the stale capabilities comment (delivery goes through the terminal host now). - runtime::retry_status: documents that Cargo feature unification lets test-thread-scoped-state reach the debug `codewhale` binary under `cargo test --workspace`; release and optimized builds never get it. Behavior note for the series (RS-7): hosts that never install the terminal host (e.g. in-process `cli dispatch`) now get "notification not sent: no terminal host" from the notify tool instead of OSC bytes on stdout. Evidence: - cargo test -p codewhale-tui --lib -- tools::notify: 7 passed; 0 failed. - cargo fmt --all; git diff --check: clean. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h * ci(split): move voice blocking-call budget with the code; list runtime crate in web facts Lint (blocking-calls ratchet): RS-5 moved the synchronous voice transcription core from commands/groups/core/voice.rs to src/voice.rs. The 6 std::fs sites (temp WAV write / sidecar read / cleanup) moved unchanged, so the budget key follows them: voice.rs gets std_fs 6 and the now-clean commands/groups/core/voice.rs entry is dropped. Total site count stays 718 across 202 files; no new debt. --update also tightened fleet/exact.rs (clean on main, std_fs 2 -> 0) and re-sorted the runtime/media_originals.rs entry. Lint & Type Check (web): check:facts failed because the committed facts.generated.ts predates the new `runtime` crate. Regenerated with derive-facts.mjs. Local checks: check-blocking-calls-budget.py within budget (718 sites, 202 files); test_check_blocking_calls_budget.py 11/11 OK; check-facts OK; check-cloud-facts OK; check:latest-release OK; check:tokens OK; derive-changelog current (6 releases); check-versions.sh --range-audit-advisory OK; cargo fmt --check clean; git diff --check clean. Not run locally: web lint/tsc/build/check:docs (no web node_modules in this checkout; PR touches no other web files). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h * fix(web): read palette RGB tokens from rgb.rs after RS-3 RS-3 moved the *_RGB consts from crates/palette/src/tokens.rs to rgb.rs, so check:tokens failed with "no palette RGB consts found". The exporter and the three docs that name the token source now point at rgb.rs. tokens.css changes only its generated-from comment; all 142 token values are identical. Checks: export-design-tokens.py --check: up to date (1 file, 142 tokens). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h * test(core): keep engine tests off exec_agent/runtime_chat_relay for the runtime ratchet Merging origin/main brought two core engine test edges into modules outside the runtime closure: #6517 asserted the isolated-chat prompt via crate::runtime_chat_relay::dedicated_chat_system_prompt(None), and the Auto-Review question fix built the headless catalog via crate::exec_agent::exec_disallowed_tools(None). The RS-0..RS-7 ratchet counts test edges as `late` (they block the crate move like prod edges), so test_checked_in_baseline_holds failed: late core|exec_agent 1 -> 2 and late core|runtime_chat_relay 0 -> 1 (new pair). Both intents are kept without the edges: the engine test asserts the shared ISOLATED_CHAT_SYSTEM_PROMPT (the relay test already pins dedicated_chat_system_prompt(None) to that constant), and the headless half passes the explicit deny list (exec_agent tests already pin exec_disallowed_tools(None) to it). Baseline unchanged. Local: scripts/test_check_command_crate_boundaries.py 23/23 OK; check-command-crate-boundaries.py --baseline-ref origin/main PASS (prod 75, test 89, late 2, uilib 1, doc 1); focused cargo tests 4/4 passed (question_tool_survives..., isolated_runtime_chat_provider_request..., isolated_chat_prompt_drops..., headless_exec_withholds...); other Lint-job python gates green; cargo fmt --all --check and git diff --check clean. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h --------- Co-authored-by: CodeWhale Bot <bot@codewhale.net> Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> | 3 天前 | |
Merge main into hook execution receipt branch Resolve four changelog/contributor-credit conflicts by preserving both credit sets. The seven original hook implementation, test and documentation patches are unchanged after normalization, including the Runtime metadata exclusion. Validation: npm test 670 passed, 0 failed; npm run check:web passed; version/credit checks passed. Root and independent source-preservation reviews passed. Child HTTP fixtures were blocked by loopback EPERM; the required root gate passed unrestricted. No Rust source conflict was edited and no new local Rust build was claimed. | 4 小时前 | |
release: v0.10.1 CHANGELOG `## [0.10.1] - 2026-09-28` with compare link; credits @gaord for #6664 and @aboimpinto for #6666, the two contributor PRs landed through integrate/0.10.1. Version pins bumped with scripts/release/prepare-release.sh 0.10.1: Feature release-note receipts OK: 27 linked issue reference(s) checked in v0.10.0..HEAD. Version state OK: workspace=0.10.1, npm=0.10.1, npm-binary=0.10.1, lockfile in sync. OHOS Windows linker wrapper contract OK; OHOS dependency graph OK. cargo fmt --check clean. Full preflight (check/clippy/test) is left to CI. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014ZwqatxgVFxHvovngywnks | 20 小时前 | |
fix(build): resolve native helper sources in the active checkout [skip ci] Read CARGO_MANIFEST_DIR at build-script execution for CLI and TUI helper builds. A shared Cargo target no longer invokes clang on a removed worktree. Keep the workspace-only relocation fixture out of the published build-support crate. Verification: both real build-script relocation regressions passed (2 passed, 0 failed). Default-feature cargo check --workspace --all-targets --locked passed on the integration tree. Workspace all-target/all-feature Clippy with release gate allow flags and cargo fmt --check passed. Crate packaging remains a later candidate gate. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> | 16 天前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 8 小时前 | ||
| 3 天前 | ||
| 3 天前 | ||
| 2 天前 | ||
| 12 分钟前 | ||
| 5 小时前 | ||
| 3 天前 | ||
| 4 小时前 | ||
| 20 小时前 | ||
| 16 天前 |