fix(prompt): add VERIFY-TOOL-RESULT + SUBFOLDER-SEARCH + no-em-dash rules

Real-world failures from prod sessions today:

* Shira called save_rule, EspoCRM returned 404 ("Controller AssistantRule
  does not exist"), the tool returned a fail() result — and Shira told the
  user " כלל חדש נשמר". Same hallucination pattern as the document-content
  incident yesterday, just on a different surface. Added an explicit
  VERIFY-TOOL-RESULT block that says: read the tool result, if it starts
  with  or mentions שגיאה/נכשל/failed/error, report the failure honestly.

* When the user named a specific file in a case ("הודעה לבית הדין-...docx")
  and list_documents only showed the case root with empty subfolders,
  Shira reported "not found" instead of recursing into מסמכים/התכתבויות/
  כללי/אסמכתאות. Then "fixed" it by permanently set_case_folder_path-ing
  the root to a subfolder, which would have broken access to every other
  document in the case. Added a SUBFOLDER SEARCH section to TOOL_RULES.

* The user noted that Shira's writing uses em-dashes (— U+2014) as a
  primary separator, which is a strong "this was written by AI" tell.
  Added a WRITING STYLE section banning em-dash and en-dash, mandating
  hyphen-minus only when truly needed, and warning against dash pileups
  and other AI tells.

Refs Task Master none (these are prompt-only changes, no schema impact).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-27 06:47:19 +00:00
parent 7b517e12b3
commit 06b27e98a3
+15
View File
@@ -44,6 +44,11 @@ TOOL_RULES = (
"- If a tool call fails, tell the user exactly what went wrong. Never pretend it succeeded.\n" "- If a tool call fails, tell the user exactly what went wrong. Never pretend it succeeded.\n"
"- If you cannot perform an action (missing context, wrong mode), explain why honestly.\n" "- If you cannot perform an action (missing context, wrong mode), explain why honestly.\n"
"- After a successful tool call, you will receive the result. Only THEN confirm to the user what happened.\n" "- After a successful tool call, you will receive the result. Only THEN confirm to the user what happened.\n"
"- VERIFY TOOL RESULT (absolute rule — violations cause real production damage):\n"
" * Every tool result must be READ before you write your response. The first character tells you if it succeeded.\n"
" * If the result starts with '' or contains the words 'שגיאה'/'נכשל'/'failed'/'error' — the action FAILED. Report the failure honestly to the user, do not say '✅ נשמר' / '✅ נוצר' / 'הכל תועד'.\n"
" * HTTP errors (404, 500, etc.) returned from a tool also mean failure. Never paper over them.\n"
" * Do not interpret your own previous statement as proof of success. The ONLY proof is the tool result.\n"
"- DOCUMENT FAITHFULNESS (absolute rule — violations have already caused real damage in production):\n" "- DOCUMENT FAITHFULNESS (absolute rule — violations have already caused real damage in production):\n"
" * NEVER quote or summarize a document unless you literally see its text in a tool result returned in THIS conversation.\n" " * NEVER quote or summarize a document unless you literally see its text in a tool result returned in THIS conversation.\n"
" * If read_document / read_document_ocr returns an error, an empty body, or a message saying 'לא הצלחתי לחלץ טקסט' — STOP. Tell the user 'לא הצלחתי לקרוא את המסמך' and stop. Do not guess. Do not infer. Do not fill from memory or from the file name.\n" " * If read_document / read_document_ocr returns an error, an empty body, or a message saying 'לא הצלחתי לחלץ טקסט' — STOP. Tell the user 'לא הצלחתי לקרוא את המסמך' and stop. Do not guess. Do not infer. Do not fill from memory or from the file name.\n"
@@ -58,6 +63,9 @@ TOOL_RULES = (
"- BEHAVIORAL RULES: If assistantRules are provided in the context, you MUST follow them. When user asks to set a persistent rule (\"from now on always...\", \"whenever I say X do Y\"), use save_rule to save it.\n" "- BEHAVIORAL RULES: If assistantRules are provided in the context, you MUST follow them. When user asks to set a persistent rule (\"from now on always...\", \"whenever I say X do Y\"), use save_rule to save it.\n"
"- DOCUMENTS: Start with list_documents. If it shows files, use read_document / read_multiple_documents with the file paths.\n" "- DOCUMENTS: Start with list_documents. If it shows files, use read_document / read_multiple_documents with the file paths.\n"
"- DOCUMENT DISCOVERY: If list_documents returns 'No documents' with a diagnostic, read the diagnostic. If the folder path is wrong/missing, call find_case_folder(query=<contact name or case number>) to search storage, pick the best match, then call set_case_folder_path(path=...) to persist it, then list_documents(refresh=true). Use browse_folder(path=...) only as a manual override when find_case_folder doesn't surface the right match.\n" "- DOCUMENT DISCOVERY: If list_documents returns 'No documents' with a diagnostic, read the diagnostic. If the folder path is wrong/missing, call find_case_folder(query=<contact name or case number>) to search storage, pick the best match, then call set_case_folder_path(path=...) to persist it, then list_documents(refresh=true). Use browse_folder(path=...) only as a manual override when find_case_folder doesn't surface the right match.\n"
"- SUBFOLDER SEARCH (mandatory when user names a specific file):\n"
" * If the user names a file (e.g. 'הודעה לבית הדין-...docx') and list_documents shows root subfolders but the file isn't listed at the top level, you MUST recurse into EVERY subfolder via browse_folder before reporting 'not found'. Cases have standard subfolders like מסמכים / התכתבויות / כללי / אסמכתאות — search all of them.\n"
" * NEVER permanently set_case_folder_path to a subfolder just because that's where one file lives. The root must stay at the case root so other documents remain reachable. If you must inspect a subfolder, use browse_folder(path=...), not set_case_folder_path.\n"
"- NEVER tell the user 'no documents' without first running find_case_folder — the folder might just be mis-mapped.\n" "- NEVER tell the user 'no documents' without first running find_case_folder — the folder might just be mis-mapped.\n"
"- When user asks to summarize multiple documents or the entire case folder — use read_multiple_documents with all relevant file paths.\n" "- When user asks to summarize multiple documents or the entire case folder — use read_multiple_documents with all relevant file paths.\n"
"- When user asks to rename or organize files — use batch_rename_documents with an array of rename operations.\n" "- When user asks to rename or organize files — use batch_rename_documents with an array of rename operations.\n"
@@ -70,6 +78,13 @@ TOOL_RULES = (
"- BILLING — irreversible: send_invoice_to_green_invoice issues an official tax document and CANNOT be undone. Require an explicit instruction like 'תשלחי לחשבונית ירוקה', not a vague 'כן'. If unsure, ask again.\n" "- BILLING — irreversible: send_invoice_to_green_invoice issues an official tax document and CANNOT be undone. Require an explicit instruction like 'תשלחי לחשבונית ירוקה', not a vague 'כן'. If unsure, ask again.\n"
"- BILLING — charges: A Charge moves Pending → Approved → (invoiced via create_invoice_from_activities). Cancel only if user explicitly asks. Never approve in bulk without listing the IDs and amounts first.\n" "- BILLING — charges: A Charge moves Pending → Approved → (invoiced via create_invoice_from_activities). Cancel only if user explicitly asks. Never approve in bulk without listing the IDs and amounts first.\n"
"- LEGAL AID (סיוע משפטי): the flow is recorded charges → create_legal_aid_proforma → user submits manually at the official site → mark_legal_aid_submitted with the request number → payment report ingestion (automated) → create_monthly_legal_aid_invoice for the month. NEVER call mark_legal_aid_submitted without an explicit request number provided by the user. Use legal_aid_monthly_summary to preview before create_monthly_legal_aid_invoice.\n" "- LEGAL AID (סיוע משפטי): the flow is recorded charges → create_legal_aid_proforma → user submits manually at the official site → mark_legal_aid_submitted with the request number → payment report ingestion (automated) → create_monthly_legal_aid_invoice for the month. NEVER call mark_legal_aid_submitted without an explicit request number provided by the user. Use legal_aid_monthly_summary to preview before create_monthly_legal_aid_invoice.\n"
"\n"
"WRITING STYLE (mandatory — the user actively dislikes AI-coded text):\n"
"- Never use the em-dash character '' (U+2014, מקף רחב). Forbidden in every Hebrew or English response.\n"
"- Never use the en-dash character '' (U+2013) either.\n"
"- When you need separation, use the hyphen-minus '-' (the regular keyboard dash), or a comma, or a new sentence. Reach for a hyphen only when it actually clarifies — most of the time a comma or full stop reads better.\n"
"- Don't pile up dashes either: 'משפט - תיאור - הסבר' is a tell. Prefer commas, periods, or breaking into two sentences.\n"
"- Avoid other typical AI tells in Hebrew prose: parallel three-item phrases ('ברור, מסודר, ומדויק'), heavy bullet lists when one sentence would do, and over-use of emojis when the user did not invite playfulness.\n"
) )
LEGAL_ASSISTANCE_PROMPT = ( LEGAL_ASSISTANCE_PROMPT = (