diff --git a/CONNECTION-MAP.md b/CONNECTION-MAP.md index d5abcca..6fc590f 100644 --- a/CONNECTION-MAP.md +++ b/CONNECTION-MAP.md @@ -45,8 +45,8 @@ | `routes/cortex_os_extension.py:17` | `api.logger` | `log = api.logger("svrnty.routes.cortex_os_extension")` | | `routes/cortex_os_extension.py:21` | `api.inject_stylesheet` | `api.inject_stylesheet(stylesheet)` | | `routes/cortex_os_extension.py:22` | `api.inject_script` | `api.inject_script(script)` | -| `routes/cortex_os_runtime_health.py:26` | `api.logger` | `log = api.logger("svrnty.routes.cortex_os_runtime_health")` | -| `routes/cortex_os_runtime_health.py:27` | `api.register_route` | `api.register_route(ROUTE_PATH, ROUTE_METHOD, _handle_runtime_health)` | +| `routes/cortex_os_runtime_health.py:30` | `api.logger` | `log = api.logger("svrnty.routes.cortex_os_runtime_health")` | +| `routes/cortex_os_runtime_health.py:31` | `api.register_route` | `api.register_route(ROUTE_PATH, ROUTE_METHOD, _handle_runtime_health)` | | `routes/transcribe.py:37` | `api.logger` | `log = api.logger("svrnty.routes.transcribe")` | | `routes/transcribe.py:38` | `api.register_route` | `api.register_route("/api/transcribe", "POST", _handle_transcribe)` | | `routes/transcribe.py:39` | `api.register_audio_attachment_processor` | `api.register_audio_attachment_processor(_transcribe_audio_attachments)` | diff --git a/routes/cortex_os_runtime_health.py b/routes/cortex_os_runtime_health.py index da93a97..07ef4ae 100644 --- a/routes/cortex_os_runtime_health.py +++ b/routes/cortex_os_runtime_health.py @@ -14,6 +14,10 @@ ROUTE_PATH = "/api/cortex-os/runtime-health" ROUTE_METHOD = "GET" CONTRACT_ID = "runtime-health/v0.1" CHECKED_AT = "2026-05-29T00:00:00Z" +SCHEMA_VERSION = "0.1.0" +HOST_RUNTIME_ID = "webui" +HOST_ADAPTER_ID = "hermes" +HOST_ADAPTER_KIND = "development_host" _FORBIDDEN_TEXT = re.compile( r"(https?://|/home/|workspaces/|\b\d{2,5}\b|token|secret|cookie|traceback|exception|\.env)", @@ -46,33 +50,77 @@ def runtime_health_payload(host_signals: dict[str, Any] | None = None) -> dict[s signals = _summarize_host_signals(host_signals or {}) status = _derive_status(signals) return { - "contract_id": CONTRACT_ID, + "schema_version": SCHEMA_VERSION, + "cortex_os_contract_id": CONTRACT_ID, + "host_runtime_id": HOST_RUNTIME_ID, + "host_adapter_id": HOST_ADAPTER_ID, + "host_adapter_kind": HOST_ADAPTER_KIND, "checked_at": CHECKED_AT, "status": status, - "readiness": "runtime_not_started", - "summary": _summary_for(status), + "readiness": "not_configured", + "signals": signals, + "display_summary": _display_summary_for(status), + "redactions": [ + {"target_path": "signals", "reason_code": "no_raw_host_payload", "label": "raw host payloads omitted"}, + {"target_path": "signals.summary", "reason_code": "path_redacted", "label": "raw paths redacted"}, + {"target_path": "signals.summary", "reason_code": "secret_redacted", "label": "secrets redacted"}, + { + "target_path": "source_trace", + "reason_code": "request_response_redacted", + "label": "request and response details omitted", + }, + ], + "warnings": [ + { + "code": "deterministic_host_surface_inputs_only", + "message": "Runtime Health uses deterministic declared host-surface inputs only.", + } + ], + "errors": [], + "source_trace": [ + { + "source_id": "runtime-health-contract", + "source_kind": "sot_document", + "label": "Runtime Health Contract", + }, + { + "source_id": "hermes-host-adapter-contract", + "source_kind": "host_adapter_contract", + "label": "Hermes Host Adapter Contract", + }, + { + "source_id": "hermes-runtime-health-slice", + "source_kind": "validator", + "label": "Hermes Runtime Health Slice", + }, + ], "authority": { - "read_only": True, + "runtime_coding": False, + "hermes_source_edits": False, + "hermes_host_adapter_authority_map": False, + "hermes_host_adapter_implementation": False, + "webui_plugin_implementation": False, + "local_json_api_route_files": False, + "local_json_api_route_handlers": False, + "browser_source": False, + "host_runtime_start": False, + "runtime_process_behavior": False, "runtime_state_mutation": False, + "product_ui_implementation": False, + "display_source": False, "tool_callable_authority": False, - "mcp_exposure": False, - "profile_exposure_change": False, + "mcp_server_runtime_behavior": False, + "mcp_tool_exposure": False, + "profile_exposure_broadening": False, "memory_domain_access": False, - "delegated_memory_grant": False, + "delegated_memory_grants": False, "sharing": False, "installer_automation": False, + "source_import": False, + "forced_internal_upstream_dependency": False, + "live_smoke_execution": False, "product_readiness_claim": False, }, - "signals": signals, - "warnings": ["deterministic_host_surface_inputs_only"], - "errors": [], - "redactions": ["host_specific_values", "raw_paths", "raw_urls", "secrets", "raw_payloads"], - "source_trace": { - "host_adapter": "hermes", - "host_surfaces": ["health", "agent_health", "dashboard_status"], - "live_probe": False, - "raw_payload_passthrough": False, - }, } @@ -80,21 +128,27 @@ def _summarize_host_signals(host_signals: dict[str, Any]) -> list[dict[str, str] names = ["health", "agent_health", "dashboard_status"] if not host_signals: return [ - {"name": name, "status": "unknown", "detail": "not_probed"} + {"signal_id": name, "state": "unknown", "summary": "not configured", "redacted": False} for name in names ] return [ - { - "name": name, - "status": _clean_status(host_signals.get(name, "unknown")), - "detail": _bounded_text(host_signals.get(f"{name}_detail", "declared_surface")), - } + _summarize_signal(name, host_signals) for name in names ] +def _summarize_signal(name: str, host_signals: dict[str, Any]) -> dict[str, Any]: + summary, redacted = _bounded_text(host_signals.get(f"{name}_detail", "declared surface")) + return { + "signal_id": name, + "state": _clean_status(host_signals.get(name, "unknown")), + "summary": summary, + "redacted": redacted, + } + + def _derive_status(signals: list[dict[str, str]]) -> str: - statuses = {signal["status"] for signal in signals} + statuses = {signal["state"] for signal in signals} if "unavailable" in statuses: return "unavailable" if "degraded" in statuses: @@ -109,23 +163,39 @@ def _clean_status(value: Any) -> str: return text if text in {"healthy", "degraded", "unavailable", "unknown"} else "unknown" -def _summary_for(status: str) -> str: +def _display_summary_for(status: str) -> dict[str, str]: if status == "healthy": - return "Runtime Health signals are healthy." + return { + "headline": "Runtime Health signals are healthy.", + "detail": "Declared Runtime Health signals are healthy.", + "severity": "ok", + } if status == "degraded": - return "Runtime Health signals are degraded." + return { + "headline": "Runtime Health signals are degraded.", + "detail": "One or more declared Runtime Health signals are degraded.", + "severity": "warning", + } if status == "unavailable": - return "Runtime Health signals are unavailable." - return "Runtime Health has not been live-probed in this slice." + return { + "headline": "Runtime Health signals are unavailable.", + "detail": "One or more declared Runtime Health signals are unavailable.", + "severity": "error", + } + return { + "headline": "Runtime Health is not configured.", + "detail": "Runtime Health has not been live-probed in this slice.", + "severity": "neutral", + } -def _bounded_text(value: Any) -> str: +def _bounded_text(value: Any) -> tuple[str, bool]: text = str(value).strip().replace("\n", " ") if not text: - return "redacted" + return "redacted", True if _FORBIDDEN_TEXT.search(text): - return "redacted" - return text[:80] + return "redacted", True + return text[:160], False def _error_envelope(code: str, message: str) -> dict[str, Any]: diff --git a/static/cortex-os/runtime-health/runtime_health.js b/static/cortex-os/runtime-health/runtime_health.js index c9795f7..7e16b18 100644 --- a/static/cortex-os/runtime-health/runtime_health.js +++ b/static/cortex-os/runtime-health/runtime_health.js @@ -21,6 +21,7 @@ panel.setAttribute("data-state", "loading"); var title = document.createElement("h2"); + title.setAttribute("data-role", "headline"); title.textContent = "Cortex OS Runtime Health"; var badge = document.createElement("span"); @@ -50,11 +51,12 @@ return panel; } - function setState(panel, state, summary, signals) { + function setState(panel, state, headline, detail, signals) { var nextState = states.indexOf(state) >= 0 ? state : "unknown"; panel.setAttribute("data-state", nextState); + panel.querySelector("[data-role='headline']").textContent = headline || "Runtime Health"; panel.querySelector("[data-role='status']").textContent = nextState; - panel.querySelector("[data-role='summary']").textContent = summary || "redacted"; + panel.querySelector("[data-role='summary']").textContent = detail || "redacted"; renderSignals(panel.querySelector("[data-role='signals']"), signals || []); } @@ -63,8 +65,11 @@ signals.slice(0, 3).forEach(function (signal) { var name = document.createElement("dt"); var value = document.createElement("dd"); - name.textContent = signal.name || "redacted"; - value.textContent = signal.status || "unknown"; + name.textContent = signal.signal_id || "redacted"; + value.textContent = signal.state || "unknown"; + if (signal.summary) { + value.setAttribute("title", signal.summary); + } list.appendChild(name); list.appendChild(value); }); @@ -72,15 +77,22 @@ function renderPayload(panel, payload) { if (!payload || payload.ok !== true || !payload.result) { - setState(panel, "error", "Runtime Health is unavailable.", []); + setState(panel, "error", "Runtime Health is unavailable.", "Runtime Health is unavailable.", []); return; } - setState(panel, payload.result.status, payload.result.summary, payload.result.signals); + var displaySummary = payload.result.display_summary || {}; + setState( + panel, + payload.result.status, + displaySummary.headline, + displaySummary.detail, + payload.result.signals, + ); } function loadRuntimeHealth() { var panel = ensurePanel(); - setState(panel, "loading", "Checking Runtime Health.", []); + setState(panel, "loading", "Cortex OS Runtime Health", "Checking Runtime Health.", []); fetch(endpoint, { method: "GET", @@ -98,7 +110,7 @@ renderPayload(panel, payload); }) .catch(function () { - setState(panel, "error", "Runtime Health is unavailable.", []); + setState(panel, "error", "Runtime Health is unavailable.", "Runtime Health is unavailable.", []); }); } diff --git a/tests/unit/test_cortex_os_runtime_health_route.py b/tests/unit/test_cortex_os_runtime_health_route.py index b6500ec..ec58d1e 100644 --- a/tests/unit/test_cortex_os_runtime_health_route.py +++ b/tests/unit/test_cortex_os_runtime_health_route.py @@ -47,10 +47,42 @@ def test_get_returns_runtime_health_envelope(): payload = handler.payload() assert handler.status_code == 200 assert payload["ok"] is True - assert payload["result"]["contract_id"] == "runtime-health/v0.1" + assert payload["result"]["schema_version"] == "0.1.0" + assert payload["result"]["cortex_os_contract_id"] == "runtime-health/v0.1" + assert payload["result"]["host_runtime_id"] == "webui" + assert payload["result"]["host_adapter_id"] == "hermes" + assert payload["result"]["host_adapter_kind"] == "development_host" + assert payload["result"]["checked_at"] == "2026-05-29T00:00:00Z" assert payload["result"]["status"] == "unknown" - assert payload["result"]["source_trace"]["live_probe"] is False + assert payload["result"]["readiness"] == "not_configured" + assert "display_summary" in payload["result"] + assert {signal["signal_id"] for signal in payload["result"]["signals"]} == { + "health", + "agent_health", + "dashboard_status", + } assert payload["result"]["authority"]["runtime_state_mutation"] is False + assert all(value is False for value in payload["result"]["authority"].values()) + + +def test_runtime_health_envelope_rejects_old_shape_fields(): + result = route.runtime_health_payload() + + forbidden_top_level = {"contract_id", "summary"} + forbidden_authority = { + "read_only", + "mcp_exposure", + "profile_exposure_change", + "delegated_memory_grant", + } + + assert forbidden_top_level.isdisjoint(result) + assert forbidden_authority.isdisjoint(result["authority"]) + assert isinstance(result["redactions"][0], dict) + assert isinstance(result["warnings"][0], dict) + assert isinstance(result["source_trace"], list) + for signal in result["signals"]: + assert {"signal_id", "state", "summary", "redacted"} == set(signal) def test_host_signal_mapping_is_closed_and_redacted(): @@ -66,11 +98,12 @@ def test_host_signal_mapping_is_closed_and_redacted(): ) assert payload["status"] == "unavailable" - assert {signal["detail"] for signal in payload["signals"]} == {"redacted"} - assert payload["source_trace"]["host_surfaces"] == [ - "health", - "agent_health", - "dashboard_status", + assert {signal["summary"] for signal in payload["signals"]} == {"redacted"} + assert {signal["redacted"] for signal in payload["signals"]} == {True} + assert [entry["source_id"] for entry in payload["source_trace"]] == [ + "runtime-health-contract", + "hermes-host-adapter-contract", + "hermes-runtime-health-slice", ] diff --git a/tests/unit/test_cortex_os_runtime_health_static.py b/tests/unit/test_cortex_os_runtime_health_static.py index c75f5a3..c2caf13 100644 --- a/tests/unit/test_cortex_os_runtime_health_static.py +++ b/tests/unit/test_cortex_os_runtime_health_static.py @@ -34,6 +34,12 @@ def test_runtime_health_display_has_no_hidden_write_surface(): "eval(", "new Function", "innerHTML", + "insertAdjacentHTML", + "outerHTML", + "DOMParser", + "template.innerHTML", + "window.location", + "createElement(\"script\"", "