fix: validate trace result provenance

This commit is contained in:
Codex Agent
2026-06-06 12:03:29 +08:00
parent 3d073fee7e
commit c80493f240
4 changed files with 78 additions and 1 deletions
+31 -1
View File
@@ -609,7 +609,7 @@ export async function loadPersistedAgentRunResult(traceId, options = {}) {
const safeId = safeTraceId(traceId);
if (!safeId || typeof options.accessController?.getAgentSessionByTraceId !== "function") return null;
const session = await options.accessController.getAgentSessionByTraceId(safeId);
const traceEvidence = agentSessionTraceEvidence(session, safeId);
const traceEvidence = validAgentSessionTraceEvidence(session, safeId);
const latestTraceId = safeTraceId(session?.lastTraceId ?? session?.session?.lastTraceId ?? session?.session?.traceId);
const topLevelAgentRun = session?.session?.agentRun && typeof session.session.agentRun === "object" ? session.session.agentRun : null;
const agentRunTraceId = safeTraceId(topLevelAgentRun?.traceId);
@@ -624,6 +624,7 @@ export async function loadPersistedAgentRunResult(traceId, options = {}) {
function persistedAgentRunResultFromSession({ traceId, session, agentRun, traceEvidence, options = {} }) {
if (!agentRun || typeof agentRun !== "object" || !agentRun.runId || !agentRun.commandId) return null;
if (!agentRunEvidenceMatchesTrace(agentRun, traceId, traceEvidence)) return null;
const status = firstNonEmpty(traceEvidence?.status, session?.status === "canceled" ? "canceled" : null, agentRun.terminalStatus, agentRun.commandState, "running");
return {
accepted: true,
@@ -767,6 +768,34 @@ function agentSessionTraceEvidence(session, traceId) {
return evidence ? { ...evidence, traceId: id } : null;
}
function validAgentSessionTraceEvidence(session, traceId) {
const evidence = agentSessionTraceEvidence(session, traceId);
if (!evidence) return null;
return agentRunEvidenceMatchesTrace(evidence.agentRun, traceId, evidence, { requireAgentRunTraceId: true }) ? evidence : null;
}
function agentRunEvidenceMatchesTrace(agentRun, traceId, traceEvidence = null, options = {}) {
const id = safeTraceId(traceId);
if (!id) return false;
const run = agentRun && typeof agentRun === "object" ? agentRun : null;
const runTraceId = safeTraceId(run?.traceId);
if (run?.commandId && runTraceId && runTraceId !== id) return false;
if (options.requireAgentRunTraceId === true && run?.commandId && runTraceId !== id) return false;
const providerTrace = run?.providerTrace && typeof run.providerTrace === "object" ? run.providerTrace : null;
const summary = traceEvidence?.traceSummary && typeof traceEvidence.traceSummary === "object" ? traceEvidence.traceSummary : null;
const summaryRun = summary?.agentRun && typeof summary.agentRun === "object" ? summary.agentRun : null;
const finalResponse = traceEvidence?.finalResponse && typeof traceEvidence.finalResponse === "object" ? traceEvidence.finalResponse : null;
const traceIds = [runTraceId, providerTrace?.traceId, summary?.traceId, finalResponse?.traceId]
.map((value) => safeTraceId(value))
.filter(Boolean);
if (traceIds.some((value) => value !== id)) return false;
const commandIds = [run?.commandId, providerTrace?.commandId, summaryRun?.commandId]
.map((value) => text(value))
.filter(Boolean);
if (commandIds.length > 1 && new Set(commandIds).size > 1) return false;
return true;
}
export function agentRunSessionEvidence(payload = {}) {
if (!payload?.agentRun) return {};
return {
@@ -785,6 +814,7 @@ export function agentRunSessionEvidence(payload = {}) {
runStatus: payload.agentRun.runStatus ?? null,
commandState: payload.agentRun.commandState ?? null,
terminalStatus: payload.agentRun.terminalStatus ?? null,
traceId: payload.agentRun.traceId ?? payload.traceId ?? payload.providerTrace?.traceId ?? null,
lastSeq: payload.agentRun.lastSeq ?? 0,
providerId: payload.agentRun.providerId ?? DEFAULT_PROVIDER_ID,
reuseEligible: payload.agentRun.reuseEligible ?? false,