const PASS_STATUSES = Object.freeze(["ok", "ready", "pass", "passed", "healthy", "available", "live"]); const ERROR_STATUSES = Object.freeze(["error", "failed", "failure"]); const RAW_DEGRADED_STATUSES = Object.freeze(["degraded"]); const BLOCKED_STATUSES = Object.freeze(["blocked", "unavailable", "rejected"]); const UNVERIFIED_STATUSES = Object.freeze(["", "unknown", "pending", "loading", "probing", "unverified", "not_observed"]); const RUNTIME_DURABLE_READY_QUERY_RESULTS = Object.freeze([ "durable_readiness_ready", "runtime_durable_ready", "query_ready", "readiness_ready", "ready", "ok", "pass", "passed" ]); const RUNTIME_DURABLE_BLOCKED_QUERY_RESULTS = Object.freeze({ driver_missing: "runtime_durable_adapter_driver_missing", ssl_negotiation_blocked: "runtime_durable_adapter_ssl_blocked", auth_blocked: "runtime_durable_adapter_auth_blocked", schema_blocked: "runtime_durable_adapter_schema_blocked", migration_blocked: "runtime_durable_adapter_migration_blocked", query_blocked: "runtime_durable_adapter_query_blocked", not_ready: "runtime_durable_adapter_query_blocked" }); const RUNTIME_DURABLE_GATE_LAYERS = Object.freeze(["ssl", "auth", "schema", "migration", "durability"]); const READ_ONLY_REASON_CODES = Object.freeze([ "read_only", "read-only", "readonly", "permission", "permissions", "forbidden", "unauthorized", "runtime_durable", "runtime-durable", "durability", "durable", "db_persistence", "persistence", "not-codex-stdio", "not-write-capable", "process-local-session-registry", "text-chat-only", "fallback:text-chat-only", "codex_stdio_blocked_readonly_available", "codex_stdio_blocked_readonly_session_available", "controlled_readonly_not_long_lived_stdio", "codex_cli_binary_missing", "runner_lifecycle_missing", "stdio_protocol_not_wired", "codex_stdio_supervisor_disabled", "security_blocked" ]); export function classifyWorkbenchLiveStatus(live = {}) { const probes = collectLiveStatusProbes(live); const reachable = probes.some((probe) => probe.reachable); if (!reachable) { const failedProbe = probes.find((probe) => !probe.reachable) ?? probes[0]; return statusResult({ kind: "unverified", label: "等待验证", tone: "pending", serviceId: failedProbe?.serviceId ?? "hwlab-cloud-api", apiPath: failedProbe?.apiPath ?? "/health/live", reasonCode: failedProbe?.reasonCode ?? "api_unverified", detail: failedProbe ? `等待验证:${probeAttribution(failedProbe)}。` : "等待同源 API 验证;主工作台不会把未探测状态当作通过。", probes }); } const errorProbe = probes.find((probe) => probe.kind === "error"); if (errorProbe) { return statusResult({ kind: "error", label: "API 错误", tone: "blocked", serviceId: errorProbe.serviceId, apiPath: errorProbe.apiPath, reasonCode: errorProbe.reasonCode, traceId: errorProbe.traceId, detail: `错误:${probeAttribution(errorProbe)}。`, probes }); } const readOnlyProbe = probes.find((probe) => probe.kind === "readonly"); if (readOnlyProbe) { return statusResult({ kind: "readonly", label: "只读模式", tone: "source", serviceId: readOnlyProbe.serviceId, apiPath: readOnlyProbe.apiPath, reasonCode: readOnlyProbe.reasonCode, traceId: readOnlyProbe.traceId, detail: `只读:${probeAttribution(readOnlyProbe)}。`, probes }); } const pendingProbe = probes.find((probe) => probe.kind === "unverified"); if (pendingProbe) { return statusResult({ kind: "unverified", label: "等待验证", tone: "pending", serviceId: pendingProbe.serviceId, apiPath: pendingProbe.apiPath, reasonCode: pendingProbe.reasonCode, traceId: pendingProbe.traceId, detail: `等待验证:${probeAttribution(pendingProbe)}。`, probes }); } return statusResult({ kind: "pass", label: "API 正常", tone: "dev-live", serviceId: "hwlab-cloud-api", apiPath: "/health/live", reasonCode: "ready", detail: "通过:hwlab-cloud-api /health/live ready;关键同源 API 已完成当前工作台只读验证。", probes }); } export function collectLiveStatusProbes(live = {}) { return [ classifyApiProbe(live.healthLive, { serviceId: "hwlab-cloud-api", apiPath: "/health/live", fallbackReasonCode: "health_live_unverified" }), classifyApiProbe(live.restIndex, { serviceId: "hwlab-cloud-api", apiPath: "/v1", fallbackReasonCode: "rest_index_unverified" }), classifyApiProbe(live.health, { serviceId: "hwlab-cloud-api", apiPath: "/json-rpc system.health", fallbackReasonCode: "system_health_unverified" }), classifyApiProbe(live.adapter, { serviceId: "hwlab-cloud-api", apiPath: "/json-rpc cloud.adapter.describe", fallbackReasonCode: "adapter_describe_unverified" }), classifyCodeAgentProbe(live), classifyDevicePodProbe(live) ].filter(Boolean); } function classifyDevicePodProbe(live = {}) { const probe = live.devicePodStatus ?? live.devicePods; const context = { serviceId: "hwlab-cloud-api", apiPath: "/v1/device-pods", fallbackReasonCode: "device_pod_unverified" }; if (!probe) { return unverifiedProbe({ ...context, reasonCode: context.fallbackReasonCode, reason: "Device Pod status not observed" }); } if (probe.ok !== true) { return errorProbe({ ...context, reasonCode: probe.timeout ? "timeout" : probe.status ? `HTTP ${probe.status}` : "device_pod_request_failed", reason: probe.error ?? "Device Pod status request failed", httpStatus: probe.status, traceId: traceIdFrom(probe), evidenceSummary: evidenceSummaryFrom(probe) }); } const data = probe.data ?? {}; const pod = data.devicePod ?? data.devicePods?.[0] ?? data.summary ?? {}; const blocker = data.summary?.blocker ?? pod.blocker ?? null; if (blocker) { return errorProbe({ ...context, reasonCode: blocker.code ?? "device_pod_blocked", reason: blocker.message ?? "Device Pod blocked", traceId: data.summary?.latestEvent?.refs?.traceId ?? data.events?.[0]?.refs?.traceId, evidenceSummary: devicePodEvidenceSummary(data) }); } if (["ok", "ready", "live", "pass", "healthy"].includes(String(data.status ?? pod.status ?? "").toLowerCase())) { return passProbe({ ...context, serviceId: data.serviceId ?? "hwlab-device-pod", reasonCode: "device_pod_ready", reason: `Device Pod ${pod.devicePodId ?? data.summary?.devicePodId ?? "unknown"} status ready`, evidenceSummary: devicePodEvidenceSummary(data) }); } return unverifiedProbe({ ...context, reasonCode: data.status ?? "device_pod_unverified", reason: "Device Pod status is not ready yet", evidenceSummary: devicePodEvidenceSummary(data) }); } function devicePodEvidenceSummary(data = {}) { const summary = data.summary ?? {}; const pod = data.devicePod ?? data.devicePods?.[0] ?? {}; const refs = summary.latestEvent?.refs ?? data.events?.[0]?.refs ?? pod.refs ?? {}; return [ summary.devicePodId ?? pod.devicePodId ? `pod=${summary.devicePodId ?? pod.devicePodId}` : null, summary.targetId ?? pod.targetId ?? pod.target?.targetId ? `target=${summary.targetId ?? pod.targetId ?? pod.target?.targetId}` : null, summary.profileHash ?? pod.profileHash ?? pod.profile?.profileHash ? `profile=${shortEvidenceToken(summary.profileHash ?? pod.profileHash ?? pod.profile?.profileHash)}` : null, refs.operationId ? `operation=${refs.operationId}` : null, refs.traceId ? `trace=${refs.traceId}` : null, refs.evidenceId ? `evidence=${refs.evidenceId}` : null ].filter(Boolean).join(" / "); } function shortEvidenceToken(value) { const text = String(value ?? "").trim(); if (!text) return "unknown"; return text.length > 16 ? text.slice(0, 16) : text; } function classifyApiProbe(probe, context) { if (!probe) { return unverifiedProbe({ ...context, reasonCode: context.fallbackReasonCode, reason: "not_observed" }); } if (probe.ok !== true) { return errorProbe({ ...context, reasonCode: probe.timeout ? "timeout" : probe.status ? `HTTP ${probe.status}` : context.fallbackReasonCode, reason: probe.error ?? "request_failed", httpStatus: probe.status, traceId: traceIdFrom(probe), evidenceSummary: evidenceSummaryFrom(probe) }); } const payload = probe.data; const serviceId = payload?.serviceId ?? context.serviceId; if ((context.apiPath === "/health/live" || context.apiPath === "/v1") && payload?.readiness?.codeAgent) { const codeAgentProbe = classifyStructuredCodeAgentProbe(payload.readiness.codeAgent); if (codeAgentProbe && codeAgentProbe.kind !== "pass" && codeAgentProbe.kind !== "unverified") { return { ...codeAgentProbe, rawStatus: rawStatusFrom(payload) }; } } const durableReason = durableRuntimeReason(payload); if (durableReason) { return readOnlyProbe({ ...context, serviceId, ...durableReason, rawStatus: rawStatusFrom(payload), traceId: traceIdFrom(payload), evidenceSummary: evidenceSummaryFrom(payload) }); } if (context.apiPath === "/v1" && payload?.codeAgent) { const codeAgentProbe = classifyCodeAgentProbe({ restIndex: probe }); if (codeAgentProbe && codeAgentProbe.kind !== "pass" && codeAgentProbe.kind !== "unverified") { return { ...codeAgentProbe, rawStatus: rawStatusFrom(payload) }; } } const blocker = firstBlocker(payload); if (blocker) { const reasonCode = String(blocker.code ?? blocker.reason ?? "blocked"); const reason = blocker.summary ?? blocker.message ?? blocker.reason ?? reasonCode; if (isReadOnlyReason(reasonCode) || isReadOnlyReason(reason)) { return readOnlyProbe({ ...context, serviceId, reasonCode, reason, rawStatus: rawStatusFrom(payload), traceId: traceIdFrom(payload), evidenceSummary: evidenceSummaryFrom(payload) }); } return errorProbe({ ...context, serviceId, reasonCode, reason, rawStatus: rawStatusFrom(payload), traceId: traceIdFrom(payload), evidenceSummary: evidenceSummaryFrom(payload) }); } const status = normalizedStatus(rawStatusFrom(payload)); if (ERROR_STATUSES.includes(status)) { return errorProbe({ ...context, serviceId, reasonCode: status, reason: "API returned error status", rawStatus: rawStatusFrom(payload), traceId: traceIdFrom(payload), evidenceSummary: evidenceSummaryFrom(payload) }); } if (RAW_DEGRADED_STATUSES.includes(status) || BLOCKED_STATUSES.includes(status) || readinessFalse(payload)) { const reasonCode = readinessFalse(payload) ? "ready_false_without_blocker" : status === "degraded" ? "api_degraded_without_attribution" : status; return errorProbe({ ...context, serviceId, reasonCode, reason: "API readiness is not pass and no concrete blocker was provided", rawStatus: rawStatusFrom(payload), traceId: traceIdFrom(payload), evidenceSummary: evidenceSummaryFrom(payload) }); } if (UNVERIFIED_STATUSES.includes(status)) { return unverifiedProbe({ ...context, serviceId, reasonCode: context.fallbackReasonCode, reason: "status_not_observed", rawStatus: rawStatusFrom(payload), traceId: traceIdFrom(payload), evidenceSummary: evidenceSummaryFrom(payload) }); } return passProbe({ ...context, serviceId, reasonCode: status || "ready", reason: "ready", rawStatus: rawStatusFrom(payload), traceId: traceIdFrom(payload), evidenceSummary: evidenceSummaryFrom(payload) }); } function classifyCodeAgentProbe(live = {}) { const availability = live.restIndex?.data?.codeAgent ?? live.healthLive?.data?.codeAgent; const structured = live.restIndex?.data?.readiness?.codeAgent ?? live.healthLive?.data?.readiness?.codeAgent; if (structured) return classifyStructuredCodeAgentProbe(structured); if (!availability) { return unverifiedProbe({ serviceId: "hwlab-cloud-api", apiPath: "/v1/agent/chat", reasonCode: "code_agent_unverified", reason: "availability_not_observed" }); } const serviceId = "hwlab-cloud-api"; const apiPath = availability.endpoint ?? "POST /v1/agent/chat"; const provider = availability.provider ?? "not_observed"; const backend = availability.backend ?? "not_observed"; const capability = availability.capabilityLevel ?? availability.runner?.capabilityLevel; const providerStatus = availability.error?.providerStatus ?? availability.providerStatus; const gate = availability.longLivedSessionGate; const stdio = availability.codexStdio ?? availability.codexStdioFeasibility; if (gate?.status === "pass" && stdio?.canStartLongLivedCodexStdio === true && availability.ready === true) { return passProbe({ serviceId, apiPath, reasonCode: "codex_stdio_ready", reason: `provider=codex-stdio; backend=${availability.codexStdio?.backend ?? backend}; capability=long-lived-codex-stdio-session`, traceId: traceIdFrom(availability), evidenceSummary: evidenceSummaryFrom(availability), meta: { provider: "codex-stdio", backend: availability.codexStdio?.backend ?? backend, capability: "long-lived-codex-stdio-session" } }); } if (capability === "text-chat-only" || availability.runner?.kind === "openai-responses-fallback") { return readOnlyProbe({ serviceId, apiPath, reasonCode: "fallback_text_chat_only", reason: `provider=${provider}; backend=${backend}; capability=text-chat-only`, traceId: traceIdFrom(availability), evidenceSummary: evidenceSummaryFrom(availability), meta: { provider, backend, capability } }); } if (availability.agentKind === "controlled-readonly-session-registry" || availability.partialReady === true) { return readOnlyProbe({ serviceId, apiPath, reasonCode: "codex_stdio_blocked_readonly_session_available", reason: `${availability.summary ?? "controlled-readonly-session-registry available; long-lived Codex stdio blocked"}; blockers=${blockerCodes(availability).join(",") || "not_observed"}`, traceId: traceIdFrom(availability), evidenceSummary: evidenceSummaryFrom(availability), meta: { provider, backend, capability } }); } if (capability === "read-only-session-tools") { return readOnlyProbe({ serviceId, apiPath, reasonCode: "code_agent_read_only_session_tools", reason: codeAgentReadOnlySessionToolsReason(availability), traceId: traceIdFrom(availability), evidenceSummary: evidenceSummaryFrom(availability), meta: { provider, backend, capability } }); } if (availability.status === "blocked" || availability.ready === false) { return errorProbe({ serviceId, apiPath, reasonCode: providerStatus ? `provider_http_${providerStatus}` : availability.reason ?? availability.blocker ?? "code_agent_blocked", reason: availability.summary ?? `provider=${provider}; backend=${backend}; capability=${capability ?? "unknown"}`, traceId: traceIdFrom(availability), meta: { provider, backend, capability } }); } if (availability.runner?.ready === true && availability.runner?.writeCapable === false) { return readOnlyProbe({ serviceId, apiPath, reasonCode: "codex_readonly_runner", reason: `runner=${availability.runner.kind ?? "hwlab-readonly-runner"}; capability=${capability ?? "read-only-tools"}`, traceId: traceIdFrom(availability), evidenceSummary: evidenceSummaryFrom(availability), meta: { provider, backend, capability } }); } if (availability.status === "available" || availability.ready === true) { return passProbe({ serviceId, apiPath, reasonCode: capability ?? "available", reason: `provider=${provider}; backend=${backend}`, traceId: traceIdFrom(availability), evidenceSummary: evidenceSummaryFrom(availability), meta: { provider, backend, capability } }); } return unverifiedProbe({ serviceId, apiPath, reasonCode: "code_agent_unverified", reason: `provider=${provider}; backend=${backend}`, traceId: traceIdFrom(availability), evidenceSummary: evidenceSummaryFrom(availability), meta: { provider, backend, capability } }); } function classifyStructuredCodeAgentProbe(readiness = {}) { const serviceId = "hwlab-cloud-api"; const apiPath = "POST /v1/agent/chat"; const provider = readiness.provider?.provider ?? "not_observed"; const backend = readiness.provider?.backend ?? "not_observed"; const capability = readiness.sessionRunner?.capabilityLevel ?? "not_observed"; if (structuredCodexStdioReady(readiness)) { return passProbe({ serviceId, apiPath, reasonCode: "codex_stdio_ready", reason: `provider=${provider}; backend=${backend}; capability=long-lived-codex-stdio-session`, meta: { provider, backend, capability } }); } if (readiness.sessionRunnerReady === true) { return readOnlyProbe({ serviceId, apiPath, reasonCode: readiness.codexStdio?.blocker ?? "codex_stdio_blocked_readonly_session_available", reason: `providerReady=${Boolean(readiness.providerReady)}; durableDbReady=${Boolean(readiness.durableDbReady)}; sessionRunner=${readiness.sessionRunner?.status ?? "unknown"}; codexStdio=${readiness.codexStdio?.status ?? "unknown"}; current=${currentStructuredBlockers(readiness).join(",") || "not_observed"}`, meta: { provider, backend, capability } }); } const blocker = readiness.currentBlocker ?? currentStructuredBlockers(readiness)[0] ?? "code_agent_blocked"; return errorProbe({ serviceId, apiPath, reasonCode: blocker, reason: `providerReady=${Boolean(readiness.providerReady)}; durableDbReady=${Boolean(readiness.durableDbReady)}; sessionRunnerReady=${Boolean(readiness.sessionRunnerReady)}; codexStdioFeasible=${Boolean(readiness.codexStdioFeasible)}`, meta: { provider, backend, capability } }); } function structuredCodexStdioReady(readiness = {}) { return Boolean( readiness.sessionRunnerReady === true && readiness.codexStdioFeasible === true && readiness.sessionRunner?.codexStdio === true && readiness.sessionRunner?.writeCapable === true && readiness.sessionRunner?.longLivedSession === true && readiness.sessionRunner?.capabilityLevel === "long-lived-codex-stdio-session" ); } function currentStructuredBlockers(readiness = {}) { return Array.isArray(readiness.currentBlockers) ? readiness.currentBlockers.filter(Boolean) : [readiness.currentBlocker].filter(Boolean); } function blockerCodes(availability) { const values = [ ...(Array.isArray(availability?.blockerCodes) ? availability.blockerCodes : []), ...(Array.isArray(availability?.blockers) ? availability.blockers.map((blocker) => blocker?.code) : []), ...(Array.isArray(availability?.longLivedSessionGate?.blockers) ? availability.longLivedSessionGate.blockers.map((blocker) => blocker?.code) : []), ...(Array.isArray(availability?.codexStdioFeasibility?.blockers) ? availability.codexStdioFeasibility.blockers.map((blocker) => blocker?.code) : []), availability?.runtimeContract?.binary?.status === "missing" ? "codex_cli_binary_missing" : null, availability?.runtimeContract?.lifecycleSupervisor?.status === "blocked" ? "runner_lifecycle_missing" : null, availability?.runtimeContract?.stdioProtocol?.status === "blocked" ? "stdio_protocol_not_wired" : null ].filter(Boolean); return [...new Set(values.map(String))]; } function durableRuntimeReason(payload) { if (!hasRuntimeDurableSignal(payload)) return null; const classification = classifyRuntimeDurableReadiness(payload); if (classification.ready) return null; if ( classification.status === "blocked" && ( isReadOnlyReason(classification.reasonCode) || String(classification.reasonCode).endsWith("_blocked") || normalizedStatus(classification.evidence?.blockedLayer).includes("durability") ) ) { return { reasonCode: classification.reasonCode, reason: classification.reason, layer: classification.evidence?.blockedLayer || "runtime-durable", classification }; } return null; } function hasRuntimeDurableSignal(payload = {}) { const runtime = payload?.runtime; const durability = payload?.readiness?.durability; const dbRuntimeReadiness = payload?.db?.runtimeReadiness; return Boolean( blockerCodeStartingWith(payload, "runtime_durable_adapter_") || hasOwnNonEmpty(runtime, ["adapter", "durable", "durableRequested", "ready", "blocker", "liveRuntimeEvidence", "connection", "durabilityContract", "gates"]) || hasOwnNonEmpty(durability, ["adapter", "durable", "ready", "blocker", "blockedLayer", "queryResult", "liveRuntimeEvidence", "gates"]) || hasOwnNonEmpty(dbRuntimeReadiness, ["adapter", "durable", "ready", "blocker", "blockedLayer", "queryResult", "liveRuntimeEvidence"]) ); } function hasOwnNonEmpty(object, fields) { if (!object || typeof object !== "object") return false; return fields.some((field) => Object.hasOwn(object, field) && object[field] !== undefined && object[field] !== null && object[field] !== ""); } export function classifyRuntimeDurableReadiness(payload = {}, options = {}) { const runtime = payload?.runtime ?? {}; const durability = payload?.readiness?.durability ?? {}; const dbRuntimeReadiness = payload?.db?.runtimeReadiness ?? {}; const gates = runtime?.gates ?? durability?.gates ?? {}; const gateBlocker = firstBlockedRuntimeGate(gates); const queryResult = firstNonEmpty( runtime?.connection?.queryResult, durability?.queryResult, dbRuntimeReadiness?.queryResult ); const queryBlocker = runtimeDurableBlockerFromQueryResult(queryResult); const readyQueryResult = isRuntimeDurableReadyQueryResult(queryResult); const explicitDurabilityReady = durabilityReadySignal({ runtime, durability, dbRuntimeReadiness, gateBlocker, queryResult, readyQueryResult, queryBlocker }); const directBlocker = firstNonEmpty( explicitDurabilityReady ? "" : runtime?.blocker, durability?.blocker, dbRuntimeReadiness?.blocker, explicitDurabilityReady ? "" : blockerCodeStartingWith(payload, "runtime_durable_adapter_") ); const reasonCode = firstNonEmpty(directBlocker, gateBlocker?.blocker, queryBlocker); const blockedLayer = firstNonEmpty( runtime?.durabilityContract?.blockedLayer, durability?.blockedLayer, dbRuntimeReadiness?.blockedLayer, gateBlocker?.layer, runtimeDurableLayerFromBlocker(reasonCode), runtimeDurableLayerFromQueryResult(queryResult) ); const adapter = firstNonEmpty(runtime?.adapter, durability?.adapter, dbRuntimeReadiness?.adapter, "unknown"); const runtimeDurable = runtime?.durable === true || durability?.durable === true || dbRuntimeReadiness?.durable === true; const runtimeExplicitlyNonDurable = runtime?.durable === false || durability?.durable === false || dbRuntimeReadiness?.durable === false; const runtimeReady = runtime?.ready === true || durability?.runtimeReady === true || dbRuntimeReadiness?.ready === true; const durabilityReady = durability?.ready === true || dbRuntimeReadiness?.ready === true || runtimeReady; const liveRuntimeEvidence = runtime?.liveRuntimeEvidence === true || durability?.liveRuntimeEvidence === true || dbRuntimeReadiness?.liveRuntimeEvidence === true; const rawStatus = rawStatusFrom(payload); const postgresRequired = options.requirePostgresAdapter === true; const adapterReady = !postgresRequired || adapter === "postgres"; const ready = adapterReady && runtimeDurable && runtimeReady && durabilityReady && liveRuntimeEvidence && !reasonCode && !blockedLayer && (!queryResult || readyQueryResult); if (ready) { return { status: "ready", ready: true, classification: "runtime_durable_ready", reasonCode: "runtime_durable_ready", reason: `runtime durable ready; adapter=${adapter}; queryResult=${queryResult || "not_observed"}`, impact: "Device Pod readiness checks may rely on durable runtime evidence when persistence readiness is green.", safeNextAction: "Continue with repo-owned DEV CD postflight; do not read or print Secret values.", retryable: true, readonly: false, evidence: runtimeDurableEvidence({ adapter, runtimeDurable, runtimeReady, durabilityReady, liveRuntimeEvidence, blockedLayer: null, queryResult, readyQueryResult, reasonCode: null, gates, rawStatus, postgresRequired }) }; } const nonReadyReasonCode = firstNonEmpty( reasonCode, postgresRequired && adapter !== "postgres" ? "runtime_durable_adapter_not_postgres" : "", runtimeExplicitlyNonDurable ? "runtime_durable_false" : "", runtimeDurable ? "" : "runtime_durable_adapter_missing", runtimeReady ? "" : "runtime_durable_runtime_not_ready", liveRuntimeEvidence ? "" : "runtime_durable_live_evidence_missing", isBlockedRuntimeStatus(rawStatus) ? rawStatus : "", "runtime_durable_adapter_not_ready" ); const layer = firstNonEmpty( blockedLayer, runtimeDurableLayerFromBlocker(nonReadyReasonCode), runtimeExplicitlyNonDurable ? "runtime-durable" : "", "runtime-durable" ); return { status: "blocked", ready: false, classification: nonReadyReasonCode, reasonCode: nonReadyReasonCode, reason: runtimeDurableBlockedReason({ reasonCode: nonReadyReasonCode, adapter, layer, queryResult }), impact: "Device Pod readiness remains source-level while durable runtime evidence is blocked.", safeNextAction: runtimeDurableSafeNextAction(nonReadyReasonCode, layer), retryable: true, readonly: true, evidence: runtimeDurableEvidence({ adapter, runtimeDurable, runtimeReady, durabilityReady, liveRuntimeEvidence, blockedLayer: layer, queryResult, readyQueryResult, reasonCode: nonReadyReasonCode, gates, rawStatus, postgresRequired }) }; } function durabilityReadySignal({ runtime, durability, dbRuntimeReadiness, gateBlocker, queryResult, readyQueryResult, queryBlocker }) { if (gateBlocker || queryBlocker) return false; if (queryResult && !readyQueryResult) return false; const ready = durability?.ready === true || dbRuntimeReadiness?.ready === true || runtime?.durabilityContract?.ready === true; if (!ready) return false; return !firstNonEmpty( durability?.blocker, dbRuntimeReadiness?.blocker, runtime?.durabilityContract?.blocker, durability?.blockedLayer, dbRuntimeReadiness?.blockedLayer, runtime?.durabilityContract?.blockedLayer ); } function isBlockedRuntimeStatus(status) { return [...ERROR_STATUSES, ...BLOCKED_STATUSES, ...RAW_DEGRADED_STATUSES].includes(normalizedStatus(status)); } function firstBlockedRuntimeGate(gates = {}) { for (const layer of RUNTIME_DURABLE_GATE_LAYERS) { const gate = gates?.[layer]; const status = normalizedStatus(gate?.status); if (gate?.ready === false || status === "blocked" || status === "failed") { return { layer, blocker: firstNonEmpty(gate?.blocker, runtimeDurableBlockerForLayer(layer)) }; } } return null; } function runtimeDurableBlockerForLayer(layer) { const text = normalizedStatus(layer); if (text === "ssl") return "runtime_durable_adapter_ssl_blocked"; if (text === "auth") return "runtime_durable_adapter_auth_blocked"; if (text === "schema") return "runtime_durable_adapter_schema_blocked"; if (text === "migration") return "runtime_durable_adapter_migration_blocked"; if (text === "durability" || text === "durability_query") return "runtime_durable_adapter_query_blocked"; return "runtime_durable_adapter_blocked"; } function runtimeDurableLayerFromBlocker(blocker) { const text = normalizedStatus(blocker); if (!text) return ""; if (text.includes("ssl")) return "ssl"; if (text.includes("auth")) return "auth"; if (text.includes("schema")) return "schema"; if (text.includes("migration")) return "migration"; if (text.includes("query")) return "durability_query"; if (text.includes("missing") || text.includes("unconfigured") || text.includes("driver")) return "adapter"; return ""; } function runtimeDurableLayerFromQueryResult(queryResult) { const text = normalizedStatus(queryResult); if (!text || isRuntimeDurableReadyQueryResult(text)) return ""; if (text.includes("ssl")) return "ssl"; if (text.includes("auth")) return "auth"; if (text.includes("schema")) return "schema"; if (text.includes("migration")) return "migration"; if (text.includes("query")) return "durability_query"; if (text.includes("driver")) return "adapter"; return ""; } function runtimeDurableBlockerFromQueryResult(queryResult) { const text = normalizedStatus(queryResult); if (!text || isRuntimeDurableReadyQueryResult(text)) return ""; return RUNTIME_DURABLE_BLOCKED_QUERY_RESULTS[text] ?? ""; } function isRuntimeDurableReadyQueryResult(queryResult) { const text = normalizedStatus(queryResult); return RUNTIME_DURABLE_READY_QUERY_RESULTS.includes(text); } function runtimeDurableEvidence({ adapter, runtimeDurable, runtimeReady, durabilityReady, liveRuntimeEvidence, blockedLayer, queryResult, readyQueryResult, reasonCode, gates, rawStatus, postgresRequired }) { return { adapter, durable: runtimeDurable, runtimeReady, durabilityReady, liveRuntimeEvidence, blocker: reasonCode, blockedLayer, queryResult: queryResult || null, readyQueryResult, rawStatus: rawStatus || null, postgresRequired, gates: summarizeRuntimeGateStatuses(gates), secretMaterialRead: false }; } function summarizeRuntimeGateStatuses(gates = {}) { return Object.fromEntries(RUNTIME_DURABLE_GATE_LAYERS.map((layer) => [ layer, { checked: gates?.[layer]?.checked === true, ready: gates?.[layer]?.ready === true, status: gates?.[layer]?.status ?? "unknown", blocker: gates?.[layer]?.blocker ?? null } ])); } function runtimeDurableBlockedReason({ reasonCode, adapter, layer, queryResult }) { if (reasonCode === "runtime_durable_false") { return `runtime durable=false; adapter=${adapter}; queryResult=${queryResult || "not_observed"}`; } if (reasonCode === "runtime_durable_adapter_not_postgres") { return `runtime durable adapter is not postgres; adapter=${adapter}; queryResult=${queryResult || "not_observed"}`; } return `runtime durable blocked at ${layer || "runtime-durable"}; blocker=${reasonCode}; queryResult=${queryResult || "unknown"}`; } function runtimeDurableSafeNextAction(reasonCode, layer) { const text = normalizedStatus(`${reasonCode} ${layer}`); if (text.includes("auth")) return "Repair DEV DB auth/SecretRef metadata through repo-owned provisioning, then rerun postflight without printing Secret values."; if (text.includes("schema") || text.includes("migration")) return "Run repo-owned DEV runtime provisioning and migration, then rerun postflight."; if (text.includes("ssl")) return "Align DEV DB SSL mode with the repo-owned DEV contract, then rerun postflight."; if (text.includes("query")) return "Inspect durable runtime query readiness, preserve evidence persistence, and rerun postflight."; if (text.includes("postgres")) return "Run DEV with HWLAB_CLOUD_RUNTIME_ADAPTER=postgres and DB URLs injected only through SecretRefs."; return "Restore durable runtime readiness through repo-owned DEV CD steps, then rerun postflight."; } function firstBlocker(payload) { const blockers = [ ...(Array.isArray(payload?.blockers) ? payload.blockers : []), ...(Array.isArray(payload?.readiness?.blockers) ? payload.readiness.blockers : []) ].filter(Boolean); if (blockers.length > 0) return blockers[0]; const code = firstNonEmpty( ...(Array.isArray(payload?.blockerCodes) ? payload.blockerCodes : []), ...(Array.isArray(payload?.readiness?.blockerCodes) ? payload.readiness.blockerCodes : []) ); return code ? { code, summary: code } : null; } function blockerCodeStartingWith(payload, prefix) { return [ ...(Array.isArray(payload?.blockerCodes) ? payload.blockerCodes : []), ...(Array.isArray(payload?.readiness?.blockerCodes) ? payload.readiness.blockerCodes : []) ].find((code) => String(code ?? "").startsWith(prefix)); } function readinessFalse(payload) { return [ payload?.ready, payload?.readiness?.ready, payload?.readiness?.durability?.ready, payload?.runtime?.ready ].some((value) => value === false); } function rawStatusFrom(payload) { return payload?.status ?? payload?.readiness?.status ?? payload?.runtime?.status ?? payload?.readiness?.durability?.status ?? ""; } function statusResult(result) { return { serviceId: null, apiPath: null, reasonCode: null, traceId: null, internalRawStatuses: result.probes .map((probe) => probe.rawStatus) .filter((status) => status !== undefined && status !== null && String(status).trim() !== ""), ...result }; } function passProbe(options) { return probe({ kind: "pass", reachable: true, ...options }); } function readOnlyProbe(options) { return probe({ kind: "readonly", reachable: true, ...options }); } function errorProbe(options) { return probe({ kind: "error", reachable: Boolean(options.httpStatus ? options.httpStatus >= 200 && options.httpStatus < 600 : true), ...options }); } function unverifiedProbe(options) { return probe({ kind: "unverified", reachable: false, ...options }); } function probe(options) { return { kind: options.kind, reachable: options.reachable, serviceId: options.serviceId, apiPath: options.apiPath, reasonCode: String(options.reasonCode ?? options.kind), reason: String(options.reason ?? options.reasonCode ?? options.kind), httpStatus: options.httpStatus ?? null, rawStatus: options.rawStatus ?? null, traceId: options.traceId ?? null, evidenceSummary: options.evidenceSummary ?? null, meta: options.meta ?? null }; } function probeAttribution(probe) { return [ `${probe.serviceId} ${probe.apiPath}`, probe.httpStatus ? `HTTP ${probe.httpStatus}` : null, displayReasonCode(probe.reasonCode), probe.reason && probe.reason !== probe.reasonCode ? displayReasonText(probe.reason) : null, probe.traceId ? `trace=${probe.traceId}` : null, probe.evidenceSummary ].filter(Boolean).join(" / "); } function displayReasonCode(reasonCode) { return String(reasonCode ?? ""); } function displayReasonText(reason) { return String(reason ?? "").replace(/\bruntime_durable_adapter_[a-z0-9_]+\b/giu, "runtime durable"); } function normalizedStatus(value) { return String(value ?? "").trim().toLowerCase(); } function isReadOnlyReason(value) { const text = normalizedStatus(value); return READ_ONLY_REASON_CODES.some((code) => text.includes(code)); } function codeAgentReadOnlySessionToolsReason(availability) { const flags = [ ...(Array.isArray(availability?.runnerLimitations) ? availability.runnerLimitations : []), ...(Array.isArray(availability?.runner?.limitations) ? availability.runner.limitations : []) ].filter(Boolean); const issue = firstNonEmpty(availability?.issue, availability?.trackingIssue, "#317"); return `capability=read-only-session-tools; ${issue} full pass not complete${flags.length > 0 ? `; ${flags.join(",")}` : ""}`; } function traceIdFrom(value) { return firstNonEmpty( value?.traceId, value?.meta?.traceId, value?.data?.traceId, value?.data?.meta?.traceId, value?.data?.trust?.traceId, value?.request?.traceId, value?.operation?.traceId, value?.result?.traceId, value?.trust?.traceId, value?.evidenceState?.traceId, value?.metadata?.traceId, value?.error?.traceId, value?.session?.lastTraceId, value?.session?.currentTraceId, value?.runnerTrace?.traceId, value?.providerTrace?.traceId ); } function evidenceSummaryFrom(value) { const payload = value?.data && typeof value.data === "object" ? value.data : value; const parts = [ ["operation", firstNonEmpty(payload?.operationId, payload?.operation?.operationId, payload?.result?.operationId, payload?.trust?.operationId)], ["audit", firstNonEmpty(payload?.auditId, payload?.audit?.auditId, payload?.auditEvent?.auditId, payload?.trust?.auditId)], ["evidence", firstNonEmpty(payload?.evidenceId, payload?.evidence?.evidenceId, payload?.evidenceRecord?.evidenceId, payload?.trust?.evidenceId)], ["session", firstNonEmpty(payload?.session?.sessionId, payload?.sessionId)] ] .filter(([, id]) => id) .slice(0, 4) .map(([label, id]) => `${label}=${id}`); return parts.length > 0 ? parts.join(" ") : null; } function firstNonEmpty(...values) { for (const value of values) { if (value !== undefined && value !== null && String(value).trim() !== "") return String(value).trim(); } return ""; }