Skip to content

Integrate Codewhale 0.9.13 contributor fixes and release verification - #6002

Open
Hmbown wants to merge 170 commits into
mainfrom
integration/new-prs-20260907
Open

Integrate Codewhale 0.9.13 contributor fixes and release verification#6002
Hmbown wants to merge 170 commits into
mainfrom
integration/new-prs-20260907

Conversation

@Hmbown

@Hmbown Hmbown commented Sep 7, 2026

Copy link
Copy Markdown
Owner

This integrates the Codewhale 0.9.13 contributor work and repairs found while testing the combined CLI, terminal UI, Runtime API and bundled Computer Use implementation.

The candidate includes provider catalog pagination and exact routing, OpenRouter vendor selection, output limits and pricing validation, queued paste and slash history, session/task ownership, Fleet isolation, localized notifications, Runtime image inputs and durable turn recovery. Native plugin authoring guides cover English and Chinese, with explicit conversion support and rejection boundaries for OpenCode and DSH. Contributor code and reporting credit are retained.

Follow-up changes make two Windows fixtures portable, reject plugin conversions that would discard source permissions, retain the observed macOS element when dispatching a click, remove duplicated tool guidance, and make the tool-schema metric independent of the inherited shell. Provider failures retain their sanitized underlying cause, and owned OAuth credentials use the earliest known access-token expiry.

Contributor PR implementations represented here: #5996, #5990, #5985, #5984, #5982, #5973, #5946, #5861, #5859, #5842, #5752 and #5726. Some implementations were adapted during integration; this list does not claim every contributor branch was merged unchanged.

Public candidate: a2a7a455bb1d1633f1944caaf57a97533847dcaa. The changelog explicitly marks 0.9.13 as an unreleased candidate.

Verified local evidence:

  • Full workspace, all features at this public head: 15,069 passed, 0 failed, 19 skipped (256.154 seconds), using freshly built binaries in an isolated test home.
  • All 22 version-0.9.13 crates passed the real publication dry run, including compilation of all unpacked tarballs at this exact clean source. No crates uploaded. Two nonfatal macOS debug-link compact-unwind warnings were recorded.
  • Website at 5978f41b6: 440 passed, 0 failed; lint (0 errors, 2 existing image warnings), types and production build passed. The subsequent generated release-note/provenance change passed its 20 focused web tests, docs projection checks and the 26-reference feature-release-note gate.
  • Runtime and persistence budgets passed at 5978f41b6. Runtime tool-schema growth was attributed to individual source changes; 12 measured tool-byte/token ceilings were reconciled with no added headroom. The initial active tool catalog measured 13,274 bytes / 3,319 estimated tokens. These byte-derived estimates are not provider usage or billing receipts.
  • The 11 follow-up commits from the preceding public head passed a redacted secret scan with 0 findings. The security review remains in progress; a clean scan is not a complete security assessment.

Hosted evidence for the preceding 8fbdc5fc head: Buildkite build 1925 passed, with Linux 15,058 passed / 0 failed / 19 skipped and macOS 15,066 passed / 0 failed / 19 skipped, plus lint and doctests. GitHub Linux, macOS, Lint, npm-wrapper and all CodeQL language jobs passed. Windows finished with 14,666 passed / 2 failed / 18 skipped; both failing fixtures are corrected in this candidate. Hosted checks for the current head are running, and their outcomes remain unverified.

The previous advisory Codewhale review refused the complete 556-file, 9,431,066-byte diff at its 8 MiB capture limit before model inference. No completed whole-PR model review is claimed. That review is advisory under the existing repository rules.

The exact-head, nonpublishing release-candidate workflow is running. It does not create a release or upload to a package/container registry. Final artifact acceptance and a completed authenticated session with the requested DeepSeek model and Computer Use—including images, cancellation and recovery—remain release checks. The requested preview returned HTTP 402 on the configured route; availability, vision, tools, speed and price have not been qualified. Local Developer ID signing is separate from notarization and public artifact publication.

Codewhale 0.9.13 is not released. Issue closure follows actual fix and release evidence. Apps deployment/customer activation and live billing remain separate evidence gates. Security disclosure follows patched-release availability.

No-Issue: This release integration combines the contributor fixes and verification listed above; individual issue closure requires its own fix and release evidence.

CodeWhale Bot and others added 22 commits September 2, 2026 13:32
Rewrite $\sim0 error/status strings in en.json (send failures,
permissions, sessions, automation, compaction, provider, telemetry
prefs, voice, clipboard) and lowercase the product name to codewhale
in user-visible inline errors. Keys, placeholders, and parsed
punctuation unchanged.

Tests: 167 targeted + 704 config/runtime_api pass; 65 locale goldens
pass; cargo fmt clean; check-tui-product-vocabulary.sh clean.
Rewrite picker/menu/config/fleet/provider/plugin copy in en.json
(shorter, warmer; product name lowercased to codewhale) and sync the
inline translate() fallbacks plus registry strings that render the
same copy. Keys, placeholders, and parsed punctuation unchanged;
test-pinned phrases (session-model-only, context length/size,
provider rejection wording) preserved.

Tests: 1401 targeted pass; 65 locale goldens pass; cargo fmt clean;
check-tui-product-vocabulary.sh clean.
Rewrite launch/setup/onboarding/telemetry-notice/command-help copy
in en.json (shorter, warmer; product name lowercased to codewhale,
zero capitalized values left) and sync the inline English strings
that render the same copy. Keys, placeholders, and parsed
punctuation unchanged; test-pinned phrases (unknown-command head,
context length/size, separate sign-in, Nothing deleted) preserved.
Pixel-blessed launch goldens untouched (menu keeps Changelog).

Tests: full codewhale-tui lib suite 11909 pass; cargo fmt clean;
check-tui-product-vocabulary.sh clean.
…n reply

Accumulate streamed content into Completed.summary so receipt notes show a bounded deliverable excerpt instead of 'no verifiable output'.

Emit the real saved-session id in the session_capture stream event, persist it on FleetReceipt, and expose it via the runtime API so a client can resolve the worker's final assistant reply through GET /v1/sessions/{id}.
… once, saved_session_id

Maintainer follow-up on #5946 (original by @gaord, preserved below as
c58c74912). Keeps the saved-session half; reworks the summary half per
review:

1. The excerpt now travels in the exec terminal event: the terminal
   `metadata` receipt carries `visible_final_answer_excerpt` (bounded,
   secret-redacted) next to the REAL pre-bound count
   `visible_final_answer_chars` of `summary.output` — the final reply,
   not the opening of the run.
2. The fleet executor's frame accumulator is deleted: nothing streams
   assistant text into per-worker memory anymore; `WorkerStream` only
   records the terminal receipt's answer.
3. Exactly one bound-and-redact helper, `exec_stream_final_answer_excerpt`
   (crates/tui/src/lib.rs, 4,000 chars); the executor-side
   `bounded_worker_summary` and task_spec-side `bounded_receipt_excerpt`
   duplicates are deleted.
4. The terminal frame is parsed exactly once: `parse_exec_terminal_*`
   take `&serde_json::Value`, and `WorkerStream::observe_line` parses
   each line once for route evidence, final answer, session capture, and
   payload mapping (`map_exec_stream_value`).
5. `session_capture.session_id` renamed to `saved_session_id` everywhere,
   and protocol `FleetReceipt.session_id` to `saved_session_id`; all
   consumers updated (runtime_api receipt JSON, manager, task_spec,
   ledger/alerts/control tests); `metadata` stays fingerprint-only and
   `metadata.resume_command` now names the field instead of pretending
   to redact one.
6. Docs updated in docs/AGENT_RUNTIME.md and docs/zh_hans/AGENT_RUNTIME.md.
7. The excerpt also surfaces on FAILED outcomes: it stays on
   `FleetWorkerTerminalEvent.final_answer` whatever the outcome, and a
   no-scorer failed/cancelled receipt keeps the text in its score notes;
   lifecycle event labels show a 160-char excerpt and worker inspection
   summaries bound notes to 240 bytes while payloads/receipts keep the
   full excerpt.

