- find_exe(): fall back to known install dirs when PATH lookup fails
(C:\Program Files\PowerShell\7, System32\WindowsPowerShell\v1.0)
- Encoding prefix: use idiomatic [Console]::OutputEncoding for PowerShell
instead of cmd.exe chcp 65001 >NUL
- Execution logging: write exec via <ShellKind> entries to
SHELL_DISPATCHER_LOG when set
- System prompt: use ShellDispatcher detection instead of raw $SHELL
so model knows it has PowerShell and generates native cmdlets
- display_command(): strip PowerShell encoding prefix for display
- Add tests for find_exe PATH + known-dir fallback
Refs #1779
Add `codewhale update --check` so users can compare the installed version with
the latest release without downloading or replacing binaries.
Surface the same release check in `codewhale doctor`, and share release lookup,
mirror handling, timeout, and version comparison logic between update and doctor.
On Windows, stderr cannot be redirected to the log file (no dup2). Suppress verbose CLI logging once the alt-screen is active so eprintln! calls from crate::logging don't leak into the TUI buffer. Also restores verbose logging on all cleanup paths after leaving alt-screen.
clear_model_scoped_telemetry() now resets last_pinned_prefix_hash to
None so /cache stats does not show the previous model/provider cache
scope's fingerprint after a switch.
- Move pinned_hash extraction after check_and_update() so the reported
hash reflects the current prefix state, not the previous turn
- Skip non-cache-aware turns (cache_hit_tokens=None) in /cache stats
aggregation; infer miss tokens when cache_miss_tokens is None
- Clear last_pinned_prefix_hash to None when pinned_combined_hash is
empty (e.g. switching to a non-caching model/provider)
Surfaces the current pinned prefix fingerprint hash and stability
diagnostics via a new `/cache stats` subcommand, per the low-risk
0.8.x slice agreed on in #2264.
Changes:
- EngineEvent::PrefixCacheChange now carries pinned_combined_hash
from PrefixStabilityManager so the TUI layer can surface it
- App.last_pinned_prefix_hash stores the hash per-turn for /cache stats
- New /cache stats command renders three sections:
- Prefix Stability: pct, checks, changes, last-change description
- Prefix Fingerprint: full SHA-256 hash, short id, drift warning
- Cache Hit Rate: aggregated token totals + low-hit advisory
- format_tokens() helper for compact K/M token display
- 6 unit tests covering: no-data, stable, drift warning, hit-rate
summary, low-hit advisory, token formatting
Refs: #2264
Article VII Tier 5 currently lists four hard-coded path conventions
(AGENTS.md / CLAUDE.md / .codewhale/instructions.md / .deepseek/instructions.md)
as the canonical Local Law sources. Embedders that inject instructions via
`EngineConfig.instructions` (rather than placing files at one of those four
paths) get their files classified by path — and since their paths don't
match, the model defaults to treating their imperatives as Tier 7 Memory
(the lowest tier per Article VII), overridable by a single user sentence.
Adds an explicit clause to Tier 5: '...and any file configured via
`EngineConfig.instructions` (rendered as <instructions source=...> blocks
above). ...embedder-declared imperatives are Local Law, not Memory
preferences.'
Pairs naturally with #2311 (InstructionSource enum) but stands alone — this
is a doc/law clarification, not an API change.
Adds `local_law_tier_covers_engine_config_instructions` test pinning the
new clause's presence.
The environment block (`platform`, `shell`, `pwd`, `lang`) was inserted
above the volatile-content boundary as a workspace-static cache layer. The
original comment claimed 'workspace path is fixed for the run' → static-
cacheable — true for the terminal use case where one process owns one
workspace for its lifetime.
It is **not** true for embedders that swap workspaces between sessions:
- IDE/GUI integrations binding the engine to a per-tab workspace
- Multi-engine pools with one engine per session
- Anything sending Op::SyncSession with a new workspace
For these embedders, `pwd` drifts session-to-session, dragging the entire
static prefix (mode prompt, project context, skills, context management,
compact template) out of cache reuse on every session switch. That's a
~30KB+ cache miss for a few-byte path change.
Moves the environment block below the volatile-content boundary, alongside
the configured `instructions = [...]` block. Effect:
- Static prefix stays byte-stable across sessions even when workspace
changes (better KV prefix cache hit rate)
- Model still sees `pwd` / `platform` / `shell` (needed for exec_shell
and structured search tools), just in a slightly later position
- No behavior change for terminal callers (workspace fixed → block content
unchanged → still in same logical place, just below the boundary)
Added a comment explaining the per-session-workspace motivation.