fix(13-08): system prompt — call tools directly, never text-ask for confirmation

On-device UAT hit an infinite politeness loop: 'every write requires a human
confirmation you cannot bypass' read to the model as 'collect consent in text
first', so it never called restart_app, the confirm gate never engaged, and
each stateless turn (history is 13-10) dropped the user's 'confirmed' into a
void. The preamble now states the intended contract: the node presents the
trusted dialog the moment the tool is called; a text pre-ask stalls the action
and trains rubber-stamping.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
archipelago
2026-08-05 13:34:23 -04:00
co-authored by Claude Fable 5
parent 830b77af18
commit 44f552cc3d
+8 -4
View File
@@ -209,10 +209,14 @@ const SYSTEM_PROMPT_PREAMBLE: &str = "You are the Archipelago node's operator-co
Only use the tools explicitly listed below for this turn — never invent a tool name or call one \
that is not listed here, even if it sounds like something this node could plausibly do. Every \
write requires a human confirmation you cannot bypass, skip, or pre-approve on the user's \
behalf. If the user asks for something outside the tools listed below (including anything \
touching keys, seeds, wallet spends, federation trust, or a factory reset), refuse plainly and, \
if there is a real path in neode-ui's Settings screen for it, name that path instead of \
fabricating a tool call.";
behalf; the node itself presents that confirmation to the operator in a trusted dialog the \
moment you call the tool. So when the user asks for something a listed tool does, call the tool \
directly — never ask for permission or confirmation in your text first. A text pre-ask is worse \
than redundant: it stalls the action behind a reply you cannot act on, and it trains the \
operator to rubber-stamp. If the user asks for something outside the tools listed below \
(including anything touching keys, seeds, wallet spends, federation trust, or a factory reset), \
refuse plainly and, if there is a real path in neode-ui's Settings screen for it, name that path \
instead of fabricating a tool call.";
pub fn build_system_prompt(visible_tools: &[tools::ToolDef]) -> String {
let mut prompt = String::from(SYSTEM_PROMPT_PREAMBLE);