Gates (RUST_MIN_STACK=16777216, shared target dir):
- cargo fmt --all: clean, no changes
- cargo clippy --workspace --all-targets --all-features --locked
  -D warnings -A clippy::uninlined_format_args -A clippy::too_many_arguments
  -A clippy::unnecessary_map_or: pass, 0 warnings
- cargo test -p codewhale-tui --lib --locked -- fleet::executor
  fleet::task_spec fleet::manager terminal_mode_tests::exec_stream
  runtime_api::tests::fleet_receipt: 100 passed, 0 failed
- cargo test -p codewhale-protocol --locked: 85 passed, 0 failed
- cargo test -p codewhale-tui --lib --locked: 11856 passed, 0 failed,
  13 ignored (one earlier run had 1 unrelated tmux clipboard flake that
  passes in isolation; a mass-failure run in between was shared-target-dir
  cross-worktree contamination, not this change)

Signed-off-by: CodeWhale Bot <bot@codewhale.net>
The second half of #5950; the /statusline composition half landed as #5962.

These presets only decide how much of each of the two rows under the composer paints:

  [tui].posture_bar  = full | compact | hidden   (default full)
  [tui].metrics_line = full | compact | hidden   (default full)

Both also settable live with /config posture_bar compact; --save writes the [tui] key, a session-only set says so, and an unknown preset names the three and changes nothing.

compact is not a second renderer: each row keeps its existing shed ladder and the preset starts it at a fixed rung, so what compact keeps is exactly what a narrow row keeps (posture bar starts render_tideline_footer at COMPACT_SHED; metrics line starts shed_pass with every segment at or above SHED_BEFORE_HELP). hidden gives the row to the transcript, resolving info_height/footer_height to 0 exactly as mini mode already did.

Honesty in what the rows claim (respecting #5578): a route that cannot prove its effective reasoning tier states no effort field instead of a placeholder that could never resolve (App::provable_reasoning_effort_label is the single gate); the cost segment is omitted only where the route itself cannot be priced (UsageChip::Unknown on BillingPresentation::Unknown) — cost: unknown stays wherever a price could exist.

Absence in an older config.toml means full; an unknown preset is refused at parse time rather than guessed.

Gates (run by the agent that authored this slice, on the pre-rebase tree; CARGO_PROFILE_DEV_DEBUG=0 to pin own artifacts in the shared target dir):
- cargo fmt --all: clean
- cargo clippy --workspace --all-targets --all-features --locked -- -D warnings (standing allowances): clean
- targeted (config, tui::infoline, tui::phase_strip, tui::ui::frame): 1014 passed / 0 failed / 0 ignored
- full cargo test -p codewhale-tui --lib --locked: 11857 passed / 0 failed / 13 ignored

Rebased onto main 9c66003 by the operator; CI is the gate for the rebased tree.

Signed-off-by: CodeWhale Bot <bot@codewhale.net>
Signed-off-by: CodeWhale Bot <bot@codewhale.net>
…ake; passes on re-roll)

Signed-off-by: CodeWhale Bot <bot@codewhale.net>
The model boundary masks credential-shaped tool output before it reaches an
upstream model (configured secrets plus a CredentialShaped structural pass).
Editing files that contain real credentials has always been awkward because
the model cannot quote those bytes back. This adds a deliberate, documented
opt-out that treats lowering the boundary as a security decision:

- config.toml gains [redaction] model_bound = "enabled" (default) | "disabled";
  "disabled" only records a request.
- After a restart the interactive TUI shows a full-screen startup gate (same
  explicit-key discipline as workspace trust: 1/Y confirm, 2/U keep, 3/N/Esc
  quit; Enter never confirms by reflex).
- Confirming persists a receipt to ~/.codewhale/redaction-state.json and
  rebuilds the engine so its client applies the opt-out. Until a receipt
  exists every process - including headless/exec runs - stays masked.
- The client opt-out covers structured ToolResult blocks only; routing/
  classification summaries and durable goal-state text keep always-on
  redaction.
- Gate copy is localized across all 15 shipped locale packs; enum, JSON, and
  ALL_MESSAGE_IDS stay in sync.
`prune_older_than_keeps_the_newest_and_drops_only_the_old_tail` fails
intermittently on windows-latest with

  assertion `left == right` failed: only the old tail should be removed
    left: 3
   right: 2

The fixture builds two old snapshots, sleeps 8s, then two new ones 1.1s
apart, and cuts at a hardcoded 6s. That assumes `repo.snapshot()` is fast:
`new:0` is only ~1.2s plus one git subprocess older than prune time, so on
a loaded Windows runner that subprocess alone carries it past the 6s line
and it is pruned with the old pair.

The existing fixture guard could not catch it — it asserts on `before[0]`
and `before[2]`, and `before[1]` is the entry that drifts.

The cut is now computed from the timestamps the repo actually recorded:
aim at the midpoint of the gap between the oldest survivor and the newest
victim, which leaves ~4s of slack in both directions instead of depending
on wall-clock luck. The gap itself is asserted first, so a fixture that
collapsed says so plainly rather than failing later as a count mismatch.

Behaviour under test is unchanged: two removed, `new:1` and `new:0`
survive. No production code is touched.

  cargo clippy -p codewhale-tui --lib -> 0 errors
  cargo test -p codewhale-tui --lib -- prune_older_than
    -> test result: ok. 3 passed; 0 failed

Found when it failed the windows leg of #5987, a PR containing zero Rust
files (TypeScript, CI config and .gitignore only), so it cannot have been
caused there.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D4rk4NXwyy6wmvii9Lp84P
Signed-off-by: CodeWhale Bot <bot@codewhale.net>
# Conflicts:
#	CHANGELOG.md
#	crates/tui/CHANGELOG.md
… cumulative stream

Devin follow-up on #5946: in a multi-step turn ExecSummary::output
accumulates every streamed delta, including pre-tool commentary from
earlier steps, so the terminal metadata could present progress text as
the deliverable. Derive visible_final_answer_chars/excerpt from the
last assistant-like message of the persisted session; the cumulative
output stays only as the fallback when the session carries no assistant
text.

Signed-off-by: Ben Gao <bengao168@msn.com>
The model boundary masks credential-shaped tool output before it reaches an
upstream model (configured secrets plus a CredentialShaped structural pass).
Editing files that contain real credentials has always been awkward because
the model cannot quote those bytes back. This adds a deliberate, documented
opt-out that treats lowering the boundary as a security decision:

- config.toml gains [redaction] model_bound = "enabled" (default) | "disabled";
  "disabled" only records a request.
- After a restart the interactive TUI shows a full-screen startup gate (same
  explicit-key discipline as workspace trust: 1/Y confirm, 2/U keep, 3/N/Esc
  quit; Enter never confirms by reflex).
- Confirming persists a receipt to ~/.codewhale/redaction-state.json and
  rebuilds the engine so its client applies the opt-out. Until a receipt
  exists every process - including headless/exec runs - stays masked.
- The client opt-out covers structured ToolResult blocks only; routing/
  classification summaries and durable goal-state text keep always-on
  redaction.
- Gate copy is localized across all 15 shipped locale packs; enum, JSON, and
  ALL_MESSAGE_IDS stay in sync.
Preserve SparkofSpike commit and two-stage confirmation. Resolve client HTTP security validation against current main. Bind consent to readable disabled config bytes and modification time; legacy or missing bindings fail closed.

Validation: config lib 647 passed, 0 failed, 1 ignored; TUI opt-out/gate/localization filters 62 passed, 0 failed; web 407 passed. Negative control against original redaction code: 0 passed, 1 failed (missing config confirmation). fmt, web facts/docs/tokens, lint and TypeScript pass (2 existing lint warnings). Prescribed root npm test && npm run check:web could not run: root package has no test script. Hosted CI and live TUI acceptance not claimed.
Signed-off-by: CodeWhale Bot <bot@codewhale.net>
Resolve changelog conflicts against release preparation, preserve contributor history, and refresh derived release notes including the reviewed redaction opt-out.

