feat: dream-cycle merge scan + pattern desk (leak recall)
Phases 5 & 6, completing the scouting desk. Phase 5 — the nightly consolidation (dream cycle, coherence block) now runs poker.scan_merge_candidates(), filing likely same-person merges to the review queue off the hot path. Fail-safe: a scan error never sinks the cycle. Phase 6 — "you've hit this leak before". Scar/confidence notes are embedded on write; recall_similar_rituals() finds past ones close to the current spot, excluding tonight. The scouting desk adds a pattern pass that surfaces them — but ONLY on genuine strategy/tilt talk (a length + cue gate), so routine logging like "stack 350" never pays for an embed. Respects the per-turn latency concern. 7 tests (deterministic embed stub to keep threshold assertions stable). Full suite 153 green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+40
-4
@@ -173,7 +173,9 @@ def _c():
|
||||
"ALTER TABLE poker_players ADD COLUMN descriptors TEXT",
|
||||
"ALTER TABLE poker_players ADD COLUMN descriptor_embedding BLOB",
|
||||
"ALTER TABLE poker_players ADD COLUMN distinctiveness REAL",
|
||||
"ALTER TABLE poker_players ADD COLUMN named INTEGER DEFAULT 1"):
|
||||
"ALTER TABLE poker_players ADD COLUMN named INTEGER DEFAULT 1",
|
||||
# Embedded scar/confidence notes → "you've hit this leak before".
|
||||
"ALTER TABLE poker_rituals ADD COLUMN embedding BLOB"):
|
||||
try:
|
||||
conn.execute(ddl)
|
||||
except Exception:
|
||||
@@ -502,16 +504,50 @@ def log_ritual(kind: str, content: str | None = None, classification: str | None
|
||||
sid = _resolve(session_id)
|
||||
if sid is None:
|
||||
raise ValueError("no live session")
|
||||
# Embed scar/confidence text so a similar spot later can recall it (Gap 3:
|
||||
# "you've hit this leak before"). Other ritual kinds don't need it.
|
||||
blob = None
|
||||
if content and kind in ("scar", "confidence"):
|
||||
vec = _embed_vec(content)
|
||||
blob = memory._to_blob(vec.tolist()) if vec is not None else None
|
||||
conn = _c()
|
||||
with conn:
|
||||
cur = conn.execute(
|
||||
"INSERT INTO poker_rituals (session_id, kind, content, classification, hand_id, created_at) "
|
||||
"VALUES (?, ?, ?, ?, ?, ?)",
|
||||
(sid, kind, content, classification, hand_id, _now()),
|
||||
"INSERT INTO poker_rituals (session_id, kind, content, classification, hand_id, "
|
||||
"embedding, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)",
|
||||
(sid, kind, content, classification, hand_id, blob, _now()),
|
||||
)
|
||||
return int(cur.lastrowid)
|
||||
|
||||
|
||||
def recall_similar_rituals(text: str, kinds: tuple[str, ...] = ("scar", "confidence"),
|
||||
k: int = 2, min_sim: float = 0.60,
|
||||
exclude_session: int | None = None) -> list[dict]:
|
||||
"""Past scar/confidence notes most similar to `text` — the leak/discipline
|
||||
pattern recall. Excludes the current session so tonight doesn't echo itself."""
|
||||
vec = _embed_vec(text)
|
||||
if vec is None:
|
||||
return []
|
||||
ph = ",".join("?" * len(kinds))
|
||||
rows = _c().execute(
|
||||
f"SELECT r.id, r.kind, r.content, r.classification, r.session_id, r.embedding, "
|
||||
f"s.started_at AS s_at, s.venue AS venue FROM poker_rituals r "
|
||||
f"LEFT JOIN poker_sessions s ON s.id = r.session_id "
|
||||
f"WHERE r.embedding IS NOT NULL AND r.kind IN ({ph})", tuple(kinds)
|
||||
).fetchall()
|
||||
scored = []
|
||||
for row in rows:
|
||||
if exclude_session and row["session_id"] == exclude_session:
|
||||
continue
|
||||
sim = _cos(vec, memory._from_blob(row["embedding"]))
|
||||
if sim >= min_sim:
|
||||
scored.append((sim, row))
|
||||
scored.sort(key=lambda x: x[0], reverse=True)
|
||||
return [{"kind": r["kind"], "content": r["content"], "classification": r["classification"],
|
||||
"when": r["s_at"], "venue": r["venue"], "sim": round(s, 3)}
|
||||
for s, r in scored[:k]]
|
||||
|
||||
|
||||
def list_rituals(session_id: int | None = None,
|
||||
kinds: tuple[str, ...] | None = None) -> list[dict]:
|
||||
"""Ritual events for a session, oldest first; optionally filtered by kind."""
|
||||
|
||||
Reference in New Issue
Block a user