generated from coulomb/repo-seed
The analysis half of the weekly coding retrospection. retro/build.py: windowed detect+measure -> top-3 improvement suggestions per repo (cross-flavor first, recommendations pulled from the Pattern Catalog) + fleet snapshot. retro/publish.py: publishes the report to the hub as the coding_retro read model (event_type= coding_retro progress event) + local JSON/md, graceful degrade. retro entrypoint with --window-days/--publish/--json. Live verify over real sessions surfaced per-repo suggestions with catalog recommendations. 13 new tests; suite 152/152. Consumed by activity-core ACTIVITY-WP-0008 (Weekly Coding Retrospection, Sat 19:00). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
64 lines
2.4 KiB
Python
64 lines
2.4 KiB
Python
"""Retro entrypoint tests (AGENTIC-WP-0010 T03)."""
|
|
|
|
import json
|
|
import os
|
|
import sys
|
|
|
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
|
|
from session_memory.core.store import Store # noqa: E402
|
|
from session_memory.retro.__main__ import main, run_retro # noqa: E402
|
|
|
|
|
|
def _digest(uid, repo, ts, retries=5):
|
|
return {
|
|
"session_uid": uid, "flavor": "claude", "repo": repo, "outcome": "fail",
|
|
"started_at": ts, "event_count": 40,
|
|
"first_prompt": "Fix the failing build and retry the suite repeatedly",
|
|
"cost": {"input_tokens": 100, "output_tokens": 10},
|
|
"tool_histogram": {"Bash": 20, "Edit": 12, "Read": 8},
|
|
"markers": {"errors": 0, "retries": retries, "test_runs": 0},
|
|
"error_snippets": [],
|
|
}
|
|
|
|
|
|
def _config(tmp_path):
|
|
store = tmp_path / ".store"
|
|
toml = tmp_path / "config.toml"
|
|
toml.write_text(
|
|
f'[store]\ndb_path="{store / "m.db"}"\nblob_dir="{store / "blobs"}"\ncursor="{store / "c.json"}"\n'
|
|
f'[curate]\ncatalog_dir="{tmp_path / "catalog"}"\n'
|
|
f'[retro]\nwindow_days=7\nreport_json="{tmp_path / "r.json"}"\nreport_md="{tmp_path / "r.md"}"\n')
|
|
st = Store(str(store / "m.db"), str(store / "blobs"))
|
|
st.write_digest("claude:a", _digest("claude:a", "r1", "2026-06-01T10:00:00Z"))
|
|
st.write_digest("claude:b", _digest("claude:b", "r1", "2026-06-02T10:00:00Z"))
|
|
st.close()
|
|
return str(toml), tmp_path
|
|
|
|
|
|
def test_run_retro_over_store(tmp_path):
|
|
from session_memory.ingest import load_config
|
|
cfg_path, _ = _config(tmp_path)
|
|
rep = run_retro(load_config(cfg_path), since="2026-05-30T00:00:00Z", until="2026-06-08T00:00:00Z")
|
|
assert rep["n_sessions"] == 2
|
|
assert rep["suggestions"]
|
|
|
|
|
|
def test_main_writes_report_files(tmp_path, capsys):
|
|
cfg_path, tp = _config(tmp_path)
|
|
rc = main(["--config", cfg_path, "--since", "2026-05-30T00:00:00Z",
|
|
"--until", "2026-06-08T00:00:00Z"])
|
|
assert rc == 0
|
|
assert os.path.exists(str(tp / "r.json")) and os.path.exists(str(tp / "r.md"))
|
|
assert "Weekly Coding Retro" in capsys.readouterr().out
|
|
|
|
|
|
def test_main_json(tmp_path, capsys):
|
|
cfg_path, _ = _config(tmp_path)
|
|
rc = main(["--config", cfg_path, "--since", "2026-05-30T00:00:00Z",
|
|
"--until", "2026-06-08T00:00:00Z", "--json"])
|
|
assert rc == 0
|
|
data = json.loads(capsys.readouterr().out)
|
|
assert data["report"]["n_sessions"] == 2
|
|
assert data["published"] is None # no --publish
|