Mechanical rustfmt of the runtime_prompt tests rewritten in PR #2874
(LeoAlex0). No logic change.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
tokio::task::spawn_blocking requires a running tokio runtime, which
breaks tests that call hook functions outside a tokio context. Since
hooks are fire-and-forget (no JoinHandle needed), std::thread::spawn
is the correct choice.
Replace platform-specific std::os::unix::io::FromRawFd with
Box<dyn std::io::Write + Send> return type. This compiles on
Windows, macOS, and Linux without unsafe code.
The closure now returns a boxed writer that is either:
- The cloned file handle (success case)
- A reopened file handle (clone failed)
- stderr (last resort, prevents panic)
1. Replace let-else with if-let-Some to avoid compilation error
- let-else with return would return from the entire function
- if-let-Some correctly assigns to tool_registry and continues
2. Preserve original goal_objective_for_prompt behavior
- Return None (not fallback) when objective exists but goal is inactive
- Use state.is_active().then() to match original semantics
1. Fix Mutex lock().unwrap() in MCP server (mcp_server.rs:384,434)
- Use unwrap_or_else(|e| e.into_inner()) to recover from poisoned locks
- Previously, a single panic while holding the lock would cascade to all threads
2. Fix std::thread::spawn in async code (hooks.rs:1055)
- Replace std::thread::spawn with tokio::task::spawn_blocking
- Respects tokio's thread pool limits instead of creating unbounded OS threads
- Fire-and-forget hook execution now properly managed by tokio runtime
3. Fix dropped JoinHandle in SSE loop (mcp.rs:647)
- Store the JoinHandle in SseTransport struct
- Enables detection of SSE loop termination
- Prevents silent connection loss without structured error reporting
4. Fix std::sync::Mutex poison handling in cost_status (cost_status.rs:28-58)
- Use unwrap_or_else(|e| e.into_inner()) to recover from poisoned locks
- Previously, a panic while holding the lock silently lost all subsequent cost data
- Cost tracking now survives mutex poisoning
5. Fix .expect() in tracing writer (runtime_log.rs:162)
- Replace expect() with fallback chain: try_clone -> reopen file -> stderr
- Prevents panicking inside tracing subscriber on fd exhaustion
- Previously, EMFILE during logging would crash the application
1. Fix deny rule prefix matching without word boundary (execpolicy/lib.rs:351-353)
- Deny rule 'rm' now blocks 'rm -rf /' but NOT 'rmdir' or 'rmview'
- Previously used bare starts_with which matched any command starting with 'rm'
- Add word-boundary check: command must equal rule or start with rule+space
2. Fix fallback prefix match clarity (execpolicy/bash_arity.rs:362-374)
- Improve comment to clarify word-boundary matching behavior
- The trailing space in starts_with already provides word boundary
3. Fix hardcoded AskForApproval::OnRequest in HTTP API (app-server/lib.rs:283)
- Read approval_policy from config instead of hardcoding OnRequest
- Users with 'auto'/'yolo' policy now get UnlessTrusted for API calls
- Previously ignored user's configured security posture
4. Fix fuzzy indentation search destroying preceding text (tools/file.rs:714-735)
- When match starts mid-line after whitespace stripping, use exact position
- Previously always expanded to line start, destroying preceding content
- Now only expands to line start when match is at a line boundary
5. Fix potential underflow in apply_hunk start index (tools/apply_patch.rs:1110-1115)
- Use checked_add_signed to safely handle negative cumulative_offset
- Prevents isize overflow on adversarial patch input
- Clamp to lines.len() instead of relying on .max(0) cast
1. Fix swallowed persist_config errors (app-server/lib.rs:882,896)
- Log errors when config persistence fails after set/unset
- Users previously got success response even when disk write failed
2. Fix swallowed job store load error (core/lib.rs:751)
- Add warning log when job store fails to load at startup
- Previously silently started with empty job list on corruption
3. Fix silent config parse failures (config/lib.rs:1590)
- Log warning when project config TOML is malformed
- Previously returned None indistinguishable from 'no config file'
4. Fix MCP connect_all errors swallowed (mcp.rs:2151,2189)
- Log warnings for each server that fails to connect
- Previously returned incomplete resource list with no indication
5. Fix error context stripped in engine status (core/engine.rs:2223)
- Use {err:#} format to include full error chain
- Was inconsistent with line 2234 which already used {err:#}
6. Fix tool audit log failures silently dropped (tool_execution.rs:122-136)
- Log each failure: serialization, directory creation, file open, write
- Previously silently dropped all errors for security audit trail
7. Fix Err(_) arms discarding error info (runtime_log.rs:179, runtime_threads.rs:828)
- Log stderr redirect failures on Windows
- Log poisoned mutex in pending_approvals
8. Fix env var parsing errors silently ignored (config/lib.rs:2519-2530)
- Warn when DEEPSEEK_TELEMETRY, DEEPSEEK_YOLO, DEEPSEEK_HTTP_HEADERS
have invalid values instead of silently treating as unset
9. Fix MCP config reload errors swallowed (mcp.rs:2011)
- Log config reload errors instead of complete silence
10. Fix .expect() on sub-agent runtime (core/engine.rs:1715)
- Gracefully fall back to basic tool set when API client missing
- Previously panicked if subagents enabled but no client configured
11. Fix .expect() on goal objective (core/engine.rs:2543)
- Use safe if-let pattern instead of check+expect
- Prevents panic if refactoring changes control flow
- Add runtime_policy_reference_is_included_in_full_prompt test to verify
that render_runtime_policy_reference() output lands in the composed
system prompt. Guards against silent breakage if the push_str() call
is accidentally removed (all existing tests would still pass).
- Strengthen change_mode_op_updates_current_mode_and_emits_status:
destructure SessionUpdated to assert that session messages do NOT
contain <runtime_prompt> tags after mode change — verifying the core
invariant that Op::ChangeMode does not write session history.
- Extend current_mode_field_assignment_takes_effect_synchronously:
now also verifies that messages_with_turn_metadata() produces the
correct runtime tag (mode="yolo" approval="auto") after a mode
switch, covering the tag-generation mechanism end-to-end.
- Fix outdated comments in composed_prompt_no_longer_inlines_tool_taxonomy
and plan_prompt_taxonomy_omits_run_tests: replace stale references to
deleted <mode_prompt> metadata with accurate descriptions of the
## Runtime Policy Reference section.
The test cache_inspect_displays_tool_result_budget_metadata relied on a
writable $HOME/.codewhale/tool_outputs/ for tool-result wire-dedup
persistence. nix build sandboxes have a read-only home tree, so the
first tool-result SHA spillover write failed, the dedup hash table was
never populated, and the second identical tool result was not marked
deduplicated — causing the expect("repeat tool-result sighting should
report dedup metadata") assertion to fail.
Set TEST_SPILLOVER_ROOT to a tempdir inside the test (matching the
with_tool_result_sha_spillover_root pattern in chat.rs), so the
wire-dedup path works in any environment without depending on $HOME.
- 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.
Add durable [[hotbar]] config bindings for slots 1-8, including default
bindings when no hotbar config is present.
Validate bindings without panicking: skip out-of-range slots, use the last
duplicate slot, and preserve unknown actions so future UI layers can show
disabled placeholders.