Files
agentic-resources/session_memory/retro/__main__.py
tegwick 0d05dfcc5d session-memory: weekly retro entrypoint + hub publish (AGENTIC-WP-0010)
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>
2026-06-07 19:17:24 +02:00

69 lines
2.6 KiB
Python

"""Weekly retro entrypoint (AGENTIC-WP-0010 T03).
python -m session_memory.retro [--window-days 7] [--since D] [--until D]
[--publish] [--json]
Builds the windowed top-3-per-repo retro over the captured sessions, writes a local
JSON + markdown report, and (with ``--publish``) posts it to the hub as the
``coding_retro`` read model that activity-core's weekly schedule consumes.
"""
from __future__ import annotations
import argparse
import json
import os
from ..core.store import Store
from ..curate.catalog import Catalog
from ..ingest import _expand, load_config
from .build import weekly_retro
from .publish import publish_to_hub, render_markdown, write_local
def run_retro(config: dict, *, window_days=None, since=None, until=None):
s = config.get("store", {})
store = Store(_expand(s["db_path"]), _expand(s["blob_dir"]))
digests = store.list_digests()
store.close()
cur = config.get("curate", {})
catalog = Catalog(_expand(cur.get("catalog_dir", "session_memory/catalog")))
rcfg = config.get("retro", {})
return weekly_retro(digests, catalog, since=since, until=until,
window_days=window_days or rcfg.get("window_days", 7))
def main(argv=None) -> int:
here = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
ap = argparse.ArgumentParser(description="Build (and optionally publish) the weekly coding retro.")
ap.add_argument("--config", default=os.path.join(here, "config.toml"))
ap.add_argument("--window-days", type=int, default=None)
ap.add_argument("--since", default=None)
ap.add_argument("--until", default=None)
ap.add_argument("--publish", action="store_true", help="post to the hub coding_retro read model")
ap.add_argument("--json", action="store_true")
args = ap.parse_args(argv)
config = load_config(args.config)
report = run_retro(config, window_days=args.window_days, since=args.since, until=args.until)
rcfg = config.get("retro", {})
write_local(report, _expand(rcfg.get("report_json", "session_memory/retro/last_retro.json")),
_expand(rcfg.get("report_md", "session_memory/retro/last_retro.md")))
published = None
if args.publish:
published = publish_to_hub(report, base_url=rcfg.get("hub_url", "http://127.0.0.1:8000"))
if args.json:
print(json.dumps({"report": report, "published": published}, indent=2))
else:
print(render_markdown(report))
if args.publish:
print(f"\npublished to hub: {published}")
return 0
if __name__ == "__main__":
raise SystemExit(main())