From 552943d6c021bd8d8261e3fa1cee83d676889c67 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Tue, 12 May 2026 14:33:57 -0400 Subject: [PATCH] feat(journal): closeout system prompt with structured-field guard Co-Authored-By: Claude Opus 4.7 (1M context) --- src/fabledassistant/services/journal_closeout.py | 16 ++++++++++++++++ tests/test_journal_closeout.py | 11 +++++++++++ 2 files changed, 27 insertions(+) diff --git a/src/fabledassistant/services/journal_closeout.py b/src/fabledassistant/services/journal_closeout.py index 843e05c..5155abe 100644 --- a/src/fabledassistant/services/journal_closeout.py +++ b/src/fabledassistant/services/journal_closeout.py @@ -38,3 +38,19 @@ def _build_transcript(messages) -> str: return "\n".join( f"{m.role.upper()}: {m.content[:_CONTENT_CAP]}" for m in tail ) + + +SYSTEM_PROMPT = ( + "You are reviewing a day's journal conversation to extract preference " + "observations the USER revealed about themselves.\n\n" + "Rules:\n" + "- Only extract patterns, habits, recurring frustrations, or contextual " + "facts the user said or demonstrated.\n" + "- DO NOT restate facts that belong in structured fields: name, job title, " + "industry, expertise level, response style, tone, interests. Those are " + "handled separately.\n" + "- DO NOT extract anything from the ASSISTANT turns about the user — only " + "what the user themselves stated or demonstrated by their choices.\n" + "- Write 2-5 short bullet points. Be specific and factual.\n" + "- If nothing notable, output only: (nothing to note)" +) diff --git a/tests/test_journal_closeout.py b/tests/test_journal_closeout.py index 9e96d84..6cd4b33 100644 --- a/tests/test_journal_closeout.py +++ b/tests/test_journal_closeout.py @@ -51,3 +51,14 @@ def test_build_transcript_keeps_only_last_20_messages(): # Newest 20 means msg-10 through msg-29 assert lines[0] == "USER: msg-10" assert lines[-1] == "USER: msg-29" + + +def test_system_prompt_lists_structured_fields_to_exclude(): + """The prompt must explicitly tell the LLM not to restate structured + fields, so the freeform learned_summary stays a narrow lane.""" + from fabledassistant.services.journal_closeout import SYSTEM_PROMPT + + text = SYSTEM_PROMPT.lower() + for field in ("name", "job title", "industry", "expertise", "response style", "tone", "interests"): + assert field in text, f"system prompt should mention '{field}'" + assert "(nothing to note)" in SYSTEM_PROMPT