session-memory Phase 1: Detect pipeline (T04-T07)

- detect/signals.py: pure extractors over digests (retry storm, repeated
  errors, budget overrun vs corpus p90, abandoned, clean pass, recovery)
- detect/cluster.py: deterministic clustering into candidate Patterns with
  evidence (sessions/repos/flavors/cost impact) + cross-flavor flagging
- detect/__main__.py: python -m session_memory.detect, ranked report
  (cross-flavor first) + --json; persists candidates to Tier 2 patterns table
- core/store.py: list_digests + save_patterns
- tests for signals, cluster, detect entrypoint

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-06 22:31:13 +02:00
parent 06767ef924
commit 436a96dcd8
9 changed files with 436 additions and 4 deletions

View File

@@ -223,6 +223,22 @@ class Store:
row = self.db.execute("SELECT json FROM digests WHERE session_uid=?", (session_uid,)).fetchone()
return json.loads(row["json"]) if row else None
def list_digests(self) -> list[dict[str, Any]]:
return [json.loads(r["json"]) for r in self.db.execute("SELECT json FROM digests")]
def save_patterns(self, patterns: list[dict[str, Any]]) -> None:
"""Persist candidate patterns to a Tier 2 table (replace prior run)."""
self.db.execute(
"CREATE TABLE IF NOT EXISTS patterns ("
"key TEXT PRIMARY KEY, json TEXT NOT NULL, detected_at TEXT NOT NULL)"
)
self.db.execute("DELETE FROM patterns")
self.db.executemany(
"INSERT INTO patterns(key, json, detected_at) VALUES(?,?,?)",
[(p["key"], json.dumps(p, sort_keys=True), _now()) for p in patterns],
)
self.db.commit()
# ---- reads -------------------------------------------------------------
def get_session(self, session_uid: str) -> Optional[Session]: