Add a typed [verifier] config table for the v0.8.67 verifier-preview lane. The only shipped verdict policy remains hunt, so unknown policies are rejected instead of silently accepted.
Document the surface in config.example.toml, CONFIGURATION.md, and the Unreleased changelog.
Verification:
- cargo fmt --all -- --check
- git diff --check
- CARGO_TARGET_DIR=/Volumes/VIXinSSD/codewhale-target cargo test -p codewhale-config verifier_config --locked
- CARGO_TARGET_DIR=/Volumes/VIXinSSD/codewhale-target cargo test -p codewhale-tui config::tests::verifier_config_parses_hunt_policy_and_merges_overrides --locked
Part of #2093
Signed-off-by: Codex <[email protected]>
- command-dispatch.md: update EPIC-002 status to Phase 8 complete
- pr-issue-evidence-prep.md: replace ⬜ placeholders with ✅ final results
- Record all validation: 489 command tests passed, 2 acceptance tests passed,
5344/5345 workspace tests passed (1 known-flaky papercut)
- Sign off as Paulo Aboim Pinto
- eval_smoke_acceptance.rs: collapse multi-line string constant to single line (cargo fmt fix)
- command-dispatch.md: advance EPIC-002 status from Phase 6 to Phase 7,
replace detailed Phase 6 evidence list with concise 'Current Evidence' summary
Phase 7 code review (F1) found the FEAT-008 PR Summary Draft did not
follow the required PR #3652 pattern: it jumped directly from the heading
to ## Summary without the PR title or Refs #2870. opening line.
Added the title line (Layer 4.4: Registry cleanup, docs, and full
validation (FEAT-008)) as a reference outside the markdown fence, and
Refs #2870. as the first line of the PR body markdown.
This is a code-review recovery fix for FEAT-008 Phase 7.
Code review REQUIRED finding F1: The public validation list still referenced
the deleted command_surfaces_acceptance target. Replaced with the current
eval_smoke_acceptance test and noted it is eval smoke, not AT-004
command-surface evidence.
Ref: FEAT-008 Phase 6 code review 2026-06-27T14:09:26.829Z
F1 [REQUIRED/test-coverage]: Rename command_surfaces.feature and
command_surfaces_acceptance.rs to eval_smoke.feature and
eval_smoke_acceptance.rs to stop implying AT-004 command-surface coverage.
Update world struct name, file path constant, and feature file header to
match. Feature file now includes disclaimer that this is not AT-004 evidence.
F2 [REQUIRED/docs-status]: command-dispatch.md evidence items use '— draft'
instead of '— pass'. pr-issue-evidence-prep.md result cells use
'⬜ Draft (Phase 6 current evidence)' instead of '⬜ Pass (draft Phase 6
evidence)'.
F3 [REQUIRED/docs-status]: FeatureTasks.md status line updated from
'Phase 6 COMPLETED' to 'Phase 6 NEEDS_CHANGES' reflecting latest code review.
Review Finding Decision Ledger recorded in phase-6-integration.md.
F1: Remap command_surfaces acceptance test as eval smoke test.
Stop counting it as AT-004 command-surface evidence — rename
feature/scenario/step text from 'command surface acceptance' to
'eval smoke test' and update runner doc comments.
F2: Rewrite public docs with draft/Phase 6 in-progress status.
command-dispatch.md: EPIC-002 Completion Status → Draft —
Phase 6 In Progress with neutral table status.
pr-issue-evidence-prep.md: Add draft header, replace ✅ with ⬜
neutral placeholders, mark all evidence as draft Phase 6.
F3: Update FeatureTasks.md status line to include Phase 6
AWAITING_REVIEW state with code review NEEDS_CHANGES note.
Also update phase-6-integration.md AT-004 row and
planning-analysis-report.md to remove command_surfaces from
AT-004 evidence, adjust count from 40 to 39.
The plugins row claimed 'list, install, and configure tools' but live
source only supports plugin discovery/listing and per-plugin metadata
detail display. No install/configure command behavior exists.
Discovered by FEAT-008 Phase 4 code review.
Refs: FEAT-008
The architecture doc only listed /jihua and /zidong as legacy/permanent
aliases, but live dispatch (commands/mod.rs:157-168) also has /slop and
/canzha dispatching directly to /debt in the same pre-registry match block.
- Updated dispatch flow Step 2 to list all four permanent aliases.
- Updated Permanent Exceptions first row to include all four aliases.
Refs: FEAT-008 Phase 4 code review finding #1
The Built-In Command Groups table listed 8 groups but the live source
registers 9 (including plugins::PluginsCommands). Added the /plugins
entry and removed the stale 'plugins' mention from utility scope.
Found during FEAT-008 Phase 4 documentation verification (Task 6).
Follow-up to #3698. The ACP adapter buffered the whole turn: it called the
non-streaming `create_message` and emitted a single `session/update` chunk
only after the provider finished. Editors like Zed show agent output
incrementally, so users waited for the entire response with no feedback, and
the readiness audit listed non-streaming as a known limitation.
Stream the turn instead, reusing the existing `LlmClient::create_message_stream`
path that the TUI engine already uses:
- `open_prompt_stream` builds the request with `stream: true` and returns the
`'static` `StreamEventBox`. It borrows `&self` only to read config/model and
open the stream, so the caller can race it against the reader without holding
a borrow on the server.
- `drive_prompt_stream` consumes the stream concurrently with the input reader:
each text delta (`content_block_delta`/`content_block_start` text) is emitted
as its own `session/update` agent_message_chunk as it arrives; `message_stop`
or stream end completes the turn with the accumulated text (recorded in
history); a provider stream error surfaces as a JSON-RPC error.
- Cancellation is preserved and now interrupts mid-stream: a matching
`session/cancel` returns `stopReason: "cancelled"` and dropping the stream
aborts the underlying provider connection. Single-flight semantics are
unchanged (other-session cancel ignored; concurrent request rejected with a
clear error). The single-writer invariant holds, so streamed chunks and
acknowledgements stay on one protocol-clean stdout stream.
The streaming + cancellation control logic stays a free function over the
reader/writer + boxed stream, so it is unit-tested with canned in-memory
streams (delta-by-delta chunking, cancel mid-stream, other-session cancel
ignored, concurrent request rejected) — no real provider call. Full bin suite
5521 green; fmt + clippy clean. Updates docs/ACP_REGISTRY_SUBMISSION.md.
Refs #3192.
Signed-off-by: findshan <[email protected]>
The ACP stdio adapter processed input strictly serially: the read loop
awaited each request — including the full provider call behind
`session/prompt` — before reading the next line. A `session/cancel`
therefore could not even be observed until the turn it was meant to
cancel had already finished, so it was a documented no-op (it just
returned `null`). Editors like Zed send `session/cancel` when the user
hits Esc, so the in-flight turn kept running and streamed a result the
user no longer wanted.
Drive `session/prompt` concurrently with the reader instead:
- `run_prompt` borrows `&self` only and never touches the writer, so it
is raced against `reader.next_line()` in `drive_prompt_with_cancellation`
while the main task keeps exclusive ownership of stdout — stdout stays
protocol-clean (the existing single-line-JSON invariant holds).
- A `session/cancel` for the in-flight session (request or notification
form) aborts the awaited provider call and the prompt returns
`stopReason: "cancelled"`; the assistant turn is not appended to history.
- A no-prompt `session/cancel` remains an idempotent `null` no-op.
- The turn is single-flight: a cancel for a different session is
acknowledged and ignored; any other concurrent request gets a clear
"prompt in progress" error rather than being silently dropped.
The cancellation control logic is extracted into a generic free function
so it is unit-tested with a delayed future and an in-memory reader — no
real provider call required. 4 new tests cover complete, cancel,
other-session-ignored, and concurrent-request-rejected paths.
Refs #3192 (advances the ACP readiness audit in docs/ACP_REGISTRY_SUBMISSION.md).
Signed-off-by: findshan <[email protected]>
Addresses maintainer review on #3638: replacing the global Constitution is a
prompt trust boundary, so the override file alone must not be enough. Gate it
behind an explicit CODEWHALE_ALLOW_BASE_PROMPT_OVERRIDE flag — the file is
ignored (with a log line pointing to the flag) unless the user has deliberately
opted in. Makes replacing the base prompt a two-step, auditable action.
- prompts.rs: BASE_PROMPT_OVERRIDE_OPT_IN_ENV + base_prompt_override_opt_in();
load_config_dir_prompt_overrides now requires it. Added a test that a present
file without the flag applies nothing (safe: no global cell mutation).
- docs/CONFIGURATION.md: document the two-step opt-in.
Refs #3638
Signed-off-by: findshan <[email protected]>
Today the Repo Working Set block only injects a path *list* ("Active paths
(prioritize these)"), so the model must spend tool calls re-reading files it
already touched. #528 asks for a cache-maximal mode that keeps the active
files' full contents resident in context each turn, trading a larger but
byte-stable prefix for far fewer re-read round-trips and high KV prefix-cache
hit rates on DeepSeek.
This adds an opt-in cache-maximal mode to the working set:
- WorkingSetConfig gains cache_maximal + per-file/total byte caps (serde
defaults so existing persisted sessions deserialize unchanged).
- summary_block, when enabled, appends an "### Active file contents
(cache-resident)" section: the top active files (existing
sorted_for_prompt order) materialized as fenced blocks, bounded by
max_resident_file_bytes per file and max_total_resident_bytes overall.
Directories and unreadable/missing files are skipped (the latter noted, not
silent); over-budget files are reported as omitted.
- Order follows sorted_for_prompt, which is turn-agnostic, so the block is
byte-identical while the files are unchanged (KV cache hit); editing a file
cache-misses from its block onward — exactly the intended trade.
- Reachable via the CODEWHALE_CACHE_MAXIMAL env toggle (1/true/on/yes) or the
config flag; **off by default**, so existing behavior (path list only) is
unchanged.
Tests (7): flag-off keeps the path list only; flag-on materializes contents;
dirs not materialized; per-file cap truncates on a char boundary; total cap
omits extras; byte-stable across next_turn when files are unchanged; changes
when a file is edited. docs/CONFIGURATION.md documents the toggle and caps.
This is a first, self-contained slice. The compaction-deferral half of #528
(hold off summarization until a hard budget wall when cache-maximal is on) is
left as a follow-up, and I'm happy to align the toggle (env vs settings.toml)
and caps with your preferred current-main design.
Refs #528
Signed-off-by: findshan <[email protected]>
Issue #3638 asks to make the hard-loaded base prompt repurposable (e.g. for
long-form writing) without editing in-tree files or building a custom
embedder. The prompt-override hooks already exist for embedders
(set_base_prompt_override + the OnceLock cells), but there was no user-facing
source that feeds them.
Bridge those hooks to a config-directory file: at startup, if
`~/.codewhale/prompts/constitution.md` (under $CODEWHALE_HOME) exists and is
non-empty, install it via the existing set_base_prompt_override path;
otherwise fall back to the bundled constant. Loaded once before any engine
spawns (first-call-wins cells).
Scope is deliberately narrow and safe: only the byte-stable base prompt
segment is user-overridable. Mode deltas, approval policy, tool taxonomy,
Context Management, and the Compaction Relay stay owned by the runtime
assembly (see StaticPromptCtx), so an override cannot strip safety-relevant
guidance (sandbox/approvals).
- prompts.rs: pure, unit-tested resolver read_prompt_override_file +
load_config_dir_prompt_overrides / load_prompt_overrides_from_config_home.
- main.rs: wire the loader in once after CLI parse, before subcommand dispatch.
- docs/CONFIGURATION.md: document the override file, its scope, and that it
cannot remove safety layers.
- 3 unit tests (present/absent/empty-file). Empty/whitespace files are ignored
so a stray file can't blank the system prompt.
Refs #3638
Signed-off-by: findshan <[email protected]>
Pin actions/stale to the current v10 commit and replace release-era dry-run dates with generated cutoff variables so the triage docs stay usable over time.
Signed-off-by: Hunter B <[email protected]>
Harvested from PR #3640 by @pkeging.
Preserves the contributor's deployment and security guide while aligning commands with the files currently shipped in the repository. The harvest replaces stale helper-script references with the actual runtime and npm commands, and adds the approval-timeout variable to the bridge env template.
Register OpenModel across the shared provider registry, CLI model registry, TUI config, provider picker, and docs. Default the route to deepseek-v4-flash, use Anthropic Messages wire semantics, and keep Bearer auth so /v1/messages and /v1/models share one client.
This harvest also updates the config example to use deepseek-v4-flash instead of deepseek-chat, which the original PR notes is not available through OpenModel Messages.
Harvested from PR #3585 by @noaft.
Verification:
- cargo fmt
- CARGO_TARGET_DIR=/Volumes/VIXinSSD/codewhale-target CARGO_INCREMENTAL=0 cargo test -p codewhale-config --locked openmodel
- CARGO_TARGET_DIR=/Volumes/VIXinSSD/codewhale-target CARGO_INCREMENTAL=0 cargo test -p codewhale-tui --bin codewhale-tui --locked openmodel
- CARGO_TARGET_DIR=/Volumes/VIXinSSD/codewhale-target CARGO_INCREMENTAL=0 cargo test -p codewhale-agent --locked first_party_recent_provider_models_are_listed
Update the /links fallback docs URL from the stale codewhale.dev providers page to the current codewhale.net docs page, and add a Qianfan-specific docs link so the provider list does not fall through to the generic CodeWhale docs.
Harvested from PR #3621 by @noaft.
Verification:
- cargo fmt
- CARGO_TARGET_DIR=/Volumes/VIXinSSD/codewhale-target CARGO_INCREMENTAL=0 cargo test -p codewhale-tui --bin codewhale-tui --locked links
- CARGO_TARGET_DIR=/Volumes/VIXinSSD/codewhale-target CARGO_INCREMENTAL=0 cargo test -p codewhale-tui --bin codewhale-tui --locked provider_link_fallback_uses_current_codewhale_docs
- curl -I -L --max-time 15 https://codewhale.net/en/docs
- curl -I -L --max-time 15 https://cloud.baidu.com/doc/qianfan/index.html
Document the current ask-only permissions.toml behavior now that approval-card S saves rules for exec_shell, write_file, edit_file, and apply_patch.
Clarify that read_file is manual-only, YOLO remains unrestricted, and allow/deny records, globs, broad directory rules, and edit/delete UI remain out of scope.
Add a release asset verification gate that compares the local and remote tag SHAs, confirms a successful Release workflow run for that SHA, and reruns the npm wrapper asset verifier against the public GitHub assets.
Strengthen npm release:check so stale or incomplete GitHub Release assets fail before publish, while local/mirror asset checks still work through explicit release-base overrides.
Document npm auth/OTP retry commands, final registry verification, and the legacy deepseek-tui no-republish rule.
Closes#2642.
Closes#2643.
Extend the #2958 prompt-mode matrix with a v0.8.56 before/after comparison for Agent, Plan, and YOLO static prompt layers. The measured result is intentionally explicit: this audit records zero token savings versus v0.8.56 because the current shared Constitution is larger than the old base prompt.\n\nVerification:\n- cargo fmt --all -- --check\n- git diff --check\n- cargo test -p codewhale-tui --bin codewhale-tui --locked mode_prompts -- --nocapture\n\nCloses #2958
Document the current Agent, Plan, and YOLO prompt-mode contract with size snapshots and runtime enforcement anchors. Add prompt tests that keep mode files as compact deltas instead of duplicated constitution or approval-policy blocks.
Refs #2958
Add a terminal visual regression matrix that maps contrast, selector, sessions, config, sidebar, and transcript surfaces to deterministic tests.
Extend the palette audit with selected-row and light-palette contrast pairs, and add a /sessions render fixture for narrow and medium terminal widths with long CJK titles, border checks, truncation checks, and selected-row visibility.
Verification: cargo fmt --all -- --check; git diff --check; cargo test -p codewhale-tui --test palette_audit --locked; cargo test -p codewhale-tui --bin codewhale-tui --locked visual_matrix -- --nocapture; cargo test -p codewhale-tui --bin codewhale-tui --locked session_picker -- --nocapture.
Fixes#3487
Create the missing stale-policy labels in GitHub and make the workflow match the documented policy: needs-info bugs can age out unless they also carry a protected label such as release-blocker or security.\n\nDocument the maintainer dry-run queries and first manual cleanup pass so the automation is auditable before it closes anything.\n\nRefs #3089
Add a shared hotbar recommendation engine that preserves the default eight-slot order, filters disabled and required-argument actions, applies category limits for eligible entries, and can serialize recommendations as [[hotbar]] bindings with labels.
Wire the setup wizard to the shared recommendation set and mark recommended rows, then document the default hotbar slots in the keybinding guide.
Verification: cargo fmt --all -- --check; git diff --check; cargo test -p codewhale-tui --bin codewhale-tui --locked hotbar -- --nocapture; cargo check -p codewhale-tui --locked.
Fixes#3397
Keep Hotbar dispatch on Alt+1 through Alt+8 only, block dispatch while inline selectors or modal/onboarding focus owns numeric input, and document the focus matrix.\n\nRefs #3395
The Linux musl/glibc build artifact prose on lines 45 and 59 still
referenced v0.8.63 as the current release lane. Bump both to v0.8.65
so the install doc matches the shipped release.
Stage the codew binary in release builds, include it in platform archives and Windows installer inputs, and teach local release asset prep/checks about the shim. The Unix archive installer now installs via atomic replace so an existing executable is not overwritten in place.
Add Fleet launch-shape validation for WhaleFlow IR with a 100-agent default population cap, five recursive rings, and bounded loop/expand requirements. Update the Fleet setup surface and docs to frame Fleet as the durable sub-agent config layer while WhaleFlow owns agent-authored orchestration.