Files
pikasTech-HWLAB/web/hwlab-cloud-web/scripts/live-status-contract.test.mjs
T
2026-05-23 15:30:19 +00:00

800 lines
23 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import test from "node:test";
import {
classifyRuntimeDurableReadiness,
classifyWorkbenchLiveStatus
} from "../live-status.mjs";
import { wiringPresentationFromSummary } from "../wiring-status.mjs";
const statusMatrix = JSON.parse(readFileSync(
new URL("../../../fixtures/cloud-web/durable-readiness-status-matrix.json", import.meta.url),
"utf8"
));
const okApi = Object.freeze({
ok: true,
status: 200,
data: {
serviceId: "hwlab-cloud-api",
status: "ok",
ready: true,
readiness: {
status: "ok",
ready: true,
durability: {
status: "ready",
ready: true
}
},
runtime: {
status: "ready",
durable: true,
ready: true,
liveRuntimeEvidence: true
}
}
});
const okRest = Object.freeze({
ok: true,
status: 200,
data: {
serviceId: "hwlab-cloud-api",
status: "ok",
ready: true,
readiness: {
status: "ok",
ready: true,
durability: {
status: "ready",
ready: true,
queryResult: "durable_readiness_ready"
}
},
runtime: {
adapter: "postgres",
status: "ready",
durable: true,
ready: true,
liveRuntimeEvidence: true,
connection: {
queryResult: "durable_readiness_ready"
}
},
codeAgent: {
endpoint: "POST /v1/agent/chat",
status: "available",
ready: true,
provider: "openai-responses",
backend: "hwlab-cloud-api/openai-responses",
capabilityLevel: "available"
}
}
});
const codexStdioRest = Object.freeze({
ok: true,
status: 200,
data: {
serviceId: "hwlab-cloud-api",
status: "ok",
ready: true,
readiness: {
status: "ok",
ready: true,
durability: {
status: "ready",
ready: true,
queryResult: "durable_readiness_ready"
}
},
runtime: {
adapter: "postgres",
status: "ready",
durable: true,
ready: true,
liveRuntimeEvidence: true,
connection: {
queryResult: "durable_readiness_ready"
}
},
codeAgent: {
endpoint: "POST /v1/agent/chat",
status: "codex-stdio-feasible",
ready: true,
provider: "codex-stdio",
backend: "hwlab-cloud-api/codex-mcp-stdio",
capabilityLevel: "long-lived-codex-stdio-session",
agentKind: "codex-stdio-feasible",
codexStdioFeasibility: {
canStartLongLivedCodexStdio: true
},
longLivedSessionGate: {
status: "pass",
pass: true
}
}
}
});
const readonlyOnlyRest = Object.freeze({
ok: true,
status: 200,
data: {
serviceId: "hwlab-cloud-api",
status: "degraded",
ready: false,
readiness: {
status: "ok",
ready: true,
durability: {
status: "ready",
ready: true,
queryResult: "durable_readiness_ready"
}
},
runtime: {
adapter: "postgres",
status: "ready",
durable: true,
ready: true,
liveRuntimeEvidence: true,
connection: {
queryResult: "durable_readiness_ready"
}
},
codeAgent: {
endpoint: "POST /v1/agent/chat",
status: "partial",
ready: false,
partialReady: true,
agentKind: "controlled-readonly-session-registry",
provider: "openai-responses",
backend: "hwlab-cloud-api/openai-responses",
capabilityLevel: "read-only-session-tools",
runner: {
kind: "hwlab-readonly-runner",
ready: true,
writeCapable: false
},
blockerCodes: ["codex_stdio_supervisor_disabled", "provider_token_boundary"],
codexStdioFeasibility: {
status: "blocked",
blockers: [{ code: "codex_stdio_supervisor_disabled" }]
},
longLivedSessionGate: {
status: "blocked",
pass: false
}
}
}
});
const okM3Control = Object.freeze({
ok: true,
status: 200,
data: {
status: "available",
readiness: {
status: "ready",
controlReady: true,
sourceKind: "DEV-LIVE",
evidenceLevel: "DEV-LIVE"
}
}
});
const okM3Status = Object.freeze({
ok: true,
status: 200,
data: {
status: "live",
sourceKind: "DEV-LIVE",
summary: "M3 硬件状态与可信持久化均为 DEV-LIVE。"
}
});
test("classifies fully ready workbench runtime as API 正常", () => {
const status = classifyWorkbenchLiveStatus({
healthLive: okApi,
restIndex: codexStdioRest,
health: okApi,
adapter: okApi,
m3Control: okM3Control,
m3Status: okM3Status
});
assert.equal(status.kind, "pass");
assert.equal(status.label, "API 正常");
assert.match(status.detail, /hwlab-cloud-api \/health\/live/u);
assert.equal(status.internalRawStatuses.includes("degraded"), false);
});
test("classifies controlled readonly Code Agent as read-only, not full pass", () => {
const status = classifyWorkbenchLiveStatus({
healthLive: okApi,
restIndex: readonlyOnlyRest,
health: okApi,
adapter: okApi,
m3Control: okM3Control,
m3Status: okM3Status
});
assert.equal(status.kind, "readonly");
assert.equal(status.label, "只读模式");
assert.equal(status.reasonCode, "codex_stdio_blocked_readonly_available");
assert.match(status.detail, /controlled-readonly-session-registry/u);
});
test("classifies concrete API failure with service path and HTTP status", () => {
const status = classifyWorkbenchLiveStatus({
healthLive: {
ok: false,
path: "/health/live",
status: 503,
error: "/health/live HTTP 503runtime unavailable"
},
restIndex: okRest,
health: okApi,
adapter: okApi,
m3Control: okM3Control,
m3Status: okM3Status
});
assert.equal(status.kind, "error");
assert.equal(status.label, "API 错误");
assert.equal(status.serviceId, "hwlab-cloud-api");
assert.equal(status.apiPath, "/health/live");
assert.equal(status.reasonCode, "HTTP 503");
assert.match(status.detail, /错误:hwlab-cloud-api \/health\/live \/ HTTP 503/u);
});
test("classifies durable runtime degraded as explicit read-only mode", () => {
const status = classifyWorkbenchLiveStatus({
healthLive: {
ok: true,
status: 200,
data: {
serviceId: "hwlab-cloud-api",
status: "degraded",
ready: false,
runtime: {
durable: true,
ready: false,
liveRuntimeEvidence: false,
status: "blocked",
blocker: "runtime_durable_adapter_schema_blocked",
connection: {
queryResult: "schema_blocked"
}
},
readiness: {
status: "degraded",
ready: false,
durability: {
status: "blocked",
ready: false,
blocker: "runtime_durable_adapter_schema_blocked",
blockedLayer: "schema",
queryResult: "schema_blocked"
}
},
blockerCodes: ["runtime_durable_adapter_schema_blocked"]
}
},
restIndex: okRest,
health: okApi,
adapter: okApi,
m3Control: okM3Control,
m3Status: okM3Status
});
assert.equal(status.kind, "readonly");
assert.equal(status.label, "只读模式");
assert.equal(status.reasonCode, "runtime_durable_adapter_schema_blocked");
assert.match(status.detail, /只读:hwlab-cloud-api \/health\/live/u);
assert.match(status.detail, /schema_blocked/u);
assert.deepEqual(status.internalRawStatuses.filter((item) => item === "degraded"), ["degraded"]);
});
test("does not classify ready queryResult durable runtime as blocked", () => {
const status = classifyWorkbenchLiveStatus({
healthLive: {
ok: true,
status: 200,
data: {
serviceId: "hwlab-cloud-api",
status: "ready",
ready: true,
runtime: {
adapter: "postgres",
durable: true,
ready: true,
liveRuntimeEvidence: true,
status: "ready",
blocker: null,
connection: {
queryResult: "durable_readiness_ready"
}
},
readiness: {
status: "ready",
ready: true,
durability: {
status: "ready",
ready: true,
blocker: null,
blockedLayer: null,
queryResult: "durable_readiness_ready"
}
},
blockerCodes: []
}
},
restIndex: okRest,
health: okApi,
adapter: okApi,
m3Control: okM3Control,
m3Status: okM3Status
});
assert.equal(status.kind, "pass");
assert.equal(status.reasonCode, "ready");
assert.equal(status.probes.find((probe) => probe.apiPath === "/health/live")?.reasonCode, "ready");
});
test("classifies auth and migration durable blockers with shared runtime reason", () => {
for (const [reasonCode, queryResult, blockedLayer] of [
["runtime_durable_adapter_auth_blocked", "auth_blocked", "auth"],
["runtime_durable_adapter_migration_blocked", "migration_blocked", "migration"]
]) {
const status = classifyWorkbenchLiveStatus({
healthLive: {
ok: true,
status: 200,
data: {
serviceId: "hwlab-cloud-api",
status: "degraded",
ready: false,
runtime: {
adapter: "postgres",
durable: false,
durableRequested: true,
ready: false,
liveRuntimeEvidence: false,
status: "blocked",
blocker: reasonCode,
connection: { queryResult },
durabilityContract: { blockedLayer },
gates: {
[blockedLayer]: {
checked: true,
ready: false,
status: "blocked",
blocker: reasonCode
}
}
},
readiness: {
ready: false,
status: "blocked",
durability: {
ready: false,
status: "blocked",
blocker: reasonCode,
blockedLayer,
queryResult
}
},
blockerCodes: [reasonCode]
}
},
restIndex: okRest,
health: okApi,
adapter: okApi,
m3Control: okM3Control,
m3Status: okM3Status
});
assert.equal(status.kind, "readonly");
assert.equal(status.reasonCode, reasonCode);
assert.match(status.detail, new RegExp(queryResult, "u"));
}
});
test("classifies missing probes as unverified instead of degraded", () => {
const status = classifyWorkbenchLiveStatus({});
assert.equal(status.kind, "unverified");
assert.equal(status.label, "等待验证");
assert.match(status.detail, /等待验证/u);
assert.doesNotMatch(`${status.label} ${status.detail}`, /降级/u);
});
test("classifies memory or non-durable runtime as read-only with explicit reason", () => {
const status = classifyWorkbenchLiveStatus({
healthLive: okApi,
restIndex: okRest,
health: {
ok: true,
status: 200,
data: {
serviceId: "hwlab-cloud-api",
status: "degraded",
runtime: {
adapter: "memory",
durable: false
}
}
},
adapter: okApi,
m3Control: okM3Control,
m3Status: okM3Status
});
assert.equal(status.kind, "readonly");
assert.equal(status.label, "只读模式");
assert.equal(status.reasonCode, "runtime_durable_false");
assert.match(status.detail, /runtime durable=false/u);
});
test("classifies raw degraded without durable/read-only reason as API error", () => {
const status = classifyWorkbenchLiveStatus({
healthLive: {
ok: true,
status: 200,
data: {
serviceId: "hwlab-cloud-api",
status: "degraded",
ready: false,
traceId: "trc_degraded_without_attribution"
}
},
restIndex: okRest,
health: okApi,
adapter: okApi,
m3Control: okM3Control,
m3Status: okM3Status
});
assert.equal(status.kind, "error");
assert.equal(status.label, "API 错误");
assert.equal(status.reasonCode, "ready_false_without_blocker");
assert.match(status.detail, /API readiness is not pass and no concrete blocker was provided/u);
assert.match(status.detail, /trace=trc_degraded_without_attribution/u);
assert.equal(status.internalRawStatuses.includes("degraded"), true);
assert.doesNotMatch(`${status.label} ${status.detail}`, /API 降级/u);
assert.doesNotMatch(`${status.label} ${status.detail}`, /API returned degraded/u);
});
test("classifies Code Agent provider timeout or fallback with concrete attribution", () => {
const providerTimeout = classifyWorkbenchLiveStatus({
healthLive: okApi,
restIndex: {
ok: true,
status: 200,
data: {
serviceId: "hwlab-cloud-api",
status: "ok",
ready: true,
codeAgent: {
endpoint: "POST /v1/agent/chat",
status: "blocked",
ready: false,
provider: "openai-responses",
backend: "hwlab-cloud-api/openai-responses",
traceId: "trc_provider_timeout",
error: {
providerStatus: 504
},
summary: "/v1/agent/chat timeout"
}
}
},
health: okApi,
adapter: okApi,
m3Control: okM3Control,
m3Status: okM3Status
});
assert.equal(providerTimeout.kind, "error");
assert.equal(providerTimeout.apiPath, "POST /v1/agent/chat");
assert.equal(providerTimeout.reasonCode, "provider_http_504");
assert.match(providerTimeout.detail, /hwlab-cloud-api POST \/v1\/agent\/chat/u);
assert.match(providerTimeout.detail, /trace=trc_provider_timeout/u);
const fallback = classifyWorkbenchLiveStatus({
healthLive: okApi,
restIndex: {
ok: true,
status: 200,
data: {
serviceId: "hwlab-cloud-api",
status: "ok",
ready: true,
codeAgent: {
endpoint: "POST /v1/agent/chat",
status: "available",
ready: true,
provider: "openai-responses",
backend: "hwlab-cloud-api/openai-responses",
capabilityLevel: "text-chat-only",
runner: {
kind: "openai-responses-fallback"
}
}
}
},
health: okApi,
adapter: okApi,
m3Control: okM3Control,
m3Status: okM3Status
});
assert.equal(fallback.kind, "readonly");
assert.equal(fallback.label, "只读模式");
assert.equal(fallback.reasonCode, "fallback_text_chat_only");
assert.match(fallback.detail, /capability=text-chat-only/u);
});
test("keeps ready durable runtime green while attributing read-only mode to Code Agent session-tools", () => {
const status = classifyWorkbenchLiveStatus({
healthLive: {
ok: true,
status: 200,
data: {
serviceId: "hwlab-cloud-api",
status: "ok",
ready: true,
runtime: {
status: "ready",
ready: true,
durable: true,
liveRuntimeEvidence: true,
blocker: null,
connection: {
queryResult: "durable_readiness_ready"
}
},
readiness: {
status: "ready",
ready: true,
durability: {
status: "ready",
ready: true,
runtimeStatus: "ready",
blockedLayer: null,
blocker: null,
queryResult: "durable_readiness_ready"
}
},
codeAgent: {
endpoint: "POST /v1/agent/chat",
status: "available",
ready: true,
provider: "codex-readonly-runner",
backend: "hwlab-cloud-api/controlled-readonly-session-registry",
capabilityLevel: "read-only-session-tools",
trackingIssue: "#317",
runnerLimitations: ["not-codex-stdio", "not-write-capable", "not-durable-session"]
}
}
},
restIndex: {
ok: true,
status: 200,
data: {
serviceId: "hwlab-cloud-api",
status: "ok",
ready: true,
codeAgent: {
endpoint: "POST /v1/agent/chat",
status: "available",
ready: true,
provider: "codex-readonly-runner",
backend: "hwlab-cloud-api/controlled-readonly-session-registry",
capabilityLevel: "read-only-session-tools",
trackingIssue: "#317",
runnerLimitations: ["not-codex-stdio", "not-write-capable", "not-durable-session"]
}
}
},
health: okApi,
adapter: okApi,
m3Control: okM3Control,
m3Status: okM3Status
});
assert.equal(status.kind, "readonly");
assert.equal(status.label, "只读模式");
assert.equal(status.serviceId, "hwlab-cloud-api");
assert.equal(status.apiPath, "POST /v1/agent/chat");
assert.equal(status.reasonCode, "code_agent_read_only_session_tools");
assert.match(status.detail, /capability=read-only-session-tools/u);
assert.match(status.detail, /#317 full pass not complete/u);
assert.doesNotMatch(status.detail, /runtime durable blocked/u);
assert.doesNotMatch(status.detail, /blocked at durability/u);
const healthLiveProbe = status.probes.find((probe) => probe.apiPath === "/health/live");
assert.equal(healthLiveProbe.kind, "pass");
assert.doesNotMatch(healthLiveProbe.reason, /blocked/u);
});
test("fixture matrix keeps durable_readiness_ready green and attributes read-only mode to Code Agent", () => {
const restPayload = {
serviceId: "hwlab-cloud-api",
status: "ok",
ready: true,
...statusMatrix.runtime.durableReady,
codeAgent: statusMatrix.codeAgent.readOnlySessionTools
};
const durable = classifyRuntimeDurableReadiness(restPayload);
const status = classifyWorkbenchLiveStatus({
healthLive: jsonProbe({
serviceId: "hwlab-cloud-api",
status: "ok",
ready: true,
...statusMatrix.runtime.durableReady
}),
restIndex: jsonProbe(restPayload),
health: okApi,
adapter: okApi,
m3Control: jsonProbe(statusMatrix.m3.controlReady),
m3Status: jsonProbe(statusMatrix.m3.trustedGreenSummary)
});
assert.equal(durable.ready, true);
assert.equal(durable.evidence.blocker, null);
assert.equal(durable.evidence.blockedLayer, null);
assert.equal(durable.evidence.queryResult, "durable_readiness_ready");
assert.equal(status.kind, "readonly");
assert.equal(status.reasonCode, "code_agent_read_only_session_tools");
assert.equal(status.apiPath, "POST /v1/agent/chat");
assert.match(status.detail, /#317 full pass not complete/u);
assert.doesNotMatch(status.detail, /runtime durable blocked|blocked at durability/u);
});
test("fixture matrix preserves runtime durable blocked attribution when durability is actually blocked", () => {
const status = classifyWorkbenchLiveStatus({
healthLive: jsonProbe(statusMatrix.runtime.durableQueryBlocked),
restIndex: okRest,
health: okApi,
adapter: okApi,
m3Control: okM3Control,
m3Status: okM3Status
});
const durable = classifyRuntimeDurableReadiness(statusMatrix.runtime.durableQueryBlocked);
assert.equal(durable.ready, false);
assert.equal(durable.reasonCode, "runtime_durable_adapter_query_blocked");
assert.equal(durable.evidence.blockedLayer, "durability_query");
assert.equal(status.kind, "readonly");
assert.equal(status.reasonCode, "runtime_durable_adapter_query_blocked");
assert.match(status.detail, /runtime durable/u);
assert.match(status.detail, /query_blocked/u);
});
test("fixture matrix keeps auth and schema runtime blockers on their exact layers", () => {
for (const [name, expectedReason, expectedLayer, expectedQuery] of [
["authBlocked", "runtime_durable_adapter_auth_blocked", "auth", "auth_blocked"],
["schemaBlocked", "runtime_durable_adapter_schema_blocked", "schema", "schema_blocked"]
]) {
const durable = classifyRuntimeDurableReadiness(statusMatrix.runtime[name]);
const status = classifyWorkbenchLiveStatus({
healthLive: jsonProbe(statusMatrix.runtime[name]),
restIndex: okRest,
health: okApi,
adapter: okApi,
m3Control: okM3Control,
m3Status: okM3Status
});
assert.equal(durable.reasonCode, expectedReason);
assert.equal(durable.evidence.blockedLayer, expectedLayer);
assert.equal(durable.evidence.queryResult, expectedQuery);
assert.equal(status.kind, "readonly");
assert.equal(status.reasonCode, expectedReason);
}
});
test("fixture matrix treats unknown or missing readiness as unverified, not runtime durable blocked", () => {
const status = classifyWorkbenchLiveStatus({
healthLive: jsonProbe(statusMatrix.runtime.unknownMissingReadiness)
});
assert.equal(status.kind, "unverified");
assert.equal(status.label, "等待验证");
assert.doesNotMatch(`${status.reasonCode} ${status.detail}`, /runtime durable blocked|blocked at durability/u);
});
test("fixture matrix keeps M3 trusted green summary aligned with live status and wiring presentation", () => {
const status = classifyWorkbenchLiveStatus({
healthLive: okApi,
restIndex: codexStdioRest,
health: okApi,
adapter: okApi,
m3Control: jsonProbe(statusMatrix.m3.controlReady),
m3Status: jsonProbe(statusMatrix.m3.trustedGreenSummary)
});
const wiring = wiringPresentationFromSummary(statusMatrix.m3.trustedGreenSummary);
const m3Probe = status.probes.find((probe) => probe.apiPath === "/v1/m3/status");
assert.equal(status.kind, "pass");
assert.equal(m3Probe.kind, "pass");
assert.equal(wiring.m3Live, true);
assert.equal(wiring.stateLabel, "实况已验证");
assert.equal(wiring.badgeTone, "dev-live");
});
test("classifies M3 control blockers by cloud-api/gateway/box/patch-panel layer", () => {
const status = classifyWorkbenchLiveStatus({
healthLive: okApi,
restIndex: okRest,
health: okApi,
adapter: okApi,
m3Control: {
ok: true,
status: 200,
data: {
status: "blocked",
traceId: "trc_m3_wiring_missing",
readiness: {
status: "blocked",
controlReady: false,
blocker: {
code: "m3_wiring_missing",
layer: "hwlab-patch-panel",
zh: "hwlab-patch-panel route unavailable"
}
}
}
},
m3Status: okM3Status
});
assert.equal(status.kind, "error");
assert.equal(status.serviceId, "hwlab-patch-panel");
assert.equal(status.apiPath, "/v1/m3/io");
assert.equal(status.reasonCode, "m3_wiring_missing");
assert.match(status.detail, /hwlab-patch-panel \/v1\/m3\/io/u);
assert.match(status.detail, /trace=trc_m3_wiring_missing/u);
});
test("includes trusted M3 evidence identifiers in probe attribution", () => {
const status = classifyWorkbenchLiveStatus({
healthLive: okApi,
restIndex: okRest,
health: okApi,
adapter: okApi,
m3Control: okM3Control,
m3Status: {
ok: true,
status: 200,
data: {
status: "live",
sourceKind: "DEV-LIVE",
summary: "M3 硬件状态与可信持久化均为 DEV-LIVE。",
trust: {
operationId: "op_m3_live",
traceId: "trc_m3_live",
auditId: "aud_m3_live",
evidenceId: "evd_m3_live"
}
}
}
});
const m3Probe = status.probes.find((probe) => probe.apiPath === "/v1/m3/status");
assert.equal(status.kind, "pass");
assert.match(m3Probe?.evidenceSummary ?? "", /operation=op_m3_live/u);
assert.match(m3Probe?.evidenceSummary ?? "", /audit=aud_m3_live/u);
assert.match(m3Probe?.evidenceSummary ?? "", /evidence=evd_m3_live/u);
});
function jsonProbe(data, status = 200) {
return {
ok: true,
status,
data
};
}