From f47284008e81aac630e4483345e84cea3cd62371 Mon Sep 17 00:00:00 2001 From: serrrfirat Date: Tue, 21 Apr 2026 23:40:41 +0300 Subject: [PATCH 1/3] fix(engine): enforce tool use for stop/pause/cancel commands (#2808) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The LLM was narrating about calling mission_pause/mission_list instead of actually executing them because neither the tool-intent nudge nor the execution obligation recognized stop/pause/cancel as action commands. - Add stop/pause/cancel/halt/disable to signals_tool_intent ACTION_VERBS so the nudge fires when the LLM says "I'll pause the mission" - Add stop/pause/cancel phrases to signals_execution_intent EXEC_PHRASES so the obligation system forces tool calls for "stop it", "pause the X" - Add bare imperative detection (startswith) for "stop", "stop pinging", "pause", "cancel" — avoids false positives like "I can't stop" - Add 5 regression tests covering true positives and false negatives Co-Authored-By: Claude Opus 4.6 (1M context) --- .../ironclaw_engine/orchestrator/default.py | 22 +++++- .../src/executor/orchestrator.rs | 75 +++++++++++++++++++ 2 files changed, 96 insertions(+), 1 deletion(-) diff --git a/crates/ironclaw_engine/orchestrator/default.py b/crates/ironclaw_engine/orchestrator/default.py index 6cae692fbaa..10ee656ab42 100644 --- a/crates/ironclaw_engine/orchestrator/default.py +++ b/crates/ironclaw_engine/orchestrator/default.py @@ -126,6 +126,7 @@ def signals_tool_intent(text): "read the", "write the", "create", "run the", "execute", "query", "retrieve", "add it", "add the", "add this", "add that", "update the", "delete", "remove the", "look into", + "stop", "pause", "cancel", "halt", "disable", ] for prefix in PREFIXES: @@ -161,10 +162,29 @@ def signals_execution_intent(text): "ship it", "deploy it", "deploy that", "deploy this", "deploy the ", "send it", "send that", "send the ", "fetch it", "fetch that", "fetch the ", + "stop it", "stop that", "stop this", "stop the ", + "pause it", "pause that", "pause this", "pause the ", + "cancel it", "cancel that", "cancel this", "cancel the ", "please run ", "please execute ", "please fetch ", "please send ", "please deploy ", + "please stop ", "please pause ", "please cancel ", ] - return any(phrase in lower for phrase in EXEC_PHRASES) + if any(phrase in lower for phrase in EXEC_PHRASES): + return True + + # Bare imperative commands at the start of the message. + # "stop pinging", "stop", "pause", "cancel" are unambiguous commands + # that don't match the "verb + pronoun/article" pattern above. + # Checking startswith avoids false positives like "I can't stop". + trimmed = lower.strip() + IMPERATIVE_STARTS = ["stop ", "pause ", "cancel ", "halt "] + BARE_COMMANDS = ["stop", "pause", "cancel", "halt"] + if trimmed in BARE_COMMANDS: + return True + if any(trimmed.startswith(s) for s in IMPERATIVE_STARTS): + return True + + return False def format_output(result, max_chars=8000): diff --git a/crates/ironclaw_engine/src/executor/orchestrator.rs b/crates/ironclaw_engine/src/executor/orchestrator.rs index 3c173634491..1b1eeb21074 100644 --- a/crates/ironclaw_engine/src/executor/orchestrator.rs +++ b/crates/ironclaw_engine/src/executor/orchestrator.rs @@ -3158,6 +3158,81 @@ mod tests { )); } + // ── Stop / pause / cancel intent (mission lifecycle) ───────── + + #[test] + fn signals_tool_intent_stop_pause_cancel() { + assert!(eval_python_bool( + r#"signals_tool_intent("I'll stop the mission now.")"# + )); + assert!(eval_python_bool( + r#"signals_tool_intent("Let me pause the ticker.")"# + )); + assert!(eval_python_bool( + r#"signals_tool_intent("I'll cancel the monitoring.")"# + )); + assert!(eval_python_bool( + r#"signals_tool_intent("I'm going to halt the recurring task.")"# + )); + assert!(eval_python_bool( + r#"signals_tool_intent("I will disable the mission.")"# + )); + } + + #[test] + fn signals_tool_intent_no_false_positive_stop_discussion() { + // "let me explain" is in EXCLUSIONS — blocks the entire text + assert!(!eval_python_bool( + r#"signals_tool_intent("Let me explain how to stop the mission.")"# + )); + // Past tense should not trigger + assert!(!eval_python_bool( + r#"signals_tool_intent("I already stopped the mission.")"# + )); + } + + // ── Execution intent: stop / pause / cancel ──────────────── + + #[test] + fn signals_execution_intent_stop_pause_cancel() { + assert!(eval_python_bool(r#"signals_execution_intent("stop it")"#)); + assert!(eval_python_bool( + r#"signals_execution_intent("pause the mission")"# + )); + assert!(eval_python_bool( + r#"signals_execution_intent("cancel that")"# + )); + assert!(eval_python_bool( + r#"signals_execution_intent("please stop the ticker")"# + )); + assert!(eval_python_bool( + r#"signals_execution_intent("please pause everything")"# + )); + } + + #[test] + fn signals_execution_intent_bare_stop() { + // Bare imperative commands — the exact user messages from #2808 + assert!(eval_python_bool(r#"signals_execution_intent("stop")"#)); + assert!(eval_python_bool( + r#"signals_execution_intent("stop pinging")"# + )); + assert!(eval_python_bool(r#"signals_execution_intent("pause")"#)); + assert!(eval_python_bool(r#"signals_execution_intent("cancel")"#)); + assert!(eval_python_bool(r#"signals_execution_intent("halt")"#)); + } + + #[test] + fn signals_execution_intent_no_false_positive_stop_in_sentence() { + // "stop" mid-sentence should NOT trigger — only at the start + assert!(!eval_python_bool( + r#"signals_execution_intent("I can't stop thinking about it")"# + )); + assert!(!eval_python_bool( + r#"signals_execution_intent("how do I stop a mission?")"# + )); + } + // ── Skill activation: smart-quote / autocorrect resilience ─── // // Regression for the ceo-setup non-activation report. iOS / macOS / most From 4304d2fcb02b2a0f6b567bad123de61ab3b2c889 Mon Sep 17 00:00:00 2001 From: serrrfirat Date: Wed, 22 Apr 2026 11:39:34 +0300 Subject: [PATCH 2/3] fix: address review findings (iteration 1) - Add missing "please halt " to EXEC_PHRASES for consistency with please stop/pause/cancel - Strip trailing punctuation from bare commands so "Stop." and "cancel!" are detected - Add 2 regression tests covering both fixes Co-Authored-By: Claude Opus 4.6 (1M context) --- crates/ironclaw_engine/orchestrator/default.py | 5 +++-- .../src/executor/orchestrator.rs | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/crates/ironclaw_engine/orchestrator/default.py b/crates/ironclaw_engine/orchestrator/default.py index 10ee656ab42..588c1fffc08 100644 --- a/crates/ironclaw_engine/orchestrator/default.py +++ b/crates/ironclaw_engine/orchestrator/default.py @@ -167,7 +167,7 @@ def signals_execution_intent(text): "cancel it", "cancel that", "cancel this", "cancel the ", "please run ", "please execute ", "please fetch ", "please send ", "please deploy ", - "please stop ", "please pause ", "please cancel ", + "please stop ", "please pause ", "please cancel ", "please halt ", ] if any(phrase in lower for phrase in EXEC_PHRASES): return True @@ -176,7 +176,8 @@ def signals_execution_intent(text): # "stop pinging", "stop", "pause", "cancel" are unambiguous commands # that don't match the "verb + pronoun/article" pattern above. # Checking startswith avoids false positives like "I can't stop". - trimmed = lower.strip() + # Strip trailing punctuation so "Stop." and "cancel!" still match. + trimmed = lower.strip().rstrip(".,!?;:") IMPERATIVE_STARTS = ["stop ", "pause ", "cancel ", "halt "] BARE_COMMANDS = ["stop", "pause", "cancel", "halt"] if trimmed in BARE_COMMANDS: diff --git a/crates/ironclaw_engine/src/executor/orchestrator.rs b/crates/ironclaw_engine/src/executor/orchestrator.rs index 1b1eeb21074..fa232983830 100644 --- a/crates/ironclaw_engine/src/executor/orchestrator.rs +++ b/crates/ironclaw_engine/src/executor/orchestrator.rs @@ -3233,6 +3233,24 @@ mod tests { )); } + #[test] + fn signals_execution_intent_please_halt() { + // "please halt" must be detected like "please stop/pause/cancel" + assert!(eval_python_bool( + r#"signals_execution_intent("please halt the mission")"# + )); + } + + #[test] + fn signals_execution_intent_bare_stop_with_punctuation() { + // Bare commands with trailing punctuation must still match + assert!(eval_python_bool(r#"signals_execution_intent("stop.")"#)); + assert!(eval_python_bool(r#"signals_execution_intent("cancel!")"#)); + assert!(eval_python_bool( + r#"signals_execution_intent("stop pinging.")"# + )); + } + // ── Skill activation: smart-quote / autocorrect resilience ─── // // Regression for the ceo-setup non-activation report. iOS / macOS / most From 9b10521e699d3eaf77e86a740496ff6f03800dc1 Mon Sep 17 00:00:00 2001 From: serrrfirat Date: Wed, 22 Apr 2026 11:51:35 +0300 Subject: [PATCH 3/3] =?UTF-8?q?fix(engine):=20address=20gemini-code-assist?= =?UTF-8?q?=20review=20=E2=80=94=20halt/disable=20consistency=20(#2814)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add "halt it/that/this/the" and "disable it/that/this/the" to EXEC_PHRASES for consistency with signals_tool_intent - Add "please disable " to polite execution phrases - Add "disable" to BARE_COMMANDS and IMPERATIVE_STARTS - Add regression test for halt/disable execution intent phrases Co-Authored-By: Claude Opus 4.6 (1M context) --- .../ironclaw_engine/orchestrator/default.py | 9 ++++++--- .../src/executor/orchestrator.rs | 19 +++++++++++++++++-- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/crates/ironclaw_engine/orchestrator/default.py b/crates/ironclaw_engine/orchestrator/default.py index 588c1fffc08..dad91ac755e 100644 --- a/crates/ironclaw_engine/orchestrator/default.py +++ b/crates/ironclaw_engine/orchestrator/default.py @@ -165,9 +165,12 @@ def signals_execution_intent(text): "stop it", "stop that", "stop this", "stop the ", "pause it", "pause that", "pause this", "pause the ", "cancel it", "cancel that", "cancel this", "cancel the ", + "halt it", "halt that", "halt this", "halt the ", + "disable it", "disable that", "disable this", "disable the ", "please run ", "please execute ", "please fetch ", "please send ", "please deploy ", - "please stop ", "please pause ", "please cancel ", "please halt ", + "please stop ", "please pause ", "please cancel ", + "please halt ", "please disable ", ] if any(phrase in lower for phrase in EXEC_PHRASES): return True @@ -178,8 +181,8 @@ def signals_execution_intent(text): # Checking startswith avoids false positives like "I can't stop". # Strip trailing punctuation so "Stop." and "cancel!" still match. trimmed = lower.strip().rstrip(".,!?;:") - IMPERATIVE_STARTS = ["stop ", "pause ", "cancel ", "halt "] - BARE_COMMANDS = ["stop", "pause", "cancel", "halt"] + IMPERATIVE_STARTS = ["stop ", "pause ", "cancel ", "halt ", "disable "] + BARE_COMMANDS = ["stop", "pause", "cancel", "halt", "disable"] if trimmed in BARE_COMMANDS: return True if any(trimmed.startswith(s) for s in IMPERATIVE_STARTS): diff --git a/crates/ironclaw_engine/src/executor/orchestrator.rs b/crates/ironclaw_engine/src/executor/orchestrator.rs index fa232983830..a447f35d3c1 100644 --- a/crates/ironclaw_engine/src/executor/orchestrator.rs +++ b/crates/ironclaw_engine/src/executor/orchestrator.rs @@ -3234,11 +3234,26 @@ mod tests { } #[test] - fn signals_execution_intent_please_halt() { - // "please halt" must be detected like "please stop/pause/cancel" + fn signals_execution_intent_halt_disable_phrases() { + // "halt/disable" pronoun+article phrases and "please halt/disable" + assert!(eval_python_bool(r#"signals_execution_intent("halt that")"#)); + assert!(eval_python_bool( + r#"signals_execution_intent("halt the mission")"# + )); + assert!(eval_python_bool( + r#"signals_execution_intent("disable it")"# + )); + assert!(eval_python_bool( + r#"signals_execution_intent("disable the ticker")"# + )); assert!(eval_python_bool( r#"signals_execution_intent("please halt the mission")"# )); + assert!(eval_python_bool( + r#"signals_execution_intent("please disable the routine")"# + )); + // Bare "disable" command + assert!(eval_python_bool(r#"signals_execution_intent("disable")"#)); } #[test]