From 726da055dcab35bc8a308af9995220a002bd575c Mon Sep 17 00:00:00 2001 From: tegwick Date: Wed, 8 Jul 2026 00:44:49 +0200 Subject: [PATCH] Fix core-hub stabilization evidence sink posting Allow persist_ops_evidence to emit State Hub progress for core-hub context sources so scheduled stabilization checks record hub-visible evidence. --- src/activity_core/ops_evidence_sinks.py | 2 +- tests/test_ops_evidence_sinks.py | 51 +++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/activity_core/ops_evidence_sinks.py b/src/activity_core/ops_evidence_sinks.py index 09101ac..9e503d0 100644 --- a/src/activity_core/ops_evidence_sinks.py +++ b/src/activity_core/ops_evidence_sinks.py @@ -36,7 +36,7 @@ def persist_ops_inventory_evidence(payload: dict[str, Any]) -> list[dict[str, An if not isinstance(source, dict): continue source_type = source.get("type") - if source_type not in {"ops-inventory", "state-hub"}: + if source_type not in {"ops-inventory", "state-hub", "core-hub"}: continue params = source.get("params") or {} diff --git a/tests/test_ops_evidence_sinks.py b/tests/test_ops_evidence_sinks.py index 413641c..f1b96c2 100644 --- a/tests/test_ops_evidence_sinks.py +++ b/tests/test_ops_evidence_sinks.py @@ -136,6 +136,57 @@ def test_state_hub_progress_sink_posts_compact_probe_summary(monkeypatch) -> Non assert "token=secret" not in serialized +def test_core_hub_stabilization_sink_posts_progress(monkeypatch) -> None: + posts: list[dict[str, Any]] = [] + + def fake_get(url: str, **kwargs: Any) -> DummyResponse: + return DummyResponse([]) + + def fake_post(url: str, **kwargs: Any) -> DummyResponse: + posts.append({"url": url, **kwargs}) + return DummyResponse({"id": "progress-core-hub-1"}) + + monkeypatch.setattr(httpx, "get", fake_get) + monkeypatch.setattr(httpx, "post", fake_post) + + result = persist_ops_inventory_evidence( + { + "activity_id": "activity-core-hub", + "run_id": "12345678-aaaa-bbbb-cccc-123456789abc", + "scheduled_for": "2026-07-07T10:15:00+00:00", + "version_used": 1, + "context_sources": [ + { + "type": "core-hub", + "query": "stabilization_check", + "bind_to": "context.core_hub_stabilization_check", + "params": { + "evidence_sinks": [ + { + "type": "state-hub-progress", + "event_type": "core_hub_stabilization_check", + "state_hub_url": "http://state-hub.test", + } + ] + }, + } + ], + "context": { + "core_hub_stabilization_check": { + "kind": "core_hub_stabilization", + "overall_pass": True, + "checks": {"widget_types_count": {"pass": True, "count": 26}}, + } + }, + } + ) + + assert result[0]["status"] == "posted" + body = posts[0]["json"] + assert body["event_type"] == "core_hub_stabilization_check" + assert "Core Hub stabilization" in body["summary"] + + def test_state_hub_progress_sink_is_idempotent(monkeypatch) -> None: idempotency_key = f"{_run_id()}:ops_probe:ops_inventory_probe"