From 9c9d71eb31570c1eeede2b657236ac13e50dcc0a Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Sun, 26 Apr 2026 21:41:15 -0400 Subject: [PATCH] fix: _witness_role_for defensive None handling (T79) --- chat/services/prompt.py | 9 ++++++++- tests/test_prompt.py | 9 ++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/chat/services/prompt.py b/chat/services/prompt.py index 0ba2bbd..d27d23c 100644 --- a/chat/services/prompt.py +++ b/chat/services/prompt.py @@ -379,8 +379,15 @@ def _witness_role_for(speaker_bot_id: str, host_bot_id: str | None) -> str: pinned the contract on ``search_memories``; this helper applies it at the call site so a guest-as-speaker doesn't silently retrieve memories under the wrong POV mask. + + When ``host_bot_id`` is ``None`` (degenerate case from a half-seeded + chat or Phase-1 path), the speaker is treated as the host so the + query falls back to the host POV mask rather than silently masking + the speaker's own memories as a guest. """ - return "host" if speaker_bot_id == host_bot_id else "guest" + if host_bot_id is None or speaker_bot_id == host_bot_id: + return "host" + return "guest" def _resolve_addressee( diff --git a/tests/test_prompt.py b/tests/test_prompt.py index e8fc30d..471d5b4 100644 --- a/tests/test_prompt.py +++ b/tests/test_prompt.py @@ -21,7 +21,7 @@ import chat.state.world # noqa: F401 import chat.state.events # noqa: F401 import chat.state.threads # noqa: F401 from chat.llm.client import Message -from chat.services.prompt import assemble_narrative_prompt +from chat.services.prompt import _witness_role_for, assemble_narrative_prompt def _seed_basic(conn) -> None: @@ -852,3 +852,10 @@ def test_assemble_with_open_thread_renders_block(tmp_path): body = msgs[0].content assert "Open threads:" in body assert "Maya's job hunt" in body + + +def test_witness_role_for_none_host_returns_host(): + assert _witness_role_for("bot_a", None) == "host" + # Sanity check: existing semantics preserved. + assert _witness_role_for("bot_a", "bot_a") == "host" + assert _witness_role_for("bot_a", "bot_b") == "guest"