fix: keep M3 ready status title honest

This commit is contained in:
unidesk-code-queue-runner
2026-05-23 08:01:07 +00:00
parent 322e3155b4
commit 4f65151b41
2 changed files with 19 additions and 1 deletions
+10 -1
View File
@@ -1252,7 +1252,7 @@ function renderM3ControlStatus() {
el.m3ControlStatus.textContent = label;
el.m3ControlStatus.className = `state-tag tone-${toneClass(tone)}`;
el.m3ControlStatus.title = operation?.blocker?.zh ?? operation?.evidenceState?.reason ?? m3ControlBlockedReason(contract);
el.m3ControlStatus.title = m3ControlStatusTitle({ operation, contract, controlReady });
const disabled = pending || !controlReady;
for (const input of [el.m3GatewaySelect, el.m3BoxSelect, el.m3PortSelect, el.m3ValueSelect, el.m3WriteDo, el.m3ReadDi]) {
input.disabled = disabled;
@@ -1268,6 +1268,15 @@ function m3ControlCanOperate(contract = state.m3Control.contract) {
contract?.readiness?.evidenceLevel === "DEV-LIVE";
}
function m3ControlStatusTitle({ operation, contract, controlReady }) {
if (operation?.blocker?.zh) return operation.blocker.zh;
if (operation?.evidenceState?.reason) return operation.evidenceState.reason;
if (controlReady) {
return "M3 IO 只读 readiness 已确认;控制仅通过 cloud-api 受控路径执行,不直连 gateway/box-simu。";
}
return m3ControlBlockedReason(contract);
}
function m3ControlBlockedReason(contract = state.m3Control.contract) {
if (!contract) return "等待 cloud-api 返回 M3 IO 只读 readiness;未确认前控制保持阻塞。";
return contract.readiness?.blocker?.zh ??
@@ -54,6 +54,7 @@ export function runM3ControlPanelGuard() {
for (const copy of [
"M3 IO 控制请求失败",
"M3 IO 只读 readiness 未 green",
"M3 IO 只读 readiness 已确认",
"受控路径受阻",
"等待 cloud-api 返回 M3 IO 只读 readiness",
"不可用时不会直连 gateway/box-simu",
@@ -135,6 +136,14 @@ function assertControlPanelSource(app) {
assert.match(canOperateBody, /readiness\?\.sourceKind === "DEV-LIVE"/u, "M3 controls must not unlock on SOURCE/DRY-RUN/BLOCKED readiness");
assert.match(canOperateBody, /readiness\?\.evidenceLevel === "DEV-LIVE"/u, "M3 controls must require live readiness evidence level");
const statusBody = functionBody(app, "renderM3ControlStatus");
assert.match(statusBody, /m3ControlStatusTitle\(\{ operation, contract, controlReady \}\)/u, "ready status title must use the control-ready-aware helper");
const statusTitleBody = functionBody(app, "m3ControlStatusTitle");
assert.match(statusTitleBody, /if \(controlReady\)/u, "ready status title must not fall through to blocked copy");
assert.match(statusTitleBody, /只读 readiness 已确认/u, "ready status title must show confirmed Chinese readiness copy");
assert.match(statusTitleBody, /return m3ControlBlockedReason\(contract\)/u, "blocked status title must still surface Chinese blocked reason");
const controlRowsBody = functionBody(app, "controlRows");
assert.match(controlRowsBody, /按钮只走受控后端/u, "control copy must describe the controlled backend route");
assert.match(controlRowsBody, /gateway-simu -> box-simu -> hwlab-patch-panel/u, "control copy must show backend-owned path");