Validation: focused chrome and Shannon tests 17 passed, 0 failed; web tests 407 passed, 0 failed. Web facts/docs/tokens, ESLint and TypeScript pass, with 2 existing image warnings. Root npm test && npm run check:web unavailable: missing root test script. Historical Linux Shannon ETXTBSY flake is not claimed fixed. No hosted integration CI or live TUI acceptance claimed.
Signed-off-by: CodeWhale Bot <bot@codewhale.net>
No tree changes. Preserve the rebased contributor commit and the already-tested config-binding fixes. Existing receipts: config 647 passed, 0 failed, 1 ignored; focused TUI 62 passed, 0 failed; web 407 passed. Root npm gate unavailable as previously recorded.

Signed-off-by: CodeWhale Bot <bot@codewhale.net>
Reviewed values against turn_budget.rs and goal configuration resolvers. Web tests 407 passed, 0 failed; docs parity passes. Root npm test/check:web scripts remain unavailable. Preserve original contributor history.

Signed-off-by: CodeWhale Bot <bot@codewhale.net>
Preserve original signed commit. Focused prune tests: 3 passed, 0 failed, including snapshot::repo::tests::prune_older_than_keeps_the_newest_and_drops_only_the_old_tail. No production changes. Combined integration hosted CI remains unrun; root npm test/check:web scripts unavailable as recorded.

Signed-off-by: CodeWhale Bot <bot@codewhale.net>
Founder requested deferring ShannonNet and Levee. Remove the backend, command, delegation/context hooks, configuration, translations, and release claims. Preserve OpenSandbox and backend receipts. Unsupported old backend settings refuse execution instead of silently selecting local execution. Independent project repositories and state remain untouched.

Validation: focused runtime/commands/localization/work-surface tests 153 passed, 0 failed; web tests 407 passed, 0 failed. Web facts/docs/tokens/lint/TypeScript and locale parity pass (2 existing lint warnings); cargo fmt passes. TUI library check passed. Literal root npm test && npm run check:web remains unavailable because the root package lacks scripts. Hosted integration CI not yet run.
Signed-off-by: CodeWhale Bot <bot@codewhale.net>
Copilot AI lite review requested due to automatic review settings September 7, 2026 19:42
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 7, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-07T19:58:33.453480Z 13c0f4a PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@cursor

cursor Bot commented Sep 7, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_3d991310-f22b-41a2-86c6-dd80c49c12bc)

@claude

claude Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Claude finished @Hmbown's task in 2m 42s —— View job


Review: Integrate 0.9.13 PRs and defer ShannonNet execution

