refactor: retire the KB-recall bridge — WT #383 native reference_knowledge (b167)

Worldtree #383 shipped native Tier-3 reference_knowledge (v1.0.0b167, live on :8081 +
demo): every Tier-3 agent context now carries the tool automatically, with evidence
packets (note_id + path provenance, confidence bucket) and a server-side grounding
rule. That supersedes the interim consumer-side memory_context pinning bridge (slice
3), so it is deleted per its INV-KB-1 retire seam.

Removed:
- src/ratatoskr/kb_bridge.py + tests/test_kb_bridge.py (the whole module).
- server.py: the pin_kb_context import + the single turn-path call-site (reverted to
  the pre-bridge wt.stream_turn call), the SSE keepalive that only covered the consult
  delay, and the bridge-only agent_id plumbing (TurnHandle.agent_id + the submit read).
- index.html: agent_id dropped from the turn POST body.
- test_web_server.py: TestKbBridgeWiring (tested the removed call-site).

Kept:
- wt.stream_turn's memory_context param (inert SDK-parity passthrough; worldtree-dev
  concurred it stays) + its forwarding tests.
- the non-str content 400 guard (general input hygiene, not bridge-specific).

Retirement LIVE-VERIFIED before deletion: a Donut session on :8081/b167 carries
builtin_tools=['reference_knowledge']; she called it and grounded in the DCC Collapse
content fully in-voice, degrading gracefully on absent content. 524 green.

Contract marks slice-3 RETIRED (historical record retained). #383 closed.
This commit is contained in:
vh
2026-08-01 23:21:44 -07:00
parent f537416f15
commit 09e425787b
6 changed files with 18 additions and 449 deletions
-82
View File
@@ -1575,85 +1575,3 @@ class TestTtsEndpoint:
)
assert resp.status_code == 200
class TestKbBridgeWiring:
"""The KB-recall bridge seam (slice 3, INV-KB-1): the turn path calls
pin_kb_context and forwards its result as memory_context on the turn POST.
Proves the ONE call-site is wired end-to-end (the consult itself is unit-tested
in test_kb_bridge.py; here we stub it to assert the plumbing)."""
@respx.mock
def test_interview_agent_pins_context_into_turn_post(self, monkeypatch) -> None:
from ratatoskr.web import server
from ratatoskr.web.server import create_app
seen = {}
async def _fake_pin(question, agent_id, *, client):
seen["question"] = question
seen["agent_id"] = agent_id
return [{"kind": "corpus_reference", "text": "grounded passage"}]
monkeypatch.setattr(server, "pin_kb_context", _fake_pin)
route = respx.post("https://w.example/sessions/s-1/messages").mock(
return_value=_sse_resp(_sse_chunk("42:1", _DONE_BODY))
)
c = TestClient(create_app(_mock_client_factory()))
tid = c.post(
"/api/turns/s-1",
json={"content": "who is Carl?", "agent_id": "ratatoskr:donut"},
).json()["turn_id"]
with c.stream("GET", f"/api/turns/s-1/stream?turn_id={tid}") as resp:
b"".join(resp.iter_bytes())
# The browser-sent agent_id reached the bridge, and its result rode the POST.
assert seen == {"question": "who is Carl?", "agent_id": "ratatoskr:donut"}
body = json.loads(route.calls.last.request.content)
assert body["memory_context"] == [
{"kind": "corpus_reference", "text": "grounded passage"}
]
@respx.mock
def test_non_interview_agent_pins_nothing(self) -> None:
# Real pin_kb_context: a non-allowlisted agent short-circuits to [] (no consult),
# so memory_context is absent from the turn POST body (SDK omits None).
from ratatoskr.web.server import create_app
route = respx.post("https://w.example/sessions/s-1/messages").mock(
return_value=_sse_resp(_sse_chunk("42:1", _DONE_BODY))
)
c = TestClient(create_app(_mock_client_factory()))
tid = c.post(
"/api/turns/s-1", json={"content": "hi", "agent_id": "mimir"}
).json()["turn_id"]
with c.stream("GET", f"/api/turns/s-1/stream?turn_id={tid}") as resp:
b"".join(resp.iter_bytes())
body = json.loads(route.calls.last.request.content)
assert "memory_context" not in body or body["memory_context"] is None
@respx.mock
def test_failed_consult_still_streams_the_turn(self, monkeypatch) -> None:
# A degraded/failed KB consult (returns []) must NOT block or fail the character
# turn — it streams to `done` with no pinned context (INV-KB-3, server-level;
# heid-code-review F9: the turn-path failure seam was untested end to end).
from ratatoskr.web import server
from ratatoskr.web.server import create_app
async def _degraded_pin(question, agent_id, *, client):
return [] # consult failed/timed-out internally → degraded to []
monkeypatch.setattr(server, "pin_kb_context", _degraded_pin)
respx.post("https://w.example/sessions/s-1/messages").mock(
return_value=_sse_resp(
_sse_chunk("42:1", {"type": "text", "content": "hi"})
+ _sse_chunk("42:2", _DONE_BODY)
)
)
c = TestClient(create_app(_mock_client_factory()))
tid = c.post(
"/api/turns/s-1",
json={"content": "who is Carl?", "agent_id": "ratatoskr:donut"},
).json()["turn_id"]
with c.stream("GET", f"/api/turns/s-1/stream?turn_id={tid}") as resp:
raw = b"".join(resp.iter_bytes())
events = [e["event"] for e in _parse_browser_sse(raw)]
assert "text" in events and "done" in events # the turn completed normally