146 lines
4.6 KiB
Python
146 lines
4.6 KiB
Python
from __future__ import annotations
|
|
|
|
import json
|
|
import os
|
|
import subprocess
|
|
from datetime import date
|
|
from pathlib import Path
|
|
|
|
from rein_aharness import brief_weekly
|
|
|
|
|
|
def _git(repo: Path, *args: str, commit_date: str | None = None) -> None:
|
|
env = None
|
|
if commit_date:
|
|
env = dict(os.environ)
|
|
env["GIT_AUTHOR_DATE"] = commit_date
|
|
env["GIT_COMMITTER_DATE"] = commit_date
|
|
subprocess.run(
|
|
["git", *args], cwd=repo, check=True, capture_output=True, env=env
|
|
)
|
|
|
|
|
|
def _repo(tmp_path: Path) -> Path:
|
|
repo = tmp_path / "binky-control"
|
|
repo.mkdir()
|
|
_git(repo, "init")
|
|
_git(repo, "config", "user.email", "test@example.com")
|
|
_git(repo, "config", "user.name", "test")
|
|
for name, body in {
|
|
"SuccessMilestones.md": "# Milestones\n\nS1: started\n",
|
|
"DecisionQueue.md": "# Decisions\n\nDEC-1 prepared\n",
|
|
"RiskRegister.md": "# Risks\n\nRISK-005 open\n",
|
|
"WORK-RECORDS.md": "# Records\n",
|
|
}.items():
|
|
(repo / name).write_text(body, encoding="utf-8")
|
|
(repo / "briefs").mkdir()
|
|
(repo / "briefs/2026-08-07-daily-brief.md").write_text(
|
|
"# Daily Brief\n\nProgress happened.\n", encoding="utf-8"
|
|
)
|
|
_git(repo, "add", ".")
|
|
_git(
|
|
repo,
|
|
"commit",
|
|
"-m",
|
|
"initial evidence",
|
|
commit_date="2026-07-01T12:00:00+00:00",
|
|
)
|
|
return repo
|
|
|
|
|
|
def test_render_uses_deterministic_risk_state() -> None:
|
|
signals = brief_weekly.WeeklySignals(
|
|
milestone_moved=False,
|
|
activity_present=True,
|
|
prior_week_milestone_free=True,
|
|
risk005_state="escalate",
|
|
)
|
|
text = brief_weekly.render_brief(
|
|
date(2026, 8, 7),
|
|
{
|
|
"milestone_summary": "Work occurred but no status changed.",
|
|
"milestone_evidence": ["S1-related work landed"],
|
|
"founder_actions": ["Review DEC-1"],
|
|
"risk005_state": "clear",
|
|
},
|
|
signals,
|
|
)
|
|
assert "**No.**" in text
|
|
assert "**State: escalate.**" in text
|
|
assert "Review DEC-1" in text
|
|
assert "State: clear" not in text
|
|
|
|
|
|
def test_derive_signals_escalates_after_prior_free_week(tmp_path: Path) -> None:
|
|
repo = _repo(tmp_path)
|
|
(repo / "briefs/2026-07-31-weekly-founder-review.md").write_text(
|
|
"# Weekly Founder Review\n\nNo milestone status changed this week.\n",
|
|
encoding="utf-8",
|
|
)
|
|
_git(repo, "add", ".")
|
|
_git(repo, "commit", "-m", "prior weekly review")
|
|
signals = brief_weekly.derive_signals(repo, date.today())
|
|
assert not signals.milestone_moved
|
|
assert signals.activity_present
|
|
assert signals.prior_week_milestone_free
|
|
assert signals.risk005_state == "escalate"
|
|
|
|
|
|
def test_run_weekly_mock_writes_commits_and_reports(tmp_path: Path, monkeypatch) -> None:
|
|
repo = _repo(tmp_path)
|
|
events: list[dict] = []
|
|
monkeypatch.setattr(
|
|
brief_weekly.hub,
|
|
"post_progress_event",
|
|
lambda **kwargs: events.append(kwargs) or True,
|
|
)
|
|
|
|
def fake(prompt: str) -> str:
|
|
assert "SuccessMilestones.md" in prompt
|
|
assert "Deterministic signals" in prompt
|
|
return json.dumps(
|
|
{
|
|
"milestone_summary": "No milestone status changed.",
|
|
"milestone_evidence": ["Daily work was recorded."],
|
|
"founder_actions": ["Review DEC-1"],
|
|
}
|
|
)
|
|
|
|
result = brief_weekly.run_brief_weekly(
|
|
repo,
|
|
day=date(2026, 8, 8),
|
|
force=True,
|
|
complete_fn=fake,
|
|
)
|
|
assert result.ok
|
|
assert result.wrote
|
|
assert result.committed
|
|
assert result.risk005_state == "quiet"
|
|
assert (repo / "briefs/2026-08-08-weekly-founder-review.md").is_file()
|
|
assert events[-1]["event_type"] == "binky_weekly_review"
|
|
assert events[-1]["detail"]["risk005_state"] == result.risk005_state
|
|
|
|
|
|
def test_skip_existing_does_not_call_model(tmp_path: Path, monkeypatch) -> None:
|
|
repo = _repo(tmp_path)
|
|
monkeypatch.setattr(brief_weekly.hub, "post_progress_event", lambda **kw: True)
|
|
day = date(2026, 8, 8)
|
|
path = brief_weekly.brief_path_for(repo, day)
|
|
path.write_text("# Weekly Founder Review\n", encoding="utf-8")
|
|
_git(repo, "add", ".")
|
|
_git(repo, "commit", "-m", "weekly review")
|
|
|
|
result = brief_weekly.run_brief_weekly(
|
|
repo,
|
|
day=day,
|
|
complete_fn=lambda prompt: (_ for _ in ()).throw(AssertionError(prompt)),
|
|
)
|
|
assert result.ok
|
|
assert result.skipped_existing
|
|
|
|
|
|
def test_parse_response_accepts_json_fence() -> None:
|
|
data = brief_weekly.parse_response(
|
|
'```json\n{"milestone_summary":"none","milestone_evidence":[],"founder_actions":[]}\n```'
|
|
)
|
|
assert data["milestone_summary"] == "none"
|