Todo list

  • Gather context (CLAUDE.md/AGENTS.md, PR diff against origin/main)
  • Review redaction/opt-out receipt logic (crates/config/src/redaction.rs, crates/tui/src/tui/redaction_gate.rs, crates/tui/src/config.rs)
  • Review ShannonNet removal for completeness/dead references (sandbox/backend.rs, client.rs, commands, locales, docs)
  • Review other integrated changes (chrome presets, snapshot-prune fixture, config docs)
  • Check for provider/model-prefix inference issues (EPIC v0.8.65 EPIC: Separate provider facts, model facts, offerings, and route resolution #2608 invariant)
  • Post final review summary

(Could not run cargo check/cargo test in this sandbox — tool execution required approval that wasn't grantable in this non-interactive review. Findings below are from careful manual reading of the full diff and cross-referencing call sites/grep, not a build.)

Summary

This is a clean, well-executed integration. I did not find correctness bugs or safety issues. Highlights:

  • Redaction opt-out (crates/config/src/redaction.rs, tui/redaction_gate.rs, client.rs): the fail-closed design is sound — confirmed_for_current_request re-derives the config's sha256+mtime binding on every check and sweeps stale receipts; missing/unreadable config, an "enabled" request, or any config edit all correctly fall back to masked. DeepSeekClient::model_bound_masking is computed once at construction from effective_masking(...), and the event loop explicitly rebuilds the engine after a confirmed opt-out (event_loop.rs ~L4789) so the new client picks it up — good, since the engine is spawned before the gate is answered (masking-on by default, as commented). Routing/classification summaries and goal-state text correctly keep unconditional redaction via the separate redact_model_bound_text path, independent of the opt-out flag.
  • ShannonNet removal: verified via grep across the whole tree — no dangling shannon/Shannon references remain outside the intentional negative-test case names in sandbox/backend.rs's unsupported_backend_refuses_execution_instead_of_falling_back_to_local test. All three create_backend call sites (lib.rs, acp_server.rs, core/engine.rs) were updated consistently for the dropped workspace parameter, and workspace remains used elsewhere in those functions (no unused-var/clippy risk). The new UnsupportedBackend correctly refuses execution for old/misspelled sandbox_backend values instead of silently falling back to local exec — matches the PR's stated intent and is a genuine safety improvement. run_subagent_in was cleanly folded back into run_subagent after the delegated-authority hooks (for_child/child_joined/child_context) were removed, and native_store_from_memory_path was correctly narrowed to private now that its only external caller (session_memory_notes) is gone.
  • Chrome row presets (posture_bar/metrics_line): the compact shed-ladder logic in phase_strip.rs/infoline.rs is internally consistent with the existing priority tables (COMPACT_SHED = SHED_COUNTS, segment.id.shed_priority() < SHED_BEFORE_HELP), and /config validation, persistence, and tests look correct.
  • Snapshot-prune fixture fix: deriving the prune cutoff from actual recorded timestamps (midpoint between the surviving/pruned pairs) instead of a fixed 6s window is a reasonable fix for the flake described in the commit message.
  • Locale parity: all 15 locale JSON files carry exactly the 13 new RedactionGate* keys and none retain the removed CmdShannonDescription key.
  • No provider/model-prefix inference issues found — nothing in this diff infers a provider/model switch from a wire-id prefix or freeform text; the sandbox-backend selection is explicit config only.

No blocking issues found. One very minor, non-blocking observation: redaction.rs's config_binding() reads file.metadata()?.modified() before reading the file body — a theoretical TOCTOU window if config.toml is edited between those two calls — but this is a local single-user security opt-out confirmation, not a trust boundary, so it's not worth extra complexity.

Nice attention to detail on the two-stage confirmation UX, the fail-closed receipt binding, and the thoroughness of the ShannonNet removal (docs, changelog, env vars, locales, tests all swept together).

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

It makes high-impact security-boundary and execution-backend behavior changes and still has at least one confirmed correctness issue to address before merge.

Pull request overview

This PR integrates several 0.9.13 release-bound changes (redaction opt-out, bottom chrome presets, config docs, test flake fix) while deferring/removing the experimental ShannonNet sandbox backend so legacy/unknown remote backend settings refuse shell execution rather than silently running locally.

Changes:

  • Add a gated, receipt-bound opt-out for model-bound tool-output redaction ([redaction] model_bound = "disabled") with a two-stage startup confirmation screen.
  • Add [tui].posture_bar / [tui].metrics_line row-size presets (full|compact|hidden) and /config wiring + tests.
  • Remove ShannonNet backend + /shannon command surface, and introduce an UnsupportedBackend that blocks execution for legacy/unknown sandbox_backend values.
File summaries
File Description
web/lib/changelog.generated.ts Changelog entries for redaction gate + chrome presets; removes ShannonNet items
docs/zh_hans/GUIDE.md Documents bottom chrome presets in zh-Hans guide
docs/SANDBOX.md Removes ShannonNet backend docs; states unsupported backends refuse execution
docs/GUIDE.md Documents bottom chrome presets in English guide
docs/CONFIGURATION.md Adds R1 budget key reference + model-bound redaction opt-out documentation
docs/ARCHITECTURE.md Removes ShannonNet backend mention from architecture listing
crates/tui/src/tui/work_surface/model.rs Updates test fixture strings away from ShannonNet path references
crates/tui/src/tui/ui/tests.rs Extends config fixtures with new chrome preset fields
crates/tui/src/tui/ui/frame/one_owner_tests.rs Adds frame layout tests for chrome row presets
crates/tui/src/tui/ui/frame.rs Implements compact/hidden behavior + cost/effort “honesty” rules + renders redaction gate
crates/tui/src/tui/ui/event_loop.rs Arms and handles the redaction startup gate; engine respawn after confirmation
crates/tui/src/tui/redaction_gate.rs New full-screen, two-stage confirmation UI for disabling model-bound masking
crates/tui/src/tui/phase_strip/tideline_tests.rs Adds compact posture bar behavior test
crates/tui/src/tui/phase_strip.rs Omits unprovable effort field; adds compact posture-bar ladder start
crates/tui/src/tui/mod.rs Exposes new redaction_gate module
crates/tui/src/tui/infoline/tests.rs Adds compact metrics-line shedding/hitbox parity test
crates/tui/src/tui/infoline.rs Adds compact metrics-line mode (pre-shed telemetry/help)
crates/tui/src/tui/app/init.rs Initializes new gate state + chrome preset fields from config
crates/tui/src/tui/app.rs Adds app state for gate + chrome presets; adds provable_reasoning_effort_label
crates/tui/src/tools/subagent/mod.rs Removes ShannonNet delegated-authority plumbing from subagent runtime
crates/tui/src/snapshot/repo.rs Fixes Windows flake by deriving prune cutoff from recorded timestamps
crates/tui/src/sandbox/shannon.rs Deletes ShannonNet sandbox backend implementation
crates/tui/src/sandbox/mod.rs Removes shannon module export
crates/tui/src/sandbox/backend.rs Adds UnsupportedBackend that refuses exec for unknown/legacy backends
crates/tui/src/localization.rs Adds RedactionGate message IDs; removes Shannon command message ID
crates/tui/src/lib.rs Updates sandbox backend creation call signature
crates/tui/src/core/engine.rs Updates sandbox backend creation call signature
crates/tui/src/config/tests.rs Adds parsing tests for chrome row presets
crates/tui/src/config.rs Adds chrome row preset config fields + redaction config plumbing; removes Shannon keys
crates/tui/src/commands/mod.rs Removes /shannon from command list
crates/tui/src/commands/groups/utility/shannon.rs Deletes /shannon implementation
crates/tui/src/commands/groups/utility/mod.rs Removes /shannon from utility command group
crates/tui/src/commands/groups/config/config.rs Adds /config support for posture_bar and metrics_line
crates/tui/src/commands/contract.rs Makes native_store_from_memory_path private (no longer re-exported)
crates/tui/src/client.rs Gates model-bound ToolResult redaction on confirmed opt-out; adds tests
crates/tui/src/acp_server.rs Updates sandbox backend creation call signature
crates/tui/locales/zh-Hant.json Adds redaction gate strings; removes Shannon command string
crates/tui/locales/zh-Hans.json Adds redaction gate strings; removes Shannon command string
crates/tui/locales/vi.json Adds redaction gate strings; removes Shannon command string
crates/tui/locales/uk.json Adds redaction gate strings; removes Shannon command string
crates/tui/locales/ru.json Adds redaction gate strings; removes Shannon command string
crates/tui/locales/pt-BR.json Adds redaction gate strings; removes Shannon command string
crates/tui/locales/ko.json Adds redaction gate strings; removes Shannon command string
crates/tui/locales/ja.json Adds redaction gate strings; removes Shannon command string
crates/tui/locales/id.json Adds redaction gate strings; removes Shannon command string
crates/tui/locales/hi.json Adds redaction gate strings; removes Shannon command string
crates/tui/locales/fr.json Adds redaction gate strings; removes Shannon command string
crates/tui/locales/es-419.json Adds redaction gate strings; removes Shannon command string
crates/tui/locales/en.json Adds redaction gate strings; removes Shannon command string
crates/tui/locales/de.json Adds redaction gate strings; removes Shannon command string
crates/tui/locales/ca.json Adds redaction gate strings; removes Shannon command string
crates/tui/CHANGELOG.md Updates TUI changelog entries for chrome presets + redaction; removes ShannonNet items
crates/config/src/redaction.rs New receipt-bound model-bound redaction opt-out implementation + tests
crates/config/src/lib.rs Adds [redaction] table to config schema and accessor
config.example.toml Documents [redaction] opt-out, chrome presets, and [goal] example
CHANGELOG.md Updates root changelog entries for chrome presets + redaction; removes ShannonNet items
Review details
  • Files reviewed: 56/56 changed files
  • Comments generated: 15
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread crates/config/src/redaction.rs Outdated
Comment on lines +249 to +252
let file = fs::File::open(path)?;
let modified = file.metadata()?.modified()?;
let mut body = String::new();
std::io::Read::read_to_string(&mut &file, &mut body)?;
"OnboardTrustUntrustedNotice": "S'ha continuat sense confiança a l'espai de treball — les eines i els hooks continuen restringits.",
"RedactionGateActionConfirm": "confirmar i desactivar",
"RedactionGateActionKeep": "mantenir l'emmascarament",
"RedactionGateActionQuit": "sortir de CodeWhale",
"OnboardTrustUntrustedNotice": "Fortfahren ohne Workspace-Vertrauen — Tools und Hooks bleiben eingeschränkt.",
"RedactionGateActionConfirm": "bestätigen und deaktivieren",
"RedactionGateActionKeep": "Schwärzung beibehalten",
"RedactionGateActionQuit": "CodeWhale beenden",
"OnboardTrustUntrustedNotice": "Continuando sin confiar en el workspace: las herramientas y los hooks siguen restringidos.",
"RedactionGateActionConfirm": "confirmar y desactivar",
"RedactionGateActionKeep": "mantener enmascaramiento",
"RedactionGateActionQuit": "salir de CodeWhale",
"OnboardTrustUntrustedNotice": "Poursuite sans confiance du workspace — les outils et hooks restent restreints.",
"RedactionGateActionConfirm": "confirmer et désactiver",
"RedactionGateActionKeep": "garder le masquage",
"RedactionGateActionQuit": "quitter CodeWhale",
"OnboardTrustUntrustedNotice": "Продолжение без доверия к рабочей области — инструменты и хуки останутся ограниченными.",
"RedactionGateActionConfirm": "подтвердить и отключить",
"RedactionGateActionKeep": "оставить маскирование",
"RedactionGateActionQuit": "выйти из CodeWhale",
"OnboardTrustUntrustedNotice": "Продовження без довіри до робочої області — інструменти та хуки лишаються обмеженими.",
"RedactionGateActionConfirm": "підтвердити й вимкнути",
"RedactionGateActionKeep": "залишити маскування",
"RedactionGateActionQuit": "вийти з CodeWhale",
"OnboardTrustUntrustedNotice": "Tiếp tục mà không tin cậy workspace — công cụ và hook vẫn bị hạn chế.",
"RedactionGateActionConfirm": "xác nhận và tắt",
"RedactionGateActionKeep": "giữ che khóa",
"RedactionGateActionQuit": "thoát CodeWhale",
"OnboardTrustUntrustedNotice": "在未信任工作区的情况下继续 — 工具与钩子保持受限。",
"RedactionGateActionConfirm": "确认并关闭",
"RedactionGateActionKeep": "保持脱敏开启",
"RedactionGateActionQuit": "退出 CodeWhale",
"OnboardTrustUntrustedNotice": "在未信任工作區的情況下繼續 — 工具與鉤子保持受限。",
"RedactionGateActionConfirm": "確認並關閉",
"RedactionGateActionKeep": "保持脫敏開啟",
"RedactionGateActionQuit": "結束 CodeWhale",

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 13c0f4ac29

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/config/src/redaction.rs Outdated
Comment on lines +116 to +119
pub fn default_model_bound_state_path() -> Option<PathBuf> {
crate::default_config_path()
.ok()
.map(|path| path.with_file_name(MODEL_BOUND_STATE_FILE_NAME))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Bind redaction receipts to the loaded config

When the documented --config option (crates/tui/src/lib.rs:226-228) or CODEWHALE_CONFIG_PATH selects another file, this still stores and validates the receipt against the default home config. Consequently, confirmation fails if only the selected config requests disabled masking; worse, an existing receipt for a disabled default config authorizes any selected config that requests disabled masking without binding the confirmation to that file. Pass the resolved config path into the receipt APIs rather than recomputing the default.

AGENTS.md reference: AGENTS.md:L28-L29

Useful? React with 👍 / 👎.

Comment on lines +711 to +715
// A `[redaction] model_bound = "disabled"` request lowers the model-bound
// masking boundary only after an explicit one-time confirmation on this
// startup gate. Arm the gate before the engine spawns so it owns the first
// screen; answering it rebuilds the engine with the confirmed mode.
app.redaction_gate = crate::tui::redaction_gate::confirmation_required(config);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Block initial dispatch until the gate is resolved

For an already-onboarded launch with auto-submitted initial input, run_tui calls submit_initial_input_if_ready before entering the event loop, and that helper checks onboarding but not app.redaction_gate. The first billable request can therefore start behind the confirmation screen, and confirming may subsequently shut down its engine. Defer initial submission until the user confirms or keeps masking enabled.

AGENTS.md reference: AGENTS.md:L28-L29

Useful? React with 👍 / 👎.

Comment thread crates/tui/src/tui/ui/event_loop.rs Outdated
Comment on lines +4814 to +4816
let _ = engine_handle.send(Op::Shutdown).await;
let engine_config = build_engine_config(app, config);
engine_handle = spawn_tui_engine(engine_config, config);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Resync history after rebuilding the engine

When this gate is confirmed while resuming a session, the original engine has already received app.api_messages through the startup Op::SyncSession, but the replacement engine is spawned without an equivalent sync. The transcript still displays the resumed conversation while the model's next turn starts with an empty history. Send the same session snapshot to the replacement before dismissing the gate.

Useful? React with 👍 / 👎.

Comment thread crates/tui/src/tui/ui/event_loop.rs Outdated
Comment on lines +4822 to +4824
app.status_message = Some(format!(
"Failed to record redaction confirmation: {err}"
));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Send gate notices through typed toasts

The confirmation-write error here and the Enter hint below add new writes to the legacy status_message sink, so these notices have no typed severity or lifetime and can overwrite unrelated status state. Route both through the toast API as required for new TUI notices.

AGENTS.md reference: crates/tui/AGENTS.md:L20-L21

Useful? React with 👍 / 👎.

Comment on lines +73 to +75
ActionHint::new(
"1/Y",
app.tr(MessageId::RedactionGateActionConfirm).to_string(),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Source gate key hints from the binding table

These literal 1/Y, 2/U, and 3/N hints duplicate the accepted keys in event_loop.rs; any key-routing change can therefore leave the footer advertising controls the gate no longer accepts. Define the gate actions in shell_key_routing and render their chords from that shared table.

AGENTS.md reference: crates/tui/AGENTS.md:L8-L13

Useful? React with 👍 / 👎.

Comment thread crates/tui/src/tui/redaction_gate.rs Outdated
}
}

fn screen_lines(app: &App, width: usize, _height: usize) -> Vec<Line<'static>> {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep the danger warning visible on short terminals

On compact terminals such as 40x12, the action footer leaves only a few body rows, but screen_lines ignores its height argument and returns the entire wrapped explanation. Paragraph then clips the tail: the first stage loses the risk/effect/rollback guidance, and the shorter second stage can still clip part of the red danger warning while its confirm action remains reachable. Use the available height to shed chrome or provide scrolling while keeping the security warning visible.

AGENTS.md reference: crates/tui/AGENTS.md:L22-L24

Useful? React with 👍 / 👎.

Comment thread CHANGELOG.md
Comment on lines +183 to +186
- Optional model-bound tool-output redaction opt-out, with two explicit startup
confirmations and a receipt bound to the readable config contents and
modification time. Unconfirmed requests keep masking enabled; routing and
stored goal summaries remain redacted (#5982, thanks @SparkofSpike).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve the harvested contributor trailer

This single-parent commit lands the model-bound redaction work from PR #5982 and explicitly credits @SparkofSpike here, but its commit message has neither the required Harvested from PR #5982 by @SparkofSpike line nor the canonical Co-authored-by trailer from .github/AUTHOR_MAP. A changelog thanks does not drive auto-close-harvested.yml or the contribution graph, so add the required mechanical credit before landing.

AGENTS.md reference: AGENTS.md:L201-L206

Useful? React with 👍 / 👎.

@codewhale-agent codewhale-agent Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codewhale review

Integrates redaction opt-out, bottom chrome presets, snapshot prune fixture, and removes ShannonNet. Security-sensitive redaction is fail-closed and tested; removal of ShannonNet correctly refuses unsupported backends instead of local fallback.

Findings

  • [WARNING] Redaction receipt path ignores custom config paths (crates/config/src/redaction.rs)
    default_model_bound_state_path() and config_binding() always use crate::default_config_path(), so a Codewhale session started with --config/CODEWHALE_CONFIG cannot confirm or honor the [redaction] model_bound opt-out against the actual loaded file. record_model_bound_disabled_confirmation() will fail if the default config does not request disabled, or bind to the default config instead of the active one. This fails closed, but makes the feature unusable outside the default config location.
  • [INFO] Stale receipt is not swept on effective_masking(Enabled) (crates/config/src/redaction.rs)
    The doc comment on effective_masking says it sweeps a stale receipt when the desired mode is Enabled, but the function returns immediately for Enabled without touching the receipt. This is not a security issue because confirmed_for_current_request still invalidates stale receipts before honoring Disabled, but the documented cleanup behavior does not occur.

Assessment

The PR looks strong: the security boundary is fail-closed and tested, unsupported sandbox backends refuse execution, and cleanup is focused. The custom-config-path issue in redaction should be fixed before merging, but it does not introduce a security vulnerability.


Advisory review by Codewhale (codewhale review --pr 6002 --post, head 13c0f4ac2939e93b1eb1a485a5dffdd0bb571de7). Line-specific findings are also posted as inline review comments; mechanical fixes arrive as committable suggestions you can apply from the Files tab. CODEOWNERS approval still governs merge.

CodeWhale Bot added 11 commits September 8, 2026 06:53
Update only chacha20 0.10.1 to 0.10.2 in Cargo.lock. RustCrypto yanked
0.10.0/0.10.1 for an SSE4.1 intrinsic used in the SSE2 RNG/legacy backend,
which is undefined behavior when that target feature is unavailable.
The patch preserves MSRV 1.85, enabled dependency edges, and public features.

The lockfile route is oauth2 -> reqwest 0.12 -> optional QUIC -> quinn-proto
-> rand 0.10 -> chacha20. No chacha20 edge is active in this workspace's
all-features/all-targets cargo tree; this does not assert observed exploitation.
Bincode/yaml-rust maintenance warnings and existing audit policy are unchanged.

Validation: cargo update --offline --precise 0.10.2 succeeded; structural lock
comparison confirms exactly one version/checksum change, all other entries
and edges unchanged; locked offline all-features/all-targets dependency
resolution passed; cargo audit --no-fetch: 0 vulnerabilities, 0 yanked crates,
2 existing maintenance warnings; git diff --check passed.
No Rust build/tests or hosted CI run for this dormant lock-only dependency.
Core root has no npm test/check:web scripts. No new advisory ignores.

Upstream: RustCrypto/stream-ciphers#583
Fix: RustCrypto/stream-ciphers#580
Release: https://github.com/RustCrypto/stream-ciphers/releases/tag/chacha20-v0.10.2
Credit giancarlocp discussion #5827 and hxfhd discussion #6010 as public reports without implying a completed fix. Keep the existing website helpers and generated changelog projections aligned.

Validation: 11 credit/projection assertions passed; changelog sync check, release-body shell tests, and git diff --check passed. Rust tests: 0 run; npm/Vitest/web build: 0 run (documentation and credit data only; coordinator owns the combined release gate).
Name the merged cache entry type, collapse five equivalent nested guards,
remove the unit-valued reserved-send binding, and box PR metadata to reduce
ReviewSource variant size. Update the production and test PR constructors.
Keep execution persistence/cancellation ordering and all trust checks intact.

Addresses eight non-allowlisted diagnostics from the strict release lint run.
Rust 1.88 MSRV and edition 2024 already support the let-chains used here;
GitHub/Buildkite stable workflows retain their existing three style allowances.
No new lint allowances or runtime abstractions.

Validation: rustfmt --check passed for all 5 touched files; git diff --check
passed; both PR constructors and borrowed snapshot consumers inspected.
No build, Clippy, or tests rerun in this donor: coordinator owns the shared
exact workspace/all-targets/all-features lint gate. Core root defines no
npm test/check:web scripts. Hosted readiness remains unverified.
Local review previously truncated its diff before model input and receipt
validation, so changes beyond the retained prefix could share a receipt.
Reject character overflow before route execution, writing a receipt, or
checking one. Preserve the existing complete-PR collector and its bounds.
Document explicit path scope, revision/fingerprint evidence, and required
cross-file review without converting advisory non-runs into clean reviews.

Validation:
- rustfmt --edition 2024 --check --config skip_children=true: passed.
- git diff --check: passed.
- Standalone rustc source-extracted guard/test harness: 2 passed, 0 failed.
  Harness uses a Result/bail shim; it is not full crate execution evidence.
- Added focused crate tests: local_review_budget_* (2 selectors).
- Cargo compilation and full crate tests: NOT RUN; delegated to root's
  combined warm-target gate. npm/web gates: NOT RUN (Rust CLI/docs slice).
- No provider calls, public mutations, workflow status changes, or rule edits.
Keep the artifact-root guard on a synchronous test while its current-thread runtime completes the async draft operation. Compare image slices without cloning, pass the existing path reference, and decode the same complete PCM sample pairs with fixed-size chunks.

Validation: workspace/all-targets/all-features Clippy passed with -D warnings and the three existing CI style allowances; rustfmt and git diff --check passed. Unit tests: 0 run in this commit; final combined execution follows. Prior full gate at50a9dae:15064 passed,0 failed,19 skipped, not promoted to this source. Core root has no npm test/check:web scripts.
Use the supported Unreleased candidate heading and HEAD compare endpoint
without inventing a publication date. Correct the introduction to the bundled
Computer Use plugin 0.2.1. Regenerate only the packaged TUI changelog and the
website changelog from the root source.

Validation:
- Changelog/public-surface web tests: 20 passed, 0 failed across 2 files.
- Website docs check: passed (23 topics, version and install snippets).
- Packaged changelog parity and website re-derivation: passed.
- Candidate check-versions.sh: passed with offline Cargo metadata only.
- --require-dated-release: correctly rejected the candidate heading and
  HEAD link with exit 1; publication still requires a real date and tag link.
- git diff --check: passed.
- No Rust build, broad npm/web gate, provider call or public mutation.
@claude

claude Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Claude finished @Hmbown's task in 4m 7s —— View job


Review: Integrate 0.9.13 PRs (fresh pass)

Todo list

  • Gather context (CLAUDE.md/AGENTS.md, PR diff against origin/main, prior review threads)
  • Review crates/config/src/cloud_facts/* (new module — provenance/scope/overlay/verify) — no issues found
  • Review crates/config/src/notifications.rs (new, 901 lines) — no issues found
  • Review crates/app-server/src/lib.rs image/output-limit bridging — no issues found
  • Cross-check previously-flagged P1s (redaction custom-config-path, initial-dispatch gate, stale-receipt sweep) against current HEAD — all confirmed fixed; locale "CodeWhale" branding still open in 13/14 non-English locales
  • Background deep-dive: provider catalog pagination / exact routing safety (provider_catalog_live.rs, provider_lake.rs, route_runtime.rs, resolver)
  • Background deep-dive: chat_completions.rs, cli/lib.rs, cli/metrics.rs, cli/cloud.rs diffs
  • Background deep-dive: verify CodeQL alerts (github/report.rs, task_manager.rs path handling, mcp/http_client.rs HTTPS) are real vs. false positive
  • Post final review summary

CodeWhale Bot added 5 commits September 8, 2026 07:20
The runtime emits turn.usage but the browser did not listen for it, leaving
its predecessor cursor behind and causing false stream-gap recovery. Add
the event to the existing subscription vocabulary. Request diagnostics
advance continuity without summing or replacing authoritative turn totals;
turn.completed continues to own the settled usage projection.

Validation: node --test crates/tui/tests/runtime_web_client.test.mjs: 36
passed, 0 failed, 0 skipped. Enhanced vocabulary/usage regression against
unmodified 52d3 browser source: 0 passed, 1 failed (missing turn.usage).
node --check app.mjs and git diff --check passed. No Cargo build, provider
call, or hosted result claimed.
Apply the existing publication-mode version guard to CNB tag builds. Keep ordinary branch and candidate builds unchanged. Document the independent CNB release destination, actual public GitHub release action, and the maintained crate inventory including cloud-facts.

Validation: existing release-workflow contract suite passed, including its10 wrapper event cases across12steps and new CNB publication ordering assertions. CNB YAML parsed and9 embedded shell blocks passed bash -n in independent review; all8 runbook relative links resolve; git diff --check passed. Rust tests:0 run. No deploy, tag, or release publication.
Translate the changed product introduction, provider/model selection,
contributor layout link and community bug-report directions. Preserve the
rest of each translation and refresh its source stamp only after reconciling
the actual English delta from f73b12c (the previously stamped source).

Validation:
- check-readme-translations.py: all 18 translations pass; source stamp
  330cff827493, matching code fences, links and section counts.
- check-readme-locales.sh: 18 locale links/files symmetric, PASS.
- check-tui-locale-parity.py: all 15 packs complete at 2,200 keys, PASS.
- web/scripts/check-locales.mjs: PASS (documented English fallbacks retained).
- git diff --check: passed.
- Scope: 18 locale READMEs only; 5 added/4 replaced lines in each.
- No Cargo, provider calls, generated source changes, broad npm/web gate
  or public mutations. Root English README and runtime web sources untouched.
@claude

claude Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Claude finished @Hmbown's task in 3m 4s —— View job


Review: Integrate 0.9.13 PRs (fresh pass, continued)

Todo list

  • Gather context (CLAUDE.md/AGENTS.md, PR diff against origin/main, prior review threads)
  • Review crates/config/src/cloud_facts/* (new module — provenance/scope/overlay/verify) — no issues found
  • Review crates/config/src/notifications.rs (new, 901 lines) — the two .expect() calls are guarded by prior validate()/non-empty key segments, safe
  • Review crates/app-server/src/lib.rs image/output-limit bridging — cursor-repeat guard in require_output_limited_model correctly prevents an infinite pagination loop; well covered by output_cap_bridge_checks_support_before_creation_and_forwards_each_surface
  • Cross-check previously-flagged P1s (redaction custom-config-path, initial-dispatch gate, stale-receipt sweep) against current HEAD — all confirmed fixed; locale "CodeWhale" branding still open in 13/14 non-English locales
  • chat_completions.rs OpenRouter vendor pin — confirmed explicit-config only ([providers.openrouter].vendor), never inferred from model string/prefix; matches the provider/route-safety invariant
  • cli/lib.rs --set dispatch — reviewed, no correctness issues
  • cli/metrics.rs audit-history dedup across default/legacy roots — traced the max-count-per-fingerprint algorithm by hand against its test fixture, order-independent and correct
  • cli/cloud.rsOpen: URL now prints verification_uri_complete (embeds the device code) instead of the bare URL; a fix, not a regression
  • Verify CodeQL alerts (github/report.rs, task_manager.rs path handling, mcp/http_client.rs HTTPS, pricing.rs/event_loop.rs cleartext logging) — all reviewed, see summary below
  • Provider catalog pagination / exact routing safety (provider_catalog_live.rs, provider_lake.rs, route_runtime.rs, resolver) — in progress
  • Post final review summary

CodeWhale Bot added 11 commits September 8, 2026 07:55
OpenCode tool restrictions and global, named-agent or legacy-mode permissions
were counted as unrelated application settings. Converting their MCP servers
could therefore discard denials. Refuse those policy-bearing inputs with
manual-port guidance before writing a bundle; retain supported static imports
and the existing native review, trust and runtime authority.

Clarify Streamable HTTP-only output and missing legacy SSE fallback in the
conversion receipt and EN/ZH guides. Replace the obsolete blanket migration
non-goal with the bounded static converter contract.

Validation: 32 Python converter tests passed, 0 failed, 0 skipped. The two new
regression tests fail against the original converter (29 failed assertions
including subtests). All 4 documented EN/ZH conversion examples passed; 28
local links/anchors resolved; both native example pairs matched. git diff
--check passed. No Cargo, native artifact, provider or UI test run in this
slice. Root npm/web gates were not rerun for this scripts/docs-only donor.
Keep interpreter syntax on bash's command parameter and remove its duplicate
from the tool description. Keep lifecycle and scope details on agent fields
and remove repeated prose from the top-level description. All parameter
schemas, roles, scope rules, approval/timeout guidance and dispatch behavior
remain unchanged.

Source-extracted serde JSON measurement at /bin/zsh removes 1,426 serialized
bytes from the initial seven-tool contract: bash457 and agent969. This is
schema size, not provider-token or billing evidence. Remaining legitimate
schema growth and the intentional hidden tts alias need separate reviewed
budget reconciliation; no budget is changed here.

Validation: cargo fmt --all -- --check and git diff --check pass. A tiny
standalone rustc harness using source-extracted functions and the existing
serde_json rlib passed 5 tests (shell interpreter cases, schema equality,
approval/timeout retention, canonical role guard). The old signed8fbd binary's
provider-free shell fixture export passed1 test. Full Cargo compilation and
candidate libtests are explicitly UNRUN in this donor lane; root owns them.
Compare the hook event heading by logical line, as the event table already
does, so Git CRLF checkout preserves the exact heading/count contract.

The Runtime API read-only snapshot was reading an exclusively held empty
process-owner lock and failing with Windows error 33. Use the established
Runtime-store lookup fixture pattern: metadata length proves empty file
content while every path remains in the before/after map. Read all nonempty
files normally with identifying failure context. Preserve authentication,
no-dispatch, settled completion, shutdown-and-wait, ownership release and
restart assertions; do not weaken production locks or retry errors.

Validation: rustfmt checks for both modified files and git diff --check pass.
Source-level LF/CRLF reproduction confirms the former newline assertion fails
on CRLF and exact line matching accepts both. The existing same-pattern
Runtime-store lookup test passed in Windows run 8fbd at test 7617/14668.
0 Rust tests and 0 Windows tests run on this donor; coordinator owns the
combined build and hosted rerun. No production source behavior changed.
Keep 0.9.13 explicitly unreleased. Correct the Computer Use bundle to source89d03ba/version0.2.1, describe supported static OpenCode/DSH conversion and unsupported policy/runtime boundaries, and record the duplicate tool-guidance removal without a billing claim.

Validation: converter32 passed0 failed; changelog Vitest6 passed0 failed; web docs check and candidate version check passed; git diff --check passed. Full npm/web gates were not rerun for this documentation-only slice; last full Core workspace at8fbd was15066 passed0 failed19 skipped.
The ignored tool-catalog metric inherited SHELL, so the same signed8fbd
binary measured14,701 active bytes under /bin/zsh and15,151 under pwsh.
Pin existing SHELL=bash after the fixture's empty PATH; no interpreter is
executed or installed. Record the actual detected binary in a versioned
profile, fail if an already-initialized dispatcher defeats the pin, and
reject missing or mismatched shell evidence in the existing budget checker.
A fresh-process regression compares complete metrics under two inherited
shells. Production tool selection, dispatch and permission code is unchanged.

Reconcile only the intentional hidden tts identity/count already measured
on signed8fbd and explained by d8e8ecf. No byte/token ceiling is raised.
Final numeric reconciliation remains pending root's fresh merged artifact.

Validation: measurement harness3pass0fail; checker harness19pass0fail;
cargo fmt --all -- --check and git diff --check pass. Five exact metric
processes on signed8fbd prove ambient-shell divergence and byte-identical
metrics when the proposed bare-bash setting is applied externally. These
are old-binary input-setting proofs, not compiled-new-fixture evidence.
New Rust fixture regression/full Cargo compilation explicitly UNRUN here;
root owns the fresh signed build and final measurement.
Initial Responses failures displayed only anyhow's outer context, so the
transcript and Alt+V both showed Responses API request failed without its
HTTP/class/cause. Render the full chain through the existing persistence
secret scrubber, as preview and subagent diagnostics already do.

Keep the previous outer text for recovery decisions and error-envelope
classification; only replace the final displayed/durable message. Context
and image retry blocks remain byte-identical, and transport retries are
untouched. Add the actual anyhow-context/typed InvalidRequest shape with
HTTP400 detail and credential redaction, preserving the terminal category.

Validation: cargo fmt --all -- --check and git diff --check pass. Source
comparison confirms the recovery branches are byte-identical. New Rust
regression and full compilation explicitly UNRUN: root owns the next signed
build. No provider calls, credential reads, logging framework or raw body
capture added. The exact dogfood process log was empty and its owned runtime
state had no cause receipt; no live provider diagnosis is claimed.
Vendor CU 4ffebcc67073529a57070ac00d5ac2cbdfaddce5. Exact observed element presses retain app, window, path, role and label and refuse a stale helper or identity without coordinate fallback. Explicit event input retains the ownership guard. Dispatch remains distinct from verified UI effect.

Validation: source CU macOS backend suite 33 passed, 0 failed, including all six native tests. Bundled direct and wire target suite 19 passed, 0 failed. All seven vendored files match the reviewed CU source. Full Core compile and live UI replay remain pending.
Explicit maintainer decision: after removing duplicate guidance and pinning
the existing bash-v2 fixture, set only the 12 tool byte/token ceilings to the
actual e27735b all-features measurement.
Active: 13274/3319; Plan full: 39885/9972; Act/Operate full: 67603/16901.
No margin, prompt/context/skill changes, tool identities, or production edits.

Retained bytes versus the prior budget: active agent -41 plus bash syntax
+431 = +390. Full surfaces also retain Git commit_plan +253 (f94d4aa),
update_goal progress +583 (f5755a8), review refusal +35 (a58cc8c),
and send_later dispatching +14 (f614104). github bounded local-report
fields add +127 Plan / +2151 Act (ab38e43). Act/Operate additionally has
speech +230 and hidden tts -2120 (d8e8ecf), and exact provider-route
fields +274 each in tasks/automation (1228c4f).

The budget predates v0.9.12: its tag already removed 361 agent bytes and
added both 274-byte route fields. Retained initial growth versus that tag
is 751 source-attributed bytes (agent +320, bare-bash syntax +431).
The initial request contains seven active definitions; full catalogs include
deferred tools. Token estimates are the existing bytes/4 heuristic and make
no provider-usage, cache, request-count, or billing claim.

Evidence: verified prebuilt libtest SHA256
5e8cbe213f32c4ecdec63494c4de5e31857b4a40134edf7b21a55bca926b1b38;
receipt SHA256 bc73c899762984833fc249e0b462a7a09bb8ff084b43b9c826e64880450a0bad.
Before: exact receipt fails the old budget at 12 tool size fields.
After: same receipt passes all 55 numeric metrics exactly at budget,
with structural identity and bounded-fragment checks passing.
Python checker tests: 19 passed, 0 failed. git diff --check: passed.
No Cargo build or Rust test run in this budget-only donor.
The e27735b full nextest run exposed one stale assertion that required
`action=wait` in the agent top-level description after duplicated lifecycle
guidance was removed. Verify the existing action/until/detached schema
field descriptions instead: immediate start, observational wait, one/all/
activity completion behavior, default turn ownership and detached lifetime.
Keep top-level start/role/claim and description-size guards unchanged.

Rename that existing test to match its lifecycle coverage. The adjacent
transcript artifact test continues to verify transcript_handle and now
also requires its model-facing handle_read direction. No production tool
text, schema, permissions, runtime behavior or measured budgets change.

Validation: rustfmt --check --edition 2024 on the changed test file passed;
git diff --check passed. Rust execution is explicitly unrun: the coordinator
owns the fresh combined build and rerun. No Cargo/provider calls made.
A parseable stored expires_at previously bypassed the access token JWT exp.
If the stored date was later than the JWT expiry, an expired access token
could be treated as fresh and skip the existing owned-token refresh.
Compare both applicable timestamps and apply the existing 60-second margin
to the earlier one. Opaque tokens still use stored expiry; unknown expiry
still fails freshness. Refresh locking, authority, token storage and provider
retry behavior are unchanged.

Add 13 pure synthetic freshness cases covering both conflict directions,
margin, JWT-only, malformed dates, opaque tokens and empty access tokens.
Extend the existing mock-owned refresh test with future stored expiry plus
expired JWT, verifying the existing refresh/rotation/revoke path handles it.
This source gap is distinct from the observed expired-token rejection;
we did not inspect live credentials or establish the session's expiry cause.

Validation: rustfmt --check --edition 2024 and git diff --check passed.
Source comparison confirms credential precedence, external import, refresh,
activation and token-response functions are unchanged. Rust tests and Cargo
compilation explicitly UNRUN here; coordinator owns the combined rebuild.
No credentials, provider requests or public writes.
Record standalone plugin PR #12 by its qualified upstream URL, retain
its verified hardening provenance, and update the vendored source pin
to 4ffebcc67073529a57070ac00d5ac2cbdfaddce5. Document observed-element
AXPress without point substitution, guarded explicit event clicks,
and the continuing need to verify action effects. Regenerate the TUI
and web changelog projections from the canonical changelog.

Validation: 20 focused web tests passed, 0 failed (2 files); feature
release-note range v0.9.12..HEAD passed all 26 linked references;
TUI projection check, web docs (23 topics), release workflow contracts
(10 event cases x 12 wrapper steps), and git diff --check passed.
Seven changed CU files byte-match standalone 4ffebcc; PR #12 merge
906b433 is its ancestor. No Cargo or full web suite rerun for this
documentation-only delta; the base 5978f41 full web gate passed 440
tests, 0 failed, before this change.
@claude

claude Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Claude finished @Hmbown's task in 2m 35s —— View job


Review: Integrate 0.9.13 PRs (final pass)

Todo list

  • Gather context (CLAUDE.md/AGENTS.md, PR diff against origin/main, prior review threads)
  • Provider catalog pagination / exact routing safety (route/resolver.rs, provider_lake.rs, route_runtime.rs)
  • Cross-check open findings from Copilot/Codex/Codewhale bot/CodeQL against current HEAD
  • Post final review summary

Summary

This was already reviewed in depth across several earlier passes on this thread (redaction opt-out, ShannonNet removal, chrome presets, cloud_facts, notifications.rs, app-server output/image bridging, chat_completions.rs vendor pin, cli/lib.rs / cli/metrics.rs / cli/cloud.rs), all of which found no new correctness or route-safety issues, and confirmed every P1 raised by Codex/Copilot on crates/config/src/redaction.rs and the redaction gate is fixed on this HEAD. This pass focused on the remaining item — provider catalog / exact routing safety — plus verifying the open CodeQL alerts.

Route-safety invariant (EPIC #2608) — holds.

  • crates/config/src/route/resolver.rs: the new resolve_with_endpoint_catalog_authority seam still resolves provider_kind from req.explicit_provider only (never a model prefix). The removed deepseek_versioned_model_prefers_responses helper was itself a prefix-based inference (deepseek-v<digit> → Responses endpoint); its removal in favor of exact catalog-row matching is a safety improvement, not a regression.
  • crates/tui/src/provider_lake.rs::runtime_catalog_resolver_for_identity (provider_lake.rs:589-775): endpoint_catalog_authoritative is only set true when status_is_fresh and every offering row's base_url_fingerprint matches the fingerprint of the exact base_url passed by the caller (row_matches_endpoint_fingerprint, provider_lake.rs:570-631). route_runtime.rs:700-744 passes the actual configured route_config.deepseek_base_url() for the identity being resolved, so a stale/foreign-endpoint roster cannot masquerade as authoritative for a different endpoint. No prefix- or freeform-text-based provider/route inference found.

CodeQL alerts (github-advanced-security review) — all reviewed as false positives:

  • task_manager.rs "uncontrolled data used in path expression" (5 alerts): every path built from task.id is reached only after validate_preallocated_task_id enforces the exact task_<16hex> shape (task_manager.rs:1498, 1554) before admit_task_record/add_task_with_id ever join it into a path. CodeQL's dataflow doesn't model that validation as a sanitizer.
  • pricing.rs:5427 "cleartext logging" of pricing_for_billing_surface(...): there is no log/print call anywhere near this function or its call sites — it's pure cost-calculation logic returning a TurnCostAudit. Mis-attributed by the query; nothing is logged, and pricing numbers aren't a secret in any case.
  • tools/github/report.rs:700 "cleartext logging" of secret: there is no tracing/log/println call in this file at all. The flagged sink is the on-disk issue-draft artifact write, which happens only after safe_text/redact_for_disclosure strips URLs, paths, and credential-shaped tokens — covered by the existing test disclosure_is_applied_before_persistence_and_review.
  • event_loop.rs:1234 "cleartext logging" of session_id: this is the one legitimate println! back on the primary screen after LeaveAlternateScreen, printing the resume hint (codewhale --resume <id>) the user needs to resume their own local session. A session id isn't a credential; this is intended UX for the new resume-hint feature.
  • mcp/http_client.rs:74 "failure to use HTTPS": validate_url intentionally accepts http:// for operator-configured MCP endpoints (e.g. local/private-network servers), gated by explicit_local_target/allow_private_network/is_restricted_ip. Worth noting for awareness (not new to this PR's design): an operator-typed http:// endpoint on a non-local host still gets Authorization headers from with_default_headers (e.g. mcp/http.rs's bearer-token config) sent in cleartext, matching the same class of risk route/resolver.rs already documents and warns about for provider endpoints (v0.8.65: Custom provider endpoints, models, and auth within provider-scoped routing #1519). Not a blocking finding — it's an explicit operator choice, not attacker-controlled input — but a future pass could reuse the existing #1519-style warning for this path too.

Still open, non-blocking (carried from earlier passes, unresolved at current HEAD):

  • 13 of 14 non-English locale files still render "...CodeWhale" instead of Codewhale in the new RedactionGate* strings (ca, de, es-419, fr, hi, id, ja, ko, pt-BR, ru, uk, vi, zh-Hans, zh-Hant — verified via grep -rl CodeWhale crates/tui/locales/*.json, all still present). AGENTS.md: public name is Codewhale; CodeWhale changes only through an explicit migration. Fix this →
  • The gate's 1/Y/2/U/3/N key hints in crates/tui/src/tui/redaction_gate.rs are still literal strings duplicated against the key-matching logic in event_loop.rs (Codex P1, low-risk/non-correctness).

No blocking correctness, route-safety, or security issues found in this pass.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants