rein-aharness/tests/test_brief_daily.py
tegwick f770825975 feat: brief-daily via llm-connect (structured daily brief)
Generate OperatingRhythm-format briefs with OpenRouter-backed llm-connect
JSON + deterministic markdown write/commit. Server path for Binky daily
rhythm without host Claude (BINKY-WP-0006-T05).
2026-07-22 00:18:52 +02:00

125 lines
3.8 KiB
Python

from __future__ import annotations
import json
import subprocess
from datetime import date
from pathlib import Path
from agent_harness import brief_daily
def _git_repo(tmp_path: Path) -> Path:
repo = tmp_path / "binky-control"
repo.mkdir()
subprocess.run(["git", "init"], cwd=repo, check=True, capture_output=True)
subprocess.run(
["git", "config", "user.email", "test@example.com"],
cwd=repo,
check=True,
capture_output=True,
)
subprocess.run(
["git", "config", "user.name", "test"],
cwd=repo,
check=True,
capture_output=True,
)
(repo / "DecisionQueue.md").write_text(
"# DecisionQueue\n\n## Open\n\n### DEC-2026-999\nstatus: prepared\n",
encoding="utf-8",
)
(repo / "OfficeHourQueue.md").write_text("# OH\n", encoding="utf-8")
(repo / "AutopilotWorkQueue.md").write_text("# AWQ\n", encoding="utf-8")
(repo / "RiskRegister.md").write_text("# Risks\n", encoding="utf-8")
(repo / "briefs").mkdir()
subprocess.run(["git", "add", "."], cwd=repo, check=True, capture_output=True)
subprocess.run(
["git", "commit", "-m", "init"],
cwd=repo,
check=True,
capture_output=True,
)
return repo
def test_render_brief_format() -> None:
md = brief_daily.render_brief(
date(2026, 7, 22),
{
"decide_now": ["DEC-1 approve cutover"],
"progress": ["WP-0005 finished"],
"risks": [],
"best_next_hour": "Approve DEC-1",
},
)
assert md.startswith("# Daily Brief — 2026-07-22\n")
assert "## Decide now" in md
assert "## Progress" in md
assert "## Risks" in md
assert "## Best next hour" in md
assert "No RiskRegister changes" in md
assert "Approve DEC-1" in md
def test_parse_brief_response_fences() -> None:
data = brief_daily.parse_brief_response(
'```json\n{"decide_now":[],"progress":["x"],"risks":[],'
'"best_next_hour":"none"}\n```'
)
assert data["progress"] == ["x"]
def test_run_brief_daily_mock(tmp_path: Path, monkeypatch) -> None:
repo = _git_repo(tmp_path)
monkeypatch.setattr(brief_daily.hub, "post_progress_event", lambda **kw: True)
day = date(2026, 7, 22)
def fake(prompt: str) -> str:
assert "DecisionQueue" in prompt
return json.dumps(
{
"decide_now": ["DEC-2026-999 go"],
"progress": ["scaffold landed"],
"risks": [],
"best_next_hour": "no founder action needed today",
}
)
result = brief_daily.run_brief_daily(
repo, day=day, complete_fn=fake, force=True
)
assert result.ok
assert result.wrote
assert result.committed
path = repo / "briefs" / "2026-07-22-daily-brief.md"
assert path.is_file()
text = path.read_text(encoding="utf-8")
assert "DEC-2026-999" in text
assert "scaffold landed" in text
def test_skip_existing_brief(tmp_path: Path, monkeypatch) -> None:
repo = _git_repo(tmp_path)
monkeypatch.setattr(brief_daily.hub, "post_progress_event", lambda **kw: True)
day = date(2026, 7, 22)
path = brief_daily.brief_path_for(repo, day)
path.write_text("# Daily Brief — 2026-07-22\n\nalready\n", encoding="utf-8")
subprocess.run(["git", "add", "."], cwd=repo, check=True, capture_output=True)
subprocess.run(
["git", "commit", "-m", "brief"],
cwd=repo,
check=True,
capture_output=True,
)
called = {"n": 0}
def boom(prompt: str) -> str:
called["n"] += 1
raise AssertionError("should not call LLM")
result = brief_daily.run_brief_daily(
repo, day=day, complete_fn=boom, force=False
)
assert result.ok
assert result.skipped_existing
assert called["n"] == 0