fix: gate trusted records on durable runtime

This commit is contained in:
Code Queue Review
2026-05-22 22:52:00 +00:00
parent b775aba196
commit 363fd3a943
2 changed files with 37 additions and 4 deletions
+29 -4
View File
@@ -847,6 +847,7 @@ function normalizePort(port) {
}
function trustedM3LiveEvidenceFrom(summary) {
if (!isDurableRuntimeReady(summary)) return null;
const candidates = [
summary?.m3TrustedLoop,
summary?.m3HardwareLoop,
@@ -858,6 +859,28 @@ function trustedM3LiveEvidenceFrom(summary) {
return candidates.find(hasTrustedM3LiveEvidence) ?? null;
}
function liveRecordTone(record, live) {
const runtimeSummary = runtimeSummaryFrom(live);
return isDurableRuntimeReady(runtimeSummary) && hasTrustedM3LiveEvidence(record) ? "dev-live" : "blocked";
}
function liveRecordDurabilityBlocker(live) {
const runtimeSummary = runtimeSummaryFrom(live);
if (isDurableRuntimeReady(runtimeSummary)) return null;
if (runtimeSummary?.durable !== true) {
return "runtime.durable=false;只读 audit/evidence 不能标为 durable ready 或 DEV-LIVE。";
}
return `runtime durable adapter 未 readystatus=${runtimeSummary?.status ?? "unknown"});可信记录保持 BLOCKED。`;
}
function isDurableRuntimeReady(summary) {
if (!summary || typeof summary !== "object") return false;
if (summary.durable !== true) return false;
if (summary.ready === false) return false;
if (summary.liveRuntimeEvidence !== true) return false;
return !["blocked", "degraded", "failed"].includes(String(summary.status ?? "").toLowerCase());
}
function hasTrustedM3LiveEvidence(candidate) {
if (!candidate || typeof candidate !== "object") return false;
if (candidate.dryRun === true || candidate.fixture === true || candidate.sourceKind === "SOURCE" || candidate.sourceKind === "DRY-RUN") return false;
@@ -1053,7 +1076,7 @@ function auditRecordCards(live) {
tone: "source"
}));
} else {
cards.push(...liveEvents.map((event) => auditCard(event, hasTrustedM3LiveEvidence(event) ? "dev-live" : "blocked")));
cards.push(...liveEvents.map((event) => auditCard(event, liveRecordTone(event, live), liveRecordDurabilityBlocker(live))));
}
} else {
cards.push(liveFailureCard("audit.event.query", live.audit.error));
@@ -1082,7 +1105,7 @@ function evidenceRecordCards(live) {
tone: "source"
}));
} else {
cards.push(...liveRecords.map((record) => evidenceCard(record, hasTrustedM3LiveEvidence(record) ? "dev-live" : "blocked")));
cards.push(...liveRecords.map((record) => evidenceCard(record, liveRecordTone(record, live), liveRecordDurabilityBlocker(live))));
}
} else {
cards.push(liveFailureCard("evidence.record.query", live.evidence.error));
@@ -1099,11 +1122,12 @@ function evidenceRecordCards(live) {
return cards;
}
function auditCard(event, tone) {
function auditCard(event, tone, durabilityBlocker = null) {
return infoCard({
title: event.auditId,
detail: [
sourceKindLabel(tone),
durabilityBlocker,
tone === "blocked" ? "只读 audit 缺少 M3 patch-panel live report / operation / trace / evidence 绑定" : null,
recordField("action", event.action),
recordField("target", event.targetId),
@@ -1115,11 +1139,12 @@ function auditCard(event, tone) {
});
}
function evidenceCard(record, tone) {
function evidenceCard(record, tone, durabilityBlocker = null) {
return infoCard({
title: record.evidenceId,
detail: [
sourceKindLabel(tone),
durabilityBlocker,
tone === "blocked" ? "只读 evidence 缺少 M3 patch-panel live report / operation / trace / audit 绑定" : null,
recordKindLabel(record.kind ?? "record"),
recordField("operation", record.operationId),
+8
View File
@@ -52,6 +52,7 @@ const requiredTrustedRecordTerms = Object.freeze([
"conversationId、traceId 和 messageId",
"provider/model/trace/conversation",
"失败原因=",
"runtime.durable=false;只读 audit/evidence 不能标为 durable ready 或 DEV-LIVE。",
"只读 audit 缺少 M3 patch-panel live report / operation / trace / evidence 绑定",
"只读 evidence 缺少 M3 patch-panel live report / operation / trace / audit 绑定",
"当前显示 SOURCE 回退,不能冒充 DEV-LIVE"
@@ -128,6 +129,13 @@ assert.match(app, /function auditRecordCards/);
assert.match(app, /function evidenceRecordCards/);
assert.match(app, /function auditCard/);
assert.match(app, /function evidenceCard/);
assert.match(app, /function liveRecordTone/);
assert.match(app, /function liveRecordDurabilityBlocker/);
assert.match(app, /function isDurableRuntimeReady/);
assert.match(app, /runtimeSummary\?\.durable !== true/);
assert.match(app, /summary\.liveRuntimeEvidence !== true/);
assert.match(app, /auditCard\(event, liveRecordTone\(event, live\), liveRecordDurabilityBlocker\(live\)\)/);
assert.match(app, /evidenceCard\(record, liveRecordTone\(record, live\), liveRecordDurabilityBlocker\(live\)\)/);
assert.match(app, /function recordGroup/);
assert.match(app, /function recordField/);
assert.match(app, /function sourceKindLabel/);