feat(STATE-WP-0064): wire consistency_sweep_remote_all state-hub query

Add POST /consistency/sweep/remote-all resolver support with a 330s
timeout and k8s projection for the consistency sweep definition.
This commit is contained in:
2026-06-21 20:19:22 +02:00
parent dbd2fbb11c
commit 3a981cc98f
3 changed files with 122 additions and 2 deletions

View File

@@ -12,6 +12,7 @@ Supported queries:
- coding_retro: latest /progress/ item with event_type=coding_retro
- daily_triage_digest: curated scalar JSON digest for daily WSJF triage
- recently_on_scope_hourly: POST {STATE_HUB_URL}/recently-on-scope/hourly
- consistency_sweep_remote_all: POST {STATE_HUB_URL}/consistency/sweep/remote-all
No caching — state hub data is live operational state and must not be stale
within a single workflow run.
@@ -31,6 +32,7 @@ from activity_core.context_resolvers.base import CONTEXT_RESOLVER_REGISTRY, Cont
_DEFAULT_STATE_HUB_URL = "http://127.0.0.1:8000"
_TIMEOUT_SECONDS = 10.0
_SWEEP_TIMEOUT_SECONDS = 330.0
_OPEN_WORKSTREAM_STATUSES = {"active", "ready", "blocked"}
_OPEN_TASK_STATUSES = {"wait", "todo", "progress"}
# Sentinel age for repos that have never had an SBOM ingested. Large enough
@@ -53,13 +55,26 @@ def _fetch_json(path: str, params: dict[str, Any] | None = None) -> Any:
return {}
def _post_json(path: str, payload: dict[str, Any]) -> Any:
def _post_json(path: str, payload: dict[str, Any], *, timeout: float = _TIMEOUT_SECONDS) -> Any:
url = f"{_base_url()}{path}"
resp = httpx.post(url, json=payload, timeout=_TIMEOUT_SECONDS)
resp = httpx.post(url, json=payload, timeout=timeout)
resp.raise_for_status()
return resp.json()
def _validate_consistency_sweep_remote_all(result: Any) -> dict[str, Any]:
if not isinstance(result, dict):
raise RuntimeError("consistency_sweep_remote_all returned a non-object response")
required_keys = {"exit_code", "lock_skipped", "repos_processed"}
missing = required_keys - set(result)
if missing:
missing_list = ", ".join(sorted(missing))
raise RuntimeError(
f"consistency_sweep_remote_all response missing required key(s): {missing_list}"
)
return result
def _validate_recently_on_scope_hourly(result: Any) -> dict[str, Any]:
if not isinstance(result, dict):
raise RuntimeError("recently_on_scope_hourly returned a non-object response")
@@ -107,6 +122,18 @@ class StateHubContextResolver(ContextResolver):
}
result = _post_json("/recently-on-scope/hourly", payload)
return _validate_recently_on_scope_hourly(result)
if query == "consistency_sweep_remote_all":
payload = {
key: value
for key, value in params.items()
if key not in {"required"}
}
result = _post_json(
"/consistency/sweep/remote-all",
payload,
timeout=_SWEEP_TIMEOUT_SECONDS,
)
return _validate_consistency_sweep_remote_all(result)
return {}