fix(engine): harden recovery regex compilation against panics #56
No reviewers
Labels
No labels
prio_critical
prio_low
type_bug
type_contact
type_issue
type_lead
type_question
type_story
type_task
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
lhumina_code/hero_shrimp!56
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "development_recovery_panic_hygiene"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
P1 panic-hygiene fix for the recovery hot path. The only remaining production panic surface in
tool_call_recovery.rswas threeRegex::new(...).expect(...)calls on constant regex literals. Each is now cached in aOnceLock<Option<Regex>>and degrades gracefully on compile failure — atracing::warn!plus the function's documented neutral fallback. Public signatures unchanged; callers compile without modification.Related Issue
Closes #42
Changes
crates/hero_shrimp_engine/src/agent_core/agent/tool_call_recovery.rsstrip_bracket_tool_calls: regex cached instatic BRACKET_RE: OnceLock<Option<Regex>>. On compile failure:tracing::warn!(target: "tool_call_recovery", ...)and return(content.to_string(), Vec::new())— same as the existing "no markers found" branch.normalize_arrow_syntax: both regexes cached in their ownOnceLock<Option<Regex>>. On compile failure of either:tracing::warn!and returnNone— same as the existing "shape didn't match" branch.crates/hero_shrimp_engine/src/agent_core/agent/force_write.rs— audited, no production changes required. Allunwrap()calls (lines 210–451) are inside#[cfg(test)] mod tests(boundary at line 198).Test Results
cargo test -p hero_shrimp_engine --lib tool_call_recovery— 40 passed, 0 failed, including the proptest fuzz suite andrecovery_never_panics_on_adversarial_input.cargo test -p hero_shrimp_engine --lib force_write— 14 passed, 0 failed.cargo test -p hero_shrimp_engine(full crate) — 1639 passed, 9 failed. The 9 failures are pre-existing ondevelopmentand unrelated to this change — they live inverification::runner::*,tools::external_cmd::*,tools::tool_catalog::verify::e2e_datetime_server::*, andtests::autonomy_*, all of which spawn shell processes or open sockets and fail in the local sandboxed environment regardless of branch. Verified by re-running ondevelopment: identical 1639/9 split, identical test names.cargo build -p hero_shrimp_engine— clean, no new warnings.Notes
The regex panic path is unreachable in practice (constant literals known to compile), so this is defense-in-depth. It formalises the contract already asserted by the adversarial test at
tool_call_recovery.rslines 696-707 (which wraps recovery instd::panic::catch_unwind): no input or environmental condition may panic the recovery routine.unwrap()/expect()in recovery hot paths (force_write, tool_call_recovery) can panic #425f84e049dcf140a2ca8a