fix: witness role parametric in prompt assembly (T71.1)
Phase 2 T46 pinned the witness mask contract on search_memories with a witness_role parameter (host/guest/you). The prompt-assembly call site in assemble_narrative_prompt was hardcoded to "host", which silently returned the wrong rows when the speaker was the guest bot. Derive the witness role from chat membership via a new private helper _witness_role_for(speaker_bot_id, host_bot_id), and apply it at the search_memories call. Behaviour is identical when the speaker is the host (or when no guest is present); the fix is load-bearing only when the guest bot is the speaker — exactly the scenario Phase 2 T43 added support for. Tests: pin both directions (host-as-speaker and guest-as-speaker) by patching the imported search_memories reference and asserting the witness_role argument the call site emits.
This commit is contained in:
@@ -452,6 +452,68 @@ def test_assemble_when_speaker_is_guest_orients_edges_correctly(tmp_path):
|
||||
assert "68/100" in body
|
||||
|
||||
|
||||
def test_speaker_is_guest_uses_guest_witness_role(tmp_path, monkeypatch):
|
||||
"""T71.1: when the guest is the speaker, ``search_memories`` is
|
||||
called with ``witness_role="guest"``, not the previously-hardcoded
|
||||
``"host"``. Pins the parametric witness role at the prompt call site
|
||||
so guest-as-speaker honours the witness mask via Phase 2 T46.
|
||||
"""
|
||||
db = tmp_path / "t.db"
|
||||
apply_migrations(db)
|
||||
captured: dict = {}
|
||||
|
||||
def _fake_search(conn, owner_id, witness_role, query, k=4):
|
||||
captured["owner_id"] = owner_id
|
||||
captured["witness_role"] = witness_role
|
||||
captured["query"] = query
|
||||
return []
|
||||
|
||||
# Patch the imported reference inside the prompt module so the
|
||||
# production call site uses the fake.
|
||||
import chat.services.prompt as prompt_mod
|
||||
monkeypatch.setattr(prompt_mod, "search_memories", _fake_search)
|
||||
|
||||
with open_db(db) as conn:
|
||||
_seed_with_guest(conn)
|
||||
# Guest as speaker — must request memories with witness_role="guest".
|
||||
assemble_narrative_prompt(
|
||||
conn,
|
||||
chat_id="chat_bot_a",
|
||||
speaker_bot_id="bot_b",
|
||||
recent_dialogue=[],
|
||||
# retrieved_memory_summaries=None forces the search path.
|
||||
retrieved_memory_summaries=None,
|
||||
)
|
||||
assert captured["owner_id"] == "bot_b"
|
||||
assert captured["witness_role"] == "guest"
|
||||
|
||||
|
||||
def test_speaker_is_host_uses_host_witness_role(tmp_path, monkeypatch):
|
||||
"""T71.1 (regression): host-as-speaker still queries with
|
||||
``witness_role="host"``."""
|
||||
db = tmp_path / "t.db"
|
||||
apply_migrations(db)
|
||||
captured: dict = {}
|
||||
|
||||
def _fake_search(conn, owner_id, witness_role, query, k=4):
|
||||
captured["witness_role"] = witness_role
|
||||
return []
|
||||
|
||||
import chat.services.prompt as prompt_mod
|
||||
monkeypatch.setattr(prompt_mod, "search_memories", _fake_search)
|
||||
|
||||
with open_db(db) as conn:
|
||||
_seed_with_guest(conn)
|
||||
assemble_narrative_prompt(
|
||||
conn,
|
||||
chat_id="chat_bot_a",
|
||||
speaker_bot_id="bot_a", # host as speaker
|
||||
recent_dialogue=[],
|
||||
retrieved_memory_summaries=None,
|
||||
)
|
||||
assert captured["witness_role"] == "host"
|
||||
|
||||
|
||||
def test_assemble_with_tight_budget_drops_guest_activity_first(tmp_path):
|
||||
"""Under tight budget MUST blocks survive but SHOULD-tier guest
|
||||
activity is dropped first."""
|
||||
|
||||
Reference in New Issue
Block a user