from __future__ import annotations from typing import Any import httpx import pytest from activity_core.context_resolvers.state_hub import StateHubContextResolver class DummyResponse: def __init__(self, payload: Any, status_error: Exception | None = None) -> None: self.payload = payload self.status_error = status_error def raise_for_status(self) -> None: if self.status_error is not None: raise self.status_error def json(self) -> Any: return self.payload def test_state_summary_query(monkeypatch) -> None: calls: list[dict[str, Any]] = [] def fake_get(url: str, **kwargs: Any) -> DummyResponse: calls.append({"url": url, **kwargs}) return DummyResponse({"tasks": {"todo": 3}}) monkeypatch.setenv("STATE_HUB_URL", "http://state-hub.test") monkeypatch.setattr(httpx, "get", fake_get) result = StateHubContextResolver().resolve("state_summary", None, {}) assert result == {"tasks": {"todo": 3}} assert calls == [ { "url": "http://state-hub.test/state/summary", "params": None, "timeout": 10.0, } ] def test_daily_triage_queries(monkeypatch) -> None: calls: list[dict[str, Any]] = [] def fake_get(url: str, **kwargs: Any) -> DummyResponse: calls.append({"url": url, **kwargs}) return DummyResponse({"url": url, "params": kwargs.get("params")}) monkeypatch.setenv("STATE_HUB_URL", "http://state-hub.test/") monkeypatch.setattr(httpx, "get", fake_get) resolver = StateHubContextResolver() resolver.resolve("next_steps", None, {}) resolver.resolve("workplan_index", None, {"refresh": False}) resolver.resolve("hub_inbox", None, {"to_agent": "hub", "unread_only": True}) assert calls == [ { "url": "http://state-hub.test/state/next_steps", "params": None, "timeout": 10.0, }, { "url": "http://state-hub.test/workplans/index", "params": {"refresh": False}, "timeout": 10.0, }, { "url": "http://state-hub.test/messages/", "params": {"to_agent": "hub", "unread_only": True}, "timeout": 10.0, }, ] def test_pending_decisions_query(monkeypatch) -> None: calls: list[dict[str, Any]] = [] def fake_get(url: str, **kwargs: Any) -> DummyResponse: calls.append({"url": url, **kwargs}) return DummyResponse([{"id": "d1", "status": "open", "deadline": "2026-07-31T00:00:00Z"}]) monkeypatch.setenv("STATE_HUB_URL", "http://state-hub.test") monkeypatch.setattr(httpx, "get", fake_get) resolver = StateHubContextResolver() result = resolver.resolve( "pending_decisions", None, {"topic_id": "topic-1", "workstream_id": "wp-1"} ) assert result == [{"id": "d1", "status": "open", "deadline": "2026-07-31T00:00:00Z"}] assert calls == [ { "url": "http://state-hub.test/decisions/", "params": {"topic_id": "topic-1", "workstream_id": "wp-1", "status": "open"}, "timeout": 10.0, } ] def test_pending_decisions_query_defaults_status_open(monkeypatch) -> None: calls: list[dict[str, Any]] = [] def fake_get(url: str, **kwargs: Any) -> DummyResponse: calls.append({"url": url, **kwargs}) return DummyResponse([]) monkeypatch.setenv("STATE_HUB_URL", "http://state-hub.test") monkeypatch.setattr(httpx, "get", fake_get) resolver = StateHubContextResolver() resolver.resolve("pending_decisions", None, {}) assert calls == [ { "url": "http://state-hub.test/decisions/", "params": {"status": "open"}, "timeout": 10.0, } ] def test_existing_queries_still_resolve(monkeypatch) -> None: calls: list[dict[str, Any]] = [] def fake_get(url: str, **kwargs: Any) -> DummyResponse: calls.append({"url": url, **kwargs}) if url.endswith("/state/domain/custodian"): return DummyResponse({"ok": True}) if url.endswith("/sbom/activity-core"): return DummyResponse({ "repo_slug": "activity-core", "last_sbom_at": "2026-04-26T11:37:56+00:00", "entry_count": 38, "entries": [], }) raise AssertionError(f"unexpected url {url}") monkeypatch.setenv("STATE_HUB_URL", "http://state-hub.test") monkeypatch.setattr(httpx, "get", fake_get) resolver = StateHubContextResolver() assert resolver.resolve("domain_summary", None, {"domain": "custodian"}) == {"ok": True} sbom = resolver.resolve("repo_sbom_status", None, {"repo_slug": "activity-core"}) assert sbom["repo_slug"] == "activity-core" assert sbom["has_sbom"] is True assert sbom["last_sbom_at"] == "2026-04-26T11:37:56+00:00" assert isinstance(sbom["sbom_age_days"], int) and sbom["sbom_age_days"] >= 0 assert [c["url"] for c in calls] == [ "http://state-hub.test/state/domain/custodian", "http://state-hub.test/sbom/activity-core", ] def test_repo_sbom_status_bulk_returns_worst_repo(monkeypatch) -> None: calls: list[dict[str, Any]] = [] def fake_get(url: str, **kwargs: Any) -> DummyResponse: calls.append({"url": url, **kwargs}) return DummyResponse([ {"slug": "fresh-repo", "last_sbom_at": "2099-01-01T00:00:00+00:00"}, {"slug": "stale-repo", "last_sbom_at": "2024-01-01T00:00:00+00:00"}, {"slug": "never-scanned", "last_sbom_at": None}, ]) monkeypatch.setenv("STATE_HUB_URL", "http://state-hub.test") monkeypatch.setattr(httpx, "get", fake_get) result = StateHubContextResolver().resolve( "repo_sbom_status", None, {"repos": "all"} ) assert calls == [ {"url": "http://state-hub.test/repos/", "params": None, "timeout": 10.0}, ] assert result["total_count"] == 3 # both stale-repo and never-scanned exceed the 30-day staleness threshold assert result["stale_count"] == 2 assert result["worst_repo_slug"] == "never-scanned" assert result["worst_age_days"] == 99999 by_slug = {entry["repo_slug"]: entry for entry in result["repos"]} assert by_slug["fresh-repo"]["has_sbom"] is True assert by_slug["fresh-repo"]["sbom_age_days"] == 0 assert by_slug["never-scanned"]["has_sbom"] is False assert by_slug["never-scanned"]["last_sbom_at"] is None def test_todo_md_staleness_returns_stale_repos(monkeypatch) -> None: calls: list[dict[str, Any]] = [] def fake_get(url: str, **kwargs: Any) -> DummyResponse: calls.append({"url": url, **kwargs}) return DummyResponse({ "stale_days": 6, "repos": [ { "repo_slug": "markitect-main", "has_todo": True, "age_days": 12, "mtime": "2026-06-26T10:00:00+00:00", "todo_path": "/home/worsch/markitect-main/TODO.md", } ], "stale_count": 1, "total_with_todo": 1, "total_scanned": 62, "worst_repo_slug": "markitect-main", "worst_age_days": 12, }) monkeypatch.setenv("STATE_HUB_URL", "http://state-hub.test") monkeypatch.setattr(httpx, "get", fake_get) result = StateHubContextResolver().resolve( "todo_md_staleness", None, {"stale_days": 6} ) assert calls == [{ "url": "http://state-hub.test/repos/todo-md-staleness", "params": {"stale_days": 6}, "timeout": 10.0, }] assert result["stale_count"] == 1 assert result["repos"][0]["repo_slug"] == "markitect-main" def test_todo_md_staleness_returns_empty_on_failure(monkeypatch) -> None: def fake_get(url: str, **kwargs: Any) -> DummyResponse: return DummyResponse(None, status_error=httpx.HTTPError("boom")) monkeypatch.setenv("STATE_HUB_URL", "http://state-hub.test") monkeypatch.setattr(httpx, "get", fake_get) assert StateHubContextResolver().resolve("todo_md_staleness", None, {}) == {} def test_repo_sbom_status_returns_empty_on_failure(monkeypatch) -> None: def fake_get(url: str, **kwargs: Any) -> DummyResponse: return DummyResponse(None, status_error=httpx.HTTPError("boom")) monkeypatch.setenv("STATE_HUB_URL", "http://state-hub.test") monkeypatch.setattr(httpx, "get", fake_get) resolver = StateHubContextResolver() assert resolver.resolve("repo_sbom_status", None, {"repo_slug": "x"}) == {} assert resolver.resolve("repo_sbom_status", None, {"repos": "all"}) == {} def test_coding_retro_returns_latest_progress_suggestions(monkeypatch) -> None: calls: list[dict[str, Any]] = [] def fake_get(url: str, **kwargs: Any) -> DummyResponse: calls.append({"url": url, **kwargs}) return DummyResponse([ { "id": "older-retro", "event_type": "coding_retro", "summary": "older", "created_at": "2026-05-31T17:00:00Z", "detail": { "generated_at": "2026-05-31T17:00:00Z", "suggestions": [ { "repo": "old-repo", "title": "Old recommendation", "recommendation": "Do the older thing.", "priority": "low", "score": 1, } ], }, }, { "id": "note-1", "event_type": "note", "summary": "ignore me", "created_at": "2026-06-07T17:05:00Z", "detail": {}, }, { "id": "newer-retro", "event_type": "coding_retro", "summary": "weekly coding retro ready", "created_at": "2026-06-07T17:10:00Z", "detail": { "generated_at": "2026-06-07T17:09:30Z", "window": { "since": "2026-05-31T00:00:00Z", "until": "2026-06-07T00:00:00Z", }, "suggestions": [ { "target_repo": "activity-core", "title": "Harden schedule smoke gates", "description": "Add a smoke proof before enablement.", "priority": "HIGH", "score": "8.5", }, { "repo_slug": "repo-without-title", "recommendation": "missing title should be skipped", "score": 9, }, ], }, }, { "id": "newer-30-day-retro", "event_type": "coding_retro", "summary": "monthly coding retro ready", "created_at": "2026-06-07T17:15:00Z", "detail": { "generated_at": "2026-06-07T17:14:30Z", "window": { "days": 30, "since": "2026-05-08T00:00:00Z", "until": "2026-06-07T00:00:00Z", }, "suggestions": [ { "repo": "broad-retro-repo", "title": "Should not displace the weekly retro", "recommendation": "Keep weekly schedule bounded.", "priority": "high", "score": 99, } ], }, }, ]) monkeypatch.setenv("STATE_HUB_URL", "http://state-hub.test/") monkeypatch.setattr(httpx, "get", fake_get) result = StateHubContextResolver().resolve( "coding_retro", None, {"limit": 20, "window_days": 7}, ) assert calls == [ { "url": "http://state-hub.test/progress/", "params": {"event_type": "coding_retro", "limit": 20}, "timeout": 10.0, } ] assert result["source_progress_id"] == "newer-retro" assert result["generated_at"] == "2026-06-07T17:09:30Z" assert result["window"] == { "since": "2026-05-31T00:00:00Z", "until": "2026-06-07T00:00:00Z", } assert result["summary"] == "weekly coding retro ready" assert result["suggestions"] == [ { "repo": "activity-core", "title": "Harden schedule smoke gates", "recommendation": "Add a smoke proof before enablement.", "priority": "high", "score": 8.5, } ] def test_coding_retro_returns_empty_when_window_does_not_match(monkeypatch) -> None: def fake_get(url: str, **kwargs: Any) -> DummyResponse: return DummyResponse([ { "id": "monthly-retro", "event_type": "coding_retro", "summary": "monthly coding retro ready", "created_at": "2026-06-07T17:10:00Z", "detail": { "window": {"days": 30}, "suggestions": [ { "repo": "activity-core", "title": "Broad retro item", "recommendation": "Do not emit from weekly schedule.", "priority": "high", "score": 10, } ], }, } ]) monkeypatch.setattr(httpx, "get", fake_get) result = StateHubContextResolver().resolve( "coding_retro", None, {"event_type": "coding_retro", "window_days": 7}, ) assert result == { "suggestions": [], "window": None, "generated_at": None, "source_progress_id": None, "event_type": "coding_retro", "summary": "", } def test_coding_retro_returns_empty_shape_when_not_published(monkeypatch) -> None: def fake_get(url: str, **kwargs: Any) -> DummyResponse: return DummyResponse([ { "id": "note-1", "event_type": "note", "created_at": "2026-06-07T17:10:00Z", } ]) monkeypatch.setattr(httpx, "get", fake_get) result = StateHubContextResolver().resolve( "coding_retro", None, {"event_type": "coding_retro"}, ) assert result == { "suggestions": [], "window": None, "generated_at": None, "source_progress_id": None, "event_type": "coding_retro", "summary": "", } def test_resolver_failure_returns_empty(monkeypatch) -> None: def fake_get(url: str, **kwargs: Any) -> DummyResponse: raise httpx.ConnectError("offline") monkeypatch.setattr(httpx, "get", fake_get) assert StateHubContextResolver().resolve("state_summary", None, {}) == {} def test_unknown_query_returns_empty() -> None: assert StateHubContextResolver().resolve("unknown", None, {}) == {} def test_recently_on_scope_hourly_posts_batch(monkeypatch) -> None: calls: list[dict[str, Any]] = [] def fake_post(url: str, **kwargs: Any) -> DummyResponse: calls.append({"url": url, **kwargs}) return DummyResponse( { "generated": [{"domain_slug": "custodian"}], "skipped": [], "failed": [], } ) monkeypatch.setenv("STATE_HUB_URL", "http://state-hub.test/") monkeypatch.setattr(httpx, "post", fake_post) result = StateHubContextResolver().resolve( "recently_on_scope_hourly", None, { "range": "1h", "active_only": True, "include_attention": False, "required": True, }, ) assert result == { "generated": [{"domain_slug": "custodian"}], "skipped": [], "failed": [], } assert calls == [ { "url": "http://state-hub.test/recently-on-scope/hourly", "json": {"range": "1h", "active_only": True, "include_attention": False}, "timeout": 10.0, } ] def test_recently_on_scope_hourly_failure_bubbles(monkeypatch) -> None: def fake_post(url: str, **kwargs: Any) -> DummyResponse: raise httpx.ConnectError("offline") monkeypatch.setattr(httpx, "post", fake_post) with pytest.raises(httpx.ConnectError): StateHubContextResolver().resolve("recently_on_scope_hourly", None, {"range": "1h"}) def test_consistency_sweep_remote_all_posts_batch(monkeypatch) -> None: calls: list[dict[str, Any]] = [] def fake_post(url: str, **kwargs: Any) -> DummyResponse: calls.append({"url": url, **kwargs}) return DummyResponse( { "exit_code": 0, "lock_skipped": False, "repos_processed": [{"repo_slug": "state-hub", "result": "pass"}], "skipped_clean": ["quiet-repo"], "skipped_missing": [], "skipped_budget": [], } ) monkeypatch.setenv("STATE_HUB_URL", "http://state-hub.test/") monkeypatch.setattr(httpx, "post", fake_post) result = StateHubContextResolver().resolve( "consistency_sweep_remote_all", None, {"max_seconds": 300, "source": "activity-core", "required": True}, ) assert result["exit_code"] == 0 assert result["repos_processed"][0]["repo_slug"] == "state-hub" assert calls == [ { "url": "http://state-hub.test/consistency/sweep/remote-all", "json": {"max_seconds": 300, "source": "activity-core"}, "timeout": 330.0, } ] def test_consistency_sweep_remote_all_failure_bubbles(monkeypatch) -> None: def fake_post(url: str, **kwargs: Any) -> DummyResponse: raise httpx.ConnectError("offline") monkeypatch.setattr(httpx, "post", fake_post) with pytest.raises(httpx.ConnectError): StateHubContextResolver().resolve( "consistency_sweep_remote_all", None, {"max_seconds": 300}, ) def test_consistency_sweep_remote_all_rejects_empty_response(monkeypatch) -> None: def fake_post(url: str, **kwargs: Any) -> DummyResponse: return DummyResponse({}) monkeypatch.setattr(httpx, "post", fake_post) with pytest.raises(RuntimeError, match="missing required key"): StateHubContextResolver().resolve( "consistency_sweep_remote_all", None, {"max_seconds": 300}, ) def test_recently_on_scope_hourly_rejects_empty_response(monkeypatch) -> None: def fake_post(url: str, **kwargs: Any) -> DummyResponse: return DummyResponse({}) monkeypatch.setattr(httpx, "post", fake_post) with pytest.raises(RuntimeError, match="missing required key"): StateHubContextResolver().resolve("recently_on_scope_hourly", None, {"range": "1h"}) def test_daily_triage_digest_is_curated_scalar_json(monkeypatch) -> None: payloads = { "/state/summary": { "generated_at": "2026-05-19T05:20:00Z", "totals": {"tasks": {"todo": 4, "wait": 1}}, "ranked_suggestions": [ { "id": "sug-1", "title": "Issue-core ingestion API key path", "stage": "suggestion", "domain_slug": "custodian", "origin_ref": "issue-core-ingestion-api-key", "relevance": 2, "wsjf": 4.7, "last_requested_at": "2026-05-19T04:00:00Z", } ], "topics": [ { "slug": "custodian", "domain_slug": "custodian", "workstreams": [ { "id": "ws-1", "slug": "cust-wp-0045", "title": "Activity-Core Daily Triage Runner Cutover", "status": "ready", "owner": "custodian", }, { "id": "ws-closed", "slug": "closed", "title": "Closed", "status": "finished", "owner": "custodian", }, ], } ], }, "/workplans/index": { "workstreams": { "ws-1": { "repo_slug": "the-custodian", "relative_path": "workplans/CUST-WP-0045.md", "needs_review": True, "health_labels": ["needs_review"], } } }, "/state/next_steps": [ { "type": "resolved_decision", "domain": "custodian", "workstream_id": "ws-1", "workstream_slug": "cust-wp-0045", "workstream_title": "Activity-Core Daily Triage Runner Cutover", "task_id": "task-1", "task_title": "T05 - Update ActivityDefinition", "message": "free text should not be included", } ], "/messages/": [ { "id": "msg-1", "from_agent": "hub", "subject": "Please review", "body": "free text should not be included", "created_at": "2026-05-19T05:00:00Z", } ], "/workplans/ws-1": { "planning_priority": "high", "planning_order": 45, }, "/tasks/": [ { "id": "task-1", "title": "T05 - Update ActivityDefinition", "status": "todo", "priority": "high", "needs_human": False, "description": "free text should not be included", }, { "id": "task-2", "title": "T06 - Canary Cutover", "status": "wait", "priority": "medium", "needs_human": True, }, ], } def fake_get(url: str, **kwargs: Any) -> DummyResponse: path = url.removeprefix("http://state-hub.test") return DummyResponse(payloads[path]) monkeypatch.setenv("STATE_HUB_URL", "http://state-hub.test") monkeypatch.setattr(httpx, "get", fake_get) raw_digest = StateHubContextResolver().resolve( "daily_triage_digest", None, {"max_workstreams": 4, "max_next_steps": 4}, ) assert isinstance(raw_digest, str) assert "free text should not be included" not in raw_digest import json digest = json.loads(raw_digest) assert digest["totals"] == {"tasks": {"todo": 4, "wait": 1}} assert digest["open_workplans"] == digest["open_workstreams"] assert digest["open_workstreams"][0]["slug"] == "cust-wp-0045" assert digest["open_workstreams"][0]["planning_priority"] == "high" assert digest["open_workstreams"][0]["open_task_counts"] == { "wait": 1, "todo": 1, "progress": 0, "needs_human": 1, "open_total": 2, } assert digest["deterministic_scoring"]["future_mode"] == ( "code_score_high_gain_high_effort_candidates" ) assert digest["ranked_suggestions"][0]["origin_ref"] == "issue-core-ingestion-api-key" def test_legacy_meter_weekly_review_summarises_candidates(monkeypatch) -> None: payloads = { "/legacy-meter/weekly-review": { "generated_at": "2026-07-08T08:30:00+00:00", "window_start": "2026-07-01T08:30:00+00:00", "window_end": "2026-07-08T08:30:00+00:00", "activity_core_handoff": { "activity_id": "statehub-legacy-interface-review", "scheduler_owner": "activity-core", }, "interfaces": [ { "interface": { "interface_key": "rest_api:GET /workstreams/", "interface_kind": "rest_api", "replacement_ref": "GET /workplans/", }, "window": {"calls": 2}, "retirement_candidate": False, }, { "interface": { "interface_key": "mcp:create_workstream", "interface_kind": "mcp_tool", "replacement_ref": "create_workplan", }, "window": {"calls": 0}, "retirement_candidate": True, "retirement_reason": "no measured usage in review window", }, ], "retirement_candidates": [ { "interface": { "interface_key": "mcp:create_workstream", "interface_kind": "mcp_tool", "replacement_ref": "create_workplan", }, "window": {"calls": 0}, "retirement_candidate": True, "retirement_reason": "no measured usage in review window", } ], } } def fake_get(url: str, **kwargs: Any) -> DummyResponse: path = url.replace("http://state-hub.test", "") return DummyResponse(payloads.get(path, {})) monkeypatch.setenv("STATE_HUB_URL", "http://state-hub.test") monkeypatch.setattr(httpx, "get", fake_get) result = StateHubContextResolver().resolve("legacy_meter_weekly_review", None, {"days": 7}) assert result["kind"] == "legacy_meter_weekly_review" assert result["interface_count"] == 2 assert result["retirement_candidate_count"] == 1 assert result["window_legacy_calls"] == 2 assert result["retirement_candidates"][0]["interface_key"] == "mcp:create_workstream" def test_legacy_meter_weekly_review_passes_hours_param(monkeypatch) -> None: seen: dict[str, Any] = {} def fake_get(url: str, **kwargs: Any) -> DummyResponse: seen["params"] = kwargs.get("params") return DummyResponse( { "generated_at": "2026-07-09T08:00:00+00:00", "window_start": "2026-07-09T00:00:00+00:00", "window_end": "2026-07-09T08:00:00+00:00", "interfaces": [], "retirement_candidates": [], } ) monkeypatch.setenv("STATE_HUB_URL", "http://state-hub.test") monkeypatch.setattr(httpx, "get", fake_get) result = StateHubContextResolver().resolve( "legacy_meter_weekly_review", None, {"hours": 8} ) assert seen["params"] == {"hours": 8} assert result["window_label"] == "8h" def test_phase5_stabilization_check_passes(monkeypatch) -> None: payloads = { "/state/health": {"status": "ok", "db": "connected"}, "/state/summary": { "totals": { "workstreams": {"total": 640}, "tasks": {"total": 4002}, "topics": {"total": 14}, } }, "/progress/": [], } def fake_get(url: str, **kwargs: Any) -> DummyResponse: path = url.replace("http://state-hub.test", "") params = kwargs.get("params") or {} if path == "/progress/": if params.get("event_type") == "consistency_sweep_remote_all": return DummyResponse([ { "created_at": "2026-07-06T20:00:00+00:00", "detail": {"exit_code": 0, "skipped_missing": []}, } ]) if params.get("event_type") == "daily_triage": return DummyResponse([ {"created_at": "2026-07-06T19:00:00+00:00", "summary": "ok"} ]) return DummyResponse(payloads.get(path, {})) from datetime import datetime, timezone fixed_now = datetime(2026, 7, 7, 10, 0, tzinfo=timezone.utc) monkeypatch.setenv("STATE_HUB_URL", "http://state-hub.test") monkeypatch.setattr(httpx, "get", fake_get) monkeypatch.setattr( "activity_core.context_resolvers.state_hub._utc_now", lambda: fixed_now, ) result = StateHubContextResolver().resolve("phase5_stabilization_check", None, {}) assert result["overall_pass"] is True assert result["skipped"] is False assert result["checks"]["totals"]["pass"] is True assert result["checks"]["totals"]["workplans"] == 640 assert result["checks"]["totals"]["workstreams"] == 640 def _binky_resolver_env(monkeypatch, progress_by_type): def fake_get(url: str, **kwargs) -> DummyResponse: params = kwargs.get("params") or {} if url.endswith("/progress/"): return DummyResponse(progress_by_type.get(params.get("event_type"), [])) return DummyResponse({}) from datetime import datetime, timezone fixed_now = datetime(2026, 7, 17, 10, 0, tzinfo=timezone.utc) monkeypatch.setenv("STATE_HUB_URL", "http://state-hub.test") monkeypatch.setattr(httpx, "get", fake_get) monkeypatch.setattr( "activity_core.context_resolvers.state_hub._utc_now", lambda: fixed_now, ) def test_binky_rhythm_daily_brief_due_when_no_events(monkeypatch) -> None: _binky_resolver_env(monkeypatch, {"binky_daily_brief": []}) result = StateHubContextResolver().resolve( "binky_rhythm_status", None, {"repo": "binky-control"} ) assert result["repo"] == "binky-control" assert result["items"] == [ { "kind": "daily_brief", "due": True, "date": "2026-07-17", "last_run_at": None, } ] def test_binky_rhythm_daily_brief_not_due_after_todays_run(monkeypatch) -> None: _binky_resolver_env( monkeypatch, { "binky_daily_brief": [ { "event_type": "binky_daily_brief", "created_at": "2026-07-17T06:30:00+00:00", "detail": {"repo": "binky-control"}, } ] }, ) result = StateHubContextResolver().resolve( "binky_rhythm_status", None, {"repo": "binky-control"} ) item = result["items"][0] assert item["due"] is False assert item["last_run_at"] == "2026-07-17T06:30:00+00:00" def test_binky_rhythm_daily_brief_ignores_other_repo_events(monkeypatch) -> None: _binky_resolver_env( monkeypatch, { "binky_daily_brief": [ { "event_type": "binky_daily_brief", "created_at": "2026-07-17T06:30:00+00:00", "detail": {"repo": "some-other-repo"}, } ] }, ) result = StateHubContextResolver().resolve( "binky_rhythm_status", None, {"repo": "binky-control"} ) assert result["items"][0]["due"] is True def test_binky_rhythm_mail_intake_window(monkeypatch) -> None: recent = { "event_type": "binky_mail_intake", "created_at": "2026-07-14T09:40:00+00:00", "detail": {"repo": "binky-control"}, } _binky_resolver_env(monkeypatch, {"binky_mail_intake": [recent]}) result = StateHubContextResolver().resolve( "binky_rhythm_status", None, {"repo": "binky-control", "kind": "mail_intake"} ) assert result["items"][0]["due"] is False stale = dict(recent, created_at="2026-07-09T09:40:00+00:00") _binky_resolver_env(monkeypatch, {"binky_mail_intake": [stale]}) result = StateHubContextResolver().resolve( "binky_rhythm_status", None, {"repo": "binky-control", "kind": "mail_intake"} ) assert result["items"][0]["due"] is True def test_binky_rhythm_weekly_review_carries_milestone_moved(monkeypatch) -> None: _binky_resolver_env( monkeypatch, { "binky_weekly_review": [], "milestone": [ { "event_type": "milestone", "created_at": "2026-07-15T12:00:00+00:00", "detail": {"repo": "binky-control"}, } ], }, ) result = StateHubContextResolver().resolve( "binky_rhythm_status", None, {"repo": "binky-control", "kind": "weekly_review"} ) item = result["items"][0] assert item["due"] is True assert item["milestone_moved"] is True def test_binky_rhythm_weekly_review_milestone_outside_window(monkeypatch) -> None: _binky_resolver_env( monkeypatch, { "binky_weekly_review": [], "milestone": [ { "event_type": "milestone", "created_at": "2026-07-01T12:00:00+00:00", "detail": {"repo": "binky-control"}, } ], }, ) result = StateHubContextResolver().resolve( "binky_rhythm_status", None, {"repo": "binky-control", "kind": "weekly_review"} ) assert result["items"][0]["milestone_moved"] is False def test_binky_rhythm_unknown_kind_returns_error_shape(monkeypatch) -> None: _binky_resolver_env(monkeypatch, {}) result = StateHubContextResolver().resolve( "binky_rhythm_status", None, {"repo": "binky-control", "kind": "nope"} ) assert result["items"] == [] assert "unknown kind" in result["error"] def test_fi_brief_status_due_when_no_events(monkeypatch) -> None: _binky_resolver_env(monkeypatch, {"fi_daily_brief": []}) result = StateHubContextResolver().resolve( "fi_brief_status", None, {"repo": "freedom-intelligence"} ) assert result["repo"] == "freedom-intelligence" assert result["items"] == [ { "kind": "daily_brief", "due": True, "date": "2026-07-17", "last_run_at": None, } ] def test_fi_brief_status_not_due_after_todays_run(monkeypatch) -> None: _binky_resolver_env( monkeypatch, { "fi_daily_brief": [ { "event_type": "fi_daily_brief", "created_at": "2026-07-17T05:30:00+00:00", "detail": {"repo": "freedom-intelligence"}, } ] }, ) result = StateHubContextResolver().resolve( "fi_brief_status", None, {"repo": "freedom-intelligence"} ) item = result["items"][0] assert item["due"] is False assert item["last_run_at"] == "2026-07-17T05:30:00+00:00" def test_fi_brief_status_ignores_other_repo(monkeypatch) -> None: _binky_resolver_env( monkeypatch, { "fi_daily_brief": [ { "event_type": "fi_daily_brief", "created_at": "2026-07-17T05:30:00+00:00", "detail": {"repo": "other-lab"}, } ] }, ) result = StateHubContextResolver().resolve( "fi_brief_status", None, {"repo": "freedom-intelligence"} ) assert result["items"][0]["due"] is True def test_fi_brief_status_unknown_kind(monkeypatch) -> None: _binky_resolver_env(monkeypatch, {}) result = StateHubContextResolver().resolve( "fi_brief_status", None, {"repo": "freedom-intelligence", "kind": "weekly"} ) assert result["items"] == [] assert "unknown kind" in result["error"]