- Rename mode_change_op_updates_current_mode_and_emits_session_updated
to current_mode_field_assignment_takes_effect_synchronously.
- The test directly mutates engine.current_mode, not through Op::ChangeMode.
The dispatch path is separately covered by
change_mode_op_updates_current_mode_and_emits_status.
- Inline mode_prompt_marker_value and approval_prompt_marker_value into
runtime_prompt_text (each called exactly once).
- Remove default_approval_mode_for_mode — zero callers.
- Replace the 2 remaining test callers with render_core_tool_taxonomy_body
(neither test depends on the ## heading — they check content only).
- Delete render_core_tool_taxonomy_block — zero production callers after
the previous refactor.
- Add render_core_tool_taxonomy_body(mode) that generates the tool
taxonomy text without the ## Core Tool Taxonomy heading.
- Refactor render_core_tool_taxonomy_block to use the body function
internally (DRY).
- Delete taxonomy_body() — a downstream strip_prefix hack that
worked around the source format instead of fixing it.
- Also removes the now-unnecessary debug_assert! (over-defensive,
since the two functions are co-located in the same file).
- Add proper blank lines (\n\n) before mode headings in
render_runtime_policy_reference (CommonMark/GFM compliance).
- Demote subheadings in agent.md from ##### to ###### so they
nest correctly under the demoted main heading.
- Add debug_assert! in taxonomy_body() to loudly fail when
render_core_tool_taxonomy_block format changes, preventing
silent heading-hierarchy breakage.
- Add render_runtime_policy_reference() in prompts.rs containing all
mode and approval policy descriptions in the frozen system-prompt
prefix (sent once per session, cache-hit thereafter).
- Simplify runtime_prompt_text() from ~500-token XML block to a ~16-token
self-closing tag (<runtime_prompt visibility="internal" mode="..." approval="..."/>).
- Fix markdown heading hierarchy in all prompts/modes/*.md and
prompts/approvals/*.md (## → #####) to nest correctly under ####.
- Remove now-unused legacy functions: mode_prompt(),
approval_prompt_for_mode(), mode_change_runtime_message().
- Simplify Op::ChangeMode: no longer persists a mode_change event
(next turn tag carries the current mode).
- Update and rename affected tests.
Builds on #2801. Reduces per-request runtime prompt overhead by 97%
(~471 tokens saved per API call). System prompt grows by ~1325 tokens
in the frozen prefix (one-time miss cost); break-even at 3 API calls.
On Windows, AltGr is delivered as Ctrl+Alt by crossterm. European keyboard
layouts (French AZERTY, German QWERTZ, etc.) use AltGr to type characters
like @ (AltGr+0), # (AltGr+3), etc. The sidebar-focus shortcuts for
Alt+@/Alt+!/Alt+#/Alt+$/Alt+%) were matching on "contains ALT" alone,
swallowing these AltGr-typed characters instead of inserting them into
the composer.
Exclude the Ctrl modifier from these sidebar-focus shortcut guards so
AltGr-typed glyphs fall through to the catch-all and
are inserted as text. This is consistent with the has_ctrl_or_alt /
is_altgr philosophy in key_hint.rs, which already treats Ctrl+Alt as
AltGr to preserve European keyboard input.
Closes#2863
Six fixes for the bot review comments landed on PR #2864 head
649d3990. See phase2-playbook.md §7 for the triage rationale.
* persistence.rs: oversized state file now surfaces an InvalidData
error instead of silently returning a default. The old behaviour
would let the next save overwrite the oversized file and destroy
the user's data. Test updated to expect the error.
* persistence.rs: PersistedDelegation gains a `status` field so
in-flight `InProgress` delegations aren't silently demoted to
`Pending` on restart. The snapshot now writes the live status
and restore_from_snapshot honours it. Adds a regression test.
* mention.rs: resolve_tab_mention no longer sorts its input — tab
mentions (@Tab2) must map to the visual order in the tab bar,
not to an arbitrary ID sort. Test updated.
* manager.rs: `pending_tasks` renamed to `completed_delegations`
because the getter returns completed DelegationResults, not
in-flight tasks. Docstring points to the in-flight getter
`pending_delegations` to avoid the same confusion recurring.
* manager.rs: delegate_task and start_meeting now validate that
the from/to tab IDs (or all participant IDs) currently exist
in the manager. Returns `None` on any unknown ID, preventing
orphaned tasks / meetings with stale tab references. Two new
regression tests cover both methods.
Local CI matrix (Windows runner, flags matching ci.yml):
- cargo fmt --all -- --check: exit 0
- cargo clippy --workspace --all-features --locked -- -D warnings: exit 0
- cargo test --workspace --all-features --locked: 4282 pass, 6 fail
(the 6 failures are pre-existing on the baseline; not caused
by this PR)
- git diff --exit-code -- Cargo.lock: exit 0
The three deferred threads (#1 close_tab cleanup, #5 cross_tab_links
snapshot, #8 TabGroup::new collision risk) are explicitly out of
scope here; they belong to the follow-up collab/UI PR per the
narrow-harvest promise to Hmbown.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Sister PR to #2753, scoped to the narrow tab-core/persistence slice
Hmbown asked for in the v0.9 stewardship review. Adds the `tab`
module under `crates/tui/src/tui/` and a one-line module registration
in `tui/mod.rs`. Nothing else in the host changes here — the
switcher / picker / meeting UI pass and the host wiring
(`App::tab_manager`, keyboard shortcuts, mouse menu, tab-bar layout
in `ui.rs`) live on #2753 and land in a follow-up PR.
Scope:
* `tab::TabManager` with monotonic `next_tab_id`, max 9 tabs by
default, snapshot/restore round-trip, group assignment,
cross-tab event/links, and persistence integration
* `tab::delegator::TaskDelegator` — bounded pending queue with
`MAX_COMPLETED_RESULTS` auto-prune; `take_pending_for_tab` marks
InProgress in place and returns a clone so subsequent
`start_task` / `complete` / `fail_task` / `cancel_task` can still
find the task (the previous `swap_remove` would have dropped it
on the first call)
* `tab::meeting::MeetingManager` — participants, messages by
type (Regular / Question / Answer / Proposal / Agreement /
Objection / Summary), decisions
* `tab::cross_tab` — `CrossTabEvent` (TaskDelegation / ReviewRequest
/ MeetingInvite / ContextSync / ResultReturn) and `SharedContext`
* `tab::group` — `TabGroup` / `TabGroupManager` /
`GroupColor` (Red/Orange/Yellow/Green/Cyan/Blue/Magenta/Gray)
* `tab::mention` — `@Tab<N>`, `@N`, `@tab<n>` (case-insensitive)
parser, with `resolve_tab_mention` for 1-indexed tab lookups
* `tab::persistence` — JSON file in the user's data dir,
`PersistedTabState` / `PersistedTab` / `PersistedDelegation` /
`PersistedGroup` with schema-version header, atomic save,
bounded file size, corruption-tolerant load
* `tab::benches` and `tab::key_e2e` regression suites (roundtrip,
save/load, end-to-end save→load with keymap)
Lint posture:
* `#![allow(dead_code, unused_imports)]` on `tab/mod.rs` because
the collab/UI pass is not on this branch; the public surface is
intentionally exposed for the follow-up wiring in #2753
* One pre-existing `tools/shell.rs` fix piggy-backed: drop the
redundant `as *mut c_void` cast on `child.as_raw_handle()` (the
return type is already `*mut c_void`). Pre-existing on
`codex/v0.9.0-stewardship`; promoted to `clippy::unnecessary_cast`
by rust 1.95
Local CI matrix on this branch (Windows runner, same flags as
`.github/workflows/ci.yml`):
* `cargo fmt --all -- --check` — pass
* `cargo clippy --workspace --all-features --locked -- -D warnings`
— pass, 0 errors
* `cargo test --bin codewhale-tui tab::` — 63/63 pass
* `git diff --exit-code -- Cargo.lock` — clean
GitHub Actions will run on the standard fork-PR approval gate; the
`on.pull_request` branch filter on this repo matches
`codex/v0.9.0-stewardship` so the same matrix will run on
ubuntu-latest, macos-latest, and windows-latest.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add recorded mock-trace replay coverage for workflows/rlm_cache_change.star and prove missing dogfood records produce ReplayDiverged instead of live fallback.\n\nVerification:\n- cargo test -p codewhale-whaleflow rlm_cache_change --locked\n- cargo fmt --all --check\n- git diff --check\n- cmp -s CHANGELOG.md crates/tui/CHANGELOG.md\n- ./scripts/release/check-versions.sh\n- ./scripts/release/check-ohos-deps.sh