// SPEC: PJ2026-01040111 long-running Workbench observation.
// Responsibility: Timing, trace-order, Code Agent card, and report-rendering source for the offline web-probe observe analyzer.
export function nodeWebObserveAnalyzerTimingSource(): string {
  return String.raw`function buildTurnTimingTable(samples, timeline) {
  const columns = [];
  const registry = new Map();
  const promptAssignmentByKey = new Map();
  const rows = [];
  for (let index = 0; index < samples.length; index += 1) {
    const sample = samples[index];
    const timelineItem = timeline[index] || {};
    const cells = {};
    const rawMetrics = turnMetricItems(sample, timelineItem);
    const domIndexes = rawMetrics.map((item) => Number(item.domIndex)).filter(Number.isFinite);
    const maxDomIndex = domIndexes.length > 0 ? Math.max(...domIndexes) : null;
    for (const rawMetric of rawMetrics) {
      const scopedKey = turnTimingScopedMetricKey(rawMetric, sample);
      const samplePromptIndex = Number(timelineItem.promptIndex ?? 0);
      const evidencePromptIndex = inferTurnMetricPromptIndex(rawMetric, samplePromptIndex, maxDomIndex);
      if (evidencePromptIndex !== null) {
        const existingPromptIndex = promptAssignmentByKey.get(scopedKey);
        if (existingPromptIndex === undefined || evidencePromptIndex > existingPromptIndex) promptAssignmentByKey.set(scopedKey, evidencePromptIndex);
      }
      const assignedPromptIndex = promptAssignmentByKey.get(scopedKey) ?? null;
      const metric = { ...rawMetric, key: scopedKey, baseKey: rawMetric.key, promptIndex: assignedPromptIndex, samplePromptIndex, pageEpoch: Number(sample?.pageEpoch ?? rawMetric.pageEpoch ?? 0) || 0 };
      let column = registry.get(metric.key);
      if (!column) {
        column = {
          id: "T" + String(columns.length + 1),
          label: "T" + String(columns.length + 1),
          keyHash: sha256(metric.key),
          source: metric.source,
          firstSeq: sample.seq ?? null,
          firstTs: sample.ts ?? null,
          lastSeq: sample.seq ?? null,
          lastTs: sample.ts ?? null,
          promptIndex: metric.promptIndex ?? null,
          lastPromptIndex: metric.promptIndex ?? null,
          traceId: metric.traceId ?? null,
          messageId: metric.messageId ?? null,
          domIndex: metric.domIndex ?? null,
          pageRole: metric.pageRole ?? sample.pageRole ?? null,
          pageId: metric.pageId ?? sample.pageId ?? null,
          pageEpoch: metric.pageEpoch ?? null
        };
        registry.set(metric.key, column);
        columns.push(column);
      } else {
        column.lastSeq = sample.seq ?? null;
        column.lastTs = sample.ts ?? null;
        if (column.source !== "turn" && metric.source === "turn") column.source = "turn";
        if (metric.promptIndex && column.promptIndex !== metric.promptIndex) column.promptIndex = metric.promptIndex;
        column.lastPromptIndex = metric.promptIndex ?? column.lastPromptIndex ?? null;
        if (!column.traceId && metric.traceId) column.traceId = metric.traceId;
        if (!column.messageId && metric.messageId) column.messageId = metric.messageId;
      }
      cells[column.id] = {
        totalElapsedSeconds: metric.totalElapsedSeconds,
        recentUpdateSeconds: metric.recentUpdateSeconds,
        status: metric.status ?? null,
        promptIndex: metric.promptIndex ?? null,
        source: metric.source,
        pageRole: metric.pageRole ?? sample.pageRole ?? null,
        pageId: metric.pageId ?? sample.pageId ?? null,
        pageEpoch: metric.pageEpoch ?? null,
        sampleGroupSeq: sample.sampleGroupSeq ?? null,
        traceId: metric.traceId ?? null,
        messageId: metric.messageId ?? null,
        textHash: metric.textHash ?? null,
        samplePromptIndex: metric.samplePromptIndex ?? null
      };
    }
    rows.push({
      ts: sample.ts ?? null,
      seq: sample.seq ?? null,
      sampleGroupSeq: sample.sampleGroupSeq ?? null,
      pageRole: sample.pageRole ?? null,
      pageId: sample.pageId ?? null,
      pageEpoch: Number(sample?.pageEpoch ?? 0) || 0,
      promptIndex: timelineItem.promptIndex ?? 0,
      routeSessionId: sample.routeSessionId ?? null,
      activeSessionId: sample.activeSessionId ?? null,
      cells
    });
  }
  const timingEvents = detectTurnTimingNonMonotonic(columns, rows);
  return {
    columns,
    rows,
    nonMonotonic: timingEvents.anomalies,
    elapsedZeroResets: timingEvents.elapsedZeroResets,
    totalElapsedForwardJumps: timingEvents.totalElapsedForwardJumps,
    terminalElapsedGrowth: timingEvents.terminalElapsedGrowth,
    terminalElapsedCorrections: timingEvents.terminalElapsedCorrections,
    recentUpdateResets: timingEvents.recentUpdateResets,
    recentUpdateSteps: timingEvents.recentUpdateSteps
  };
}

function turnTimingScopedMetricKey(metric, sample) {
  return [
    metric?.key ?? "unknown",
    metric?.pageRole ?? sample?.pageRole ?? "unknown-role",
    metric?.pageId ?? sample?.pageId ?? "unknown-page",
    Number(sample?.pageEpoch ?? metric?.pageEpoch ?? 0) || 0
  ].join("|page:");
}

function inferTurnMetricPromptIndex(metric, samplePromptIndex, maxDomIndex) {
  const promptIndex = Number(samplePromptIndex);
  if (!Number.isFinite(promptIndex) || promptIndex <= 0) return null;
  if (metric?.source === "aggregate") return promptIndex;
  if (isActiveTurnStatus(metric?.status)) return promptIndex;
  const domIndex = Number(metric?.domIndex);
  if (!isTerminalTurnStatus(metric?.status) && Number.isFinite(domIndex) && Number.isFinite(maxDomIndex) && domIndex === maxDomIndex && metric?.recentUpdateSeconds !== null && metric?.recentUpdateSeconds !== undefined) return promptIndex;
  return null;
}

function detectTurnTimingNonMonotonic(columns, rows) {
  const anomalies = [];
  const elapsedZeroResets = [];
  const totalElapsedForwardJumps = [];
  const terminalElapsedGrowth = [];
  const terminalElapsedCorrections = [];
  const recentUpdateResets = [];
  const recentUpdateSteps = [];
  for (const column of columns) {
    const previousByMetric = new Map();
    let previousTerminalTotal = null;
    for (const row of rows) {
      const cell = row.cells?.[column.id];
      if (!cell) continue;
      for (const metric of ["totalElapsedSeconds", "recentUpdateSeconds"]) {
        const value = cell[metric];
        if (value === null || value === undefined || !Number.isFinite(Number(value))) continue;
        const current = Number(value);
        const previous = previousByMetric.get(metric);
        if (previous && metric === "totalElapsedSeconds" && current < previous.value) {
          const anomaly = previous.value > 0 && current === 0 ? "zero-reset" : "decrease";
          const terminalTransition = !isTerminalTurnStatus(previous.status) && isTerminalTurnStatus(cell.status);
          const dropSeconds = previous.value - current;
          const allowedDropSeconds = Math.max(1, Number(alertThresholds?.turnTimingSampleSlackSeconds || 0));
          const event = {
            columnId: column.id,
            columnLabel: column.label,
            ...timingFindingMeta("dom-card-total-elapsed-sequence", timingStatusFromTurnStatus(cell.status ?? previous.status), {
              cardElapsedSource: cell.source ?? column.source ?? "dom-card",
            }),
            metric,
            anomaly,
            expectedPattern: anomaly === "zero-reset" ? "total-elapsed-should-not-return-to-zero" : "total-elapsed-monotonic",
            fromSeq: previous.seq,
            fromTs: previous.ts,
            fromValue: previous.value,
            fromStatus: previous.status ?? null,
            toSeq: row.seq ?? null,
            toTs: row.ts ?? null,
            toValue: current,
            toStatus: cell.status ?? null,
            delta: current - previous.value,
            traceId: cell.traceId ?? column.traceId ?? null,
            messageId: cell.messageId ?? column.messageId ?? null,
            promptIndex: cell.promptIndex ?? null,
            samplePromptIndex: row.promptIndex ?? null,
            source: cell.source ?? column.source ?? null,
            pageRole: cell.pageRole ?? column.pageRole ?? null,
            pageId: cell.pageId ?? column.pageId ?? null,
            pageEpoch: cell.pageEpoch ?? row.pageEpoch ?? column.pageEpoch ?? null,
            valuesRedacted: true
          };
          if (terminalTransition && anomaly === "decrease" && dropSeconds <= allowedDropSeconds) {
            terminalElapsedCorrections.push({
              ...event,
              anomaly: "terminal-boundary-correction",
              expectedPattern: "terminal-sealed-duration-may-correct-running-elapsed-within-slack",
              allowedDropSeconds,
            });
          } else {
            anomalies.push(event);
            if (anomaly === "zero-reset") elapsedZeroResets.push(event);
          }
        }
        if (previous && metric === "totalElapsedSeconds" && current > previous.value) {
          const sampleDeltaSeconds = elapsedSecondsBetween(previous.ts, row.ts);
          const delta = current - previous.value;
          const allowedIncreaseSeconds = sampleDeltaSeconds + alertThresholds.turnTimingSampleSlackSeconds;
          const terminalTransition = !isTerminalTurnStatus(previous.status) && isTerminalTurnStatus(cell.status);
          if (delta > allowedIncreaseSeconds && !terminalTransition) {
            totalElapsedForwardJumps.push({
              columnId: column.id,
              columnLabel: column.label,
              ...timingFindingMeta("dom-card-total-elapsed-sequence", timingStatusFromTurnStatus(cell.status ?? previous.status), {
                cardElapsedSource: cell.source ?? column.source ?? "dom-card",
              }),
              metric,
              anomaly: "forward-jump",
              expectedPattern: "total-elapsed-increase-should-match-browser-sample-interval",
              fromSeq: previous.seq,
              fromTs: previous.ts,
              fromValue: previous.value,
              fromStatus: previous.status ?? null,
              toSeq: row.seq ?? null,
              toTs: row.ts ?? null,
              toValue: current,
              toStatus: cell.status ?? null,
              delta,
              sampleDeltaSeconds,
              allowedIncreaseSeconds,
              excessiveIncreaseSeconds: Number((delta - allowedIncreaseSeconds).toFixed(3)),
              traceId: cell.traceId ?? column.traceId ?? null,
              messageId: cell.messageId ?? column.messageId ?? null,
              promptIndex: cell.promptIndex ?? null,
              samplePromptIndex: row.promptIndex ?? null,
              source: cell.source ?? column.source ?? null,
              pageRole: cell.pageRole ?? column.pageRole ?? null,
              pageId: cell.pageId ?? column.pageId ?? null,
              pageEpoch: cell.pageEpoch ?? row.pageEpoch ?? column.pageEpoch ?? null,
              valuesRedacted: true
            });
          }
        }
        if (metric === "totalElapsedSeconds" && isTerminalTurnStatus(cell.status)) {
          if (previousTerminalTotal && current > previousTerminalTotal.value) {
            terminalElapsedGrowth.push({
              columnId: column.id,
              columnLabel: column.label,
              ...timingFindingMeta("terminal-card-total-elapsed-seal", timingStatusFromTurnStatus(cell.status, "business-turn-completed"), {
                cardElapsedSource: cell.source ?? column.source ?? "dom-card",
              }),
              metric,
              anomaly: "terminal-growth",
              expectedPattern: "terminal-total-elapsed-sealed",
              fromSeq: previousTerminalTotal.seq,
              fromTs: previousTerminalTotal.ts,
              fromValue: previousTerminalTotal.value,
              fromStatus: previousTerminalTotal.status,
              toSeq: row.seq ?? null,
              toTs: row.ts ?? null,
              toValue: current,
              toStatus: cell.status ?? null,
              delta: current - previousTerminalTotal.value,
              traceId: cell.traceId ?? column.traceId ?? null,
              messageId: cell.messageId ?? column.messageId ?? null,
              promptIndex: cell.promptIndex ?? null,
              samplePromptIndex: row.promptIndex ?? null,
              source: cell.source ?? column.source ?? null,
              pageRole: cell.pageRole ?? column.pageRole ?? null,
              pageId: cell.pageId ?? column.pageId ?? null,
              pageEpoch: cell.pageEpoch ?? row.pageEpoch ?? column.pageEpoch ?? null,
              valuesRedacted: true
            });
          }
          previousTerminalTotal = { value: current, seq: row.seq ?? null, ts: row.ts ?? null, status: cell.status ?? null };
        }
        if (previous && metric === "recentUpdateSeconds") {
          const elapsedMs = Date.parse(String(row.ts ?? "")) - Date.parse(String(previous.ts ?? ""));
          const elapsedSeconds = Number.isFinite(elapsedMs) && elapsedMs >= 0 ? elapsedMs / 1000 : null;
          const increase = current - previous.value;
          const allowedIncrease = elapsedSeconds === null
            ? alertThresholds.turnTimingSampleSlackSeconds
            : Math.max(alertThresholds.turnTimingSampleSlackSeconds, elapsedSeconds + alertThresholds.turnTimingSampleSlackSeconds);
          const excessiveIncrease = increase > allowedIncrease ? increase - allowedIncrease : 0;
          recentUpdateSteps.push({
            columnId: column.id,
            columnLabel: column.label,
            metric: "recentUpdateSeconds",
            event: increase < 0 ? "reset" : excessiveIncrease > 0 ? "jump" : "increase",
            expectedPattern: "sawtooth-increase-or-reset",
            fromSeq: previous.seq,
            fromTs: previous.ts,
            fromValue: previous.value,
            toSeq: row.seq ?? null,
            toTs: row.ts ?? null,
            toValue: current,
            delta: increase,
            sampleDeltaSeconds: elapsedSeconds,
            allowedIncreaseSeconds: allowedIncrease,
            excessiveIncreaseSeconds: excessiveIncrease,
            traceId: cell.traceId ?? column.traceId ?? null,
            messageId: cell.messageId ?? column.messageId ?? null,
            promptIndex: cell.promptIndex ?? null,
            samplePromptIndex: row.promptIndex ?? null,
            source: cell.source ?? column.source ?? null,
            pageRole: cell.pageRole ?? column.pageRole ?? null,
            pageId: cell.pageId ?? column.pageId ?? null,
            pageEpoch: cell.pageEpoch ?? row.pageEpoch ?? column.pageEpoch ?? null,
            valuesRedacted: true
          });
          if (increase < 0) {
            recentUpdateResets.push({
              columnId: column.id,
              columnLabel: column.label,
              metric: "recentUpdateSeconds",
              event: "reset",
              fromSeq: previous.seq,
              fromTs: previous.ts,
              fromValue: previous.value,
              toSeq: row.seq ?? null,
              toTs: row.ts ?? null,
              toValue: current,
              delta: increase,
              sampleDeltaSeconds: elapsedSeconds,
              traceId: cell.traceId ?? column.traceId ?? null,
              messageId: cell.messageId ?? column.messageId ?? null,
              promptIndex: cell.promptIndex ?? null,
              samplePromptIndex: row.promptIndex ?? null,
              source: cell.source ?? column.source ?? null,
              pageRole: cell.pageRole ?? column.pageRole ?? null,
              pageId: cell.pageId ?? column.pageId ?? null,
              pageEpoch: cell.pageEpoch ?? row.pageEpoch ?? column.pageEpoch ?? null,
              valuesRedacted: true
            });
          }
          if (excessiveIncrease > 0) {
            anomalies.push({
              columnId: column.id,
              columnLabel: column.label,
              metric: "recentUpdateSeconds",
              anomaly: "jump",
              expectedPattern: "sawtooth-increase-or-reset",
              fromSeq: previous.seq,
              fromTs: previous.ts,
              fromValue: previous.value,
              toSeq: row.seq ?? null,
              toTs: row.ts ?? null,
              toValue: current,
              delta: increase,
              sampleDeltaSeconds: elapsedSeconds,
              allowedIncreaseSeconds: allowedIncrease,
              excessiveIncreaseSeconds: excessiveIncrease,
              traceId: cell.traceId ?? column.traceId ?? null,
              messageId: cell.messageId ?? column.messageId ?? null,
              promptIndex: cell.promptIndex ?? null,
              samplePromptIndex: row.promptIndex ?? null,
              source: cell.source ?? column.source ?? null,
              pageRole: cell.pageRole ?? column.pageRole ?? null,
              pageId: cell.pageId ?? column.pageId ?? null,
              pageEpoch: cell.pageEpoch ?? row.pageEpoch ?? column.pageEpoch ?? null,
              valuesRedacted: true
            });
          }
        }
        previousByMetric.set(metric, { value: current, seq: row.seq ?? null, ts: row.ts ?? null, status: cell.status ?? null });
      }
    }
  }
  return { anomalies, elapsedZeroResets, totalElapsedForwardJumps, terminalElapsedGrowth, terminalElapsedCorrections, recentUpdateResets, recentUpdateSteps };
}

function elapsedSecondsBetween(fromTs, toTs) {
  const from = Date.parse(fromTs);
  const to = Date.parse(toTs);
  if (!Number.isFinite(from) || !Number.isFinite(to) || to < from) return 0;
  return Number(((to - from) / 1000).toFixed(3));
}

function maxPositiveDelta(items) {
  const values = (Array.isArray(items) ? items : [])
    .map((item) => Number(item.delta))
    .filter((value) => Number.isFinite(value) && value > 0);
  return values.length > 0 ? Math.max(...values) : 0;
}

function isTerminalTurnStatus(value) {
  const status = String(value ?? "").trim().toLowerCase().replace(/_/gu, "-");
  return ["completed", "succeeded", "success", "failed", "error", "blocked", "timeout", "canceled", "cancelled", "stale", "done", "terminal", "thread-resume-failed"].includes(status);
}



function buildTraceOrderMetrics(samples, timeline) {
  const rows = [];
  const orderAnomalies = [];
  const completionNotLast = [];
  const groups = new Map();
  for (let sampleIndex = 0; sampleIndex < samples.length; sampleIndex += 1) {
    const sample = samples[sampleIndex] || {};
    const sampleRows = traceTimingRowsForSample(sample, timeline[sampleIndex] || {});
    for (const row of sampleRows) {
      const normalized = {
        ...row,
        sampleIndex,
        sampleSeq: sample.seq ?? null,
        timestamp: sample.ts || sample.timestamp || sample.collectedAt || sample.time || null,
        pageRole: row.pageRole || sample.pageRole || sample.role || sample.contextRole || null,
        pageId: row.pageId || sample.pageId || sample.contextId || null,
        sessionId: row.sessionId || sample.sessionId || sample.workbenchSessionId || null,
      };
      rows.push(normalized);
      const key = traceRowGroupKey(normalized);
      if (!groups.has(key)) groups.set(key, []);
      groups.get(key).push(normalized);
    }
  }
  const slackSeconds = Math.max(1, Number(alertThresholds?.turnTimingSampleSlackSeconds || 0));
  for (const groupRows of groups.values()) {
    const sorted = groupRows.slice().sort((a, b) => {
      if (a.sampleIndex !== b.sampleIndex) return a.sampleIndex - b.sampleIndex;
      return (a.rowIndex ?? 0) - (b.rowIndex ?? 0);
    });
    let previous = null;
    for (const row of sorted) {
      if (previous) {
        const reasons = [];
        if (Number.isFinite(previous.totalSeconds) && Number.isFinite(row.totalSeconds) && row.totalSeconds + slackSeconds < previous.totalSeconds) {
          reasons.push('total-decreased');
        }
        if (Number.isFinite(previous.projectedSeq) && Number.isFinite(row.projectedSeq) && row.projectedSeq < previous.projectedSeq) {
          reasons.push('projected-seq-decreased');
        }
        if (Number.isFinite(previous.clockSeconds) && Number.isFinite(row.clockSeconds)) {
          const diff = previous.clockSeconds - row.clockSeconds;
          if (diff > slackSeconds && diff < 43200) reasons.push('clock-decreased');
        }
        if (Number.isFinite(previous.timestampMs) && Number.isFinite(row.timestampMs) && row.timestampMs + slackSeconds * 1000 < previous.timestampMs) {
          reasons.push('timestamp-decreased');
        }
        if (reasons.length) {
          orderAnomalies.push({
            sampleIndex: row.sampleIndex,
            sampleSeq: row.sampleSeq,
            timestamp: row.timestamp,
            pageRole: row.pageRole,
            pageId: row.pageId,
            sessionId: row.sessionId,
            traceId: row.traceId || previous.traceId || null,
            previousRowIndex: previous.rowIndex,
            currentRowIndex: row.rowIndex,
            reasons,
            previousTotalSeconds: previous.totalSeconds,
            currentTotalSeconds: row.totalSeconds,
            previousProjectedSeq: previous.projectedSeq,
            currentProjectedSeq: row.projectedSeq,
            previousSourceSeq: previous.sourceSeq,
            currentSourceSeq: row.sourceSeq,
            previousEventSeq: previous.eventSeq,
            currentEventSeq: row.eventSeq,
            previousClockSeconds: previous.clockSeconds,
            currentClockSeconds: row.clockSeconds,
            previousTimestampMs: previous.timestampMs,
            currentTimestampMs: row.timestampMs,
            previousPreview: previous.preview,
            currentPreview: row.preview,
          });
        }
      }
      previous = row;
    }
    for (let index = 0; index < sorted.length; index += 1) {
      const row = sorted[index];
      if (!row.isCompletion) continue;
      const later = sorted.slice(index + 1).find((candidate) => {
        if (candidate.isCompletion && candidate.preview === row.preview) return false;
        return Number.isFinite(candidate.totalSeconds) || Number.isFinite(candidate.clockSeconds) || Number.isFinite(candidate.projectedSeq);
      });
      if (later) {
        completionNotLast.push({
          sampleIndex: row.sampleIndex,
          sampleSeq: row.sampleSeq,
          timestamp: row.timestamp,
          pageRole: row.pageRole,
          pageId: row.pageId,
          sessionId: row.sessionId,
          traceId: row.traceId || later.traceId || null,
          completionRowIndex: row.rowIndex,
          laterRowIndex: later.rowIndex,
          completionTotalSeconds: row.totalSeconds,
          laterTotalSeconds: later.totalSeconds,
          completionProjectedSeq: row.projectedSeq,
          laterProjectedSeq: later.projectedSeq,
          completionSourceSeq: row.sourceSeq,
          laterSourceSeq: later.sourceSeq,
          completionEventSeq: row.eventSeq,
          laterEventSeq: later.eventSeq,
          completionPreview: row.preview,
          laterPreview: later.preview,
        });
      }
    }
  }
  return {
    summary: {
      sampleCount: samples.length,
      traceRowCount: rows.length,
      orderAnomalyCount: orderAnomalies.length,
      completionNotLastCount: completionNotLast.length,
    },
    rows: rows.slice(0, 200),
    orderAnomalies: orderAnomalies.slice(0, 100),
    completionNotLast: completionNotLast.slice(0, 100),
  };
}

function buildCodeAgentCardDurationUnderreportedMetrics(samples, timeline) {
  const findings = [];
  const slackSeconds = Math.max(5, Number(alertThresholds?.turnTimingSampleSlackSeconds || 0));
  for (let sampleIndex = 0; sampleIndex < samples.length; sampleIndex += 1) {
    const sample = samples[sampleIndex] || {};
    const cards = codeAgentCardsForSample(sample);
    if (!cards.length) continue;
    const traceRows = traceTimingRowsForSample(sample, timeline[sampleIndex] || {});
    const terminalCards = cards.filter((card) => isCodeAgentCardTerminal(card));
    const sampleText = sampleVisibleText(sample, timeline[sampleIndex] || {});
    for (const card of terminalCards) {
      const cardText = codeAgentCardText(card);
      const parsedCardSeconds = parseTotalElapsedSeconds(cardText).filter(Number.isFinite);
      const cardSeconds = Number.isFinite(Number(card.totalElapsedSeconds)) ? Number(card.totalElapsedSeconds) : parsedCardSeconds.length > 0 ? Math.max(...parsedCardSeconds) : NaN;
      if (!Number.isFinite(cardSeconds)) continue;
      const traceMatched = traceRows.filter((row) => traceRowMatchesCard(row, card, terminalCards.length));
      const traceEvidence = maxTraceDurationEvidence(traceMatched);
      const textEvidence = maxSelfReportedDurationEvidence([card.text, card.preview, card.finalResponseText, card.runningRecordText, terminalCards.length === 1 ? sampleText : ''].filter(Boolean).join('\n'));
      const evidences = [traceEvidence, textEvidence].filter((item) => item && item.exact === true && Number.isFinite(item.seconds));
      if (!evidences.length) continue;
      const strongest = evidences.sort((a, b) => b.seconds - a.seconds)[0];
      const tolerance = Math.max(slackSeconds, Math.ceil(strongest.seconds * 0.05));
      if (strongest.seconds > cardSeconds + tolerance) {
        findings.push({
          sampleIndex,
          ...timingFindingMeta(strongest.kind, timingStatusFromTurnStatus(card.status || card.state || card.phase, "business-turn-completed"), {
            cardElapsedSource: "dom-card-total-elapsed",
            expectedElapsedSource: strongest.kind,
          }),
          timestamp: sample.timestamp || sample.collectedAt || sample.time || null,
          pageRole: card.pageRole || sample.pageRole || sample.role || sample.contextRole || null,
          pageId: card.pageId || sample.pageId || sample.contextId || null,
          sessionId: card.sessionId || sample.sessionId || sample.workbenchSessionId || null,
          traceId: card.traceId || strongest.traceId || null,
          status: card.status || card.state || card.phase || null,
          cardTotalElapsedSeconds: cardSeconds,
          expectedElapsedSeconds: strongest.seconds,
          deltaSeconds: strongest.seconds - cardSeconds,
          toleranceSeconds: tolerance,
          evidenceKind: strongest.kind,
          evidencePreview: strongest.preview,
          cardPreview: card.preview || compactOneLine(cardText || ''),
        });
      }
    }
  }
  return findings.slice(0, 100);
}

function buildCodeAgentCardDurationMismatchMetrics(samples, timeline) {
  const findings = [];
  const slackSeconds = Math.max(5, Number(alertThresholds?.turnTimingSampleSlackSeconds || 0));
  for (let sampleIndex = 0; sampleIndex < samples.length; sampleIndex += 1) {
    const sample = samples[sampleIndex] || {};
    const cards = codeAgentCardsForSample(sample);
    if (!cards.length) continue;
    const traceRows = traceTimingRowsForSample(sample, timeline[sampleIndex] || {});
    const terminalCards = cards.filter((card) => isCodeAgentCardTerminal(card));
    const sampleText = sampleVisibleText(sample, timeline[sampleIndex] || {});
    for (const card of terminalCards) {
      const cardText = codeAgentCardText(card);
      const parsedCardSeconds = parseTotalElapsedSeconds(cardText).filter(Number.isFinite);
      const cardSeconds = Number.isFinite(Number(card.totalElapsedSeconds)) ? Number(card.totalElapsedSeconds) : parsedCardSeconds.length > 0 ? Math.max(...parsedCardSeconds) : NaN;
      if (!Number.isFinite(cardSeconds)) continue;
      const traceMatched = traceRows.filter((row) => traceRowMatchesCard(row, card, terminalCards.length));
      const traceEvidence = maxTraceDurationEvidence(traceMatched);
      const textEvidence = maxSelfReportedDurationEvidence([card.text, card.preview, card.finalResponseText, card.runningRecordText, terminalCards.length === 1 ? sampleText : ''].filter(Boolean).join('\n'));
      const evidences = [traceEvidence, textEvidence].filter((item) => item && item.exact === true && Number.isFinite(item.seconds));
      if (!evidences.length) continue;
      const strongest = evidences.sort((a, b) => b.seconds - a.seconds)[0];
      const exactEvidence = strongest.exact === true || strongest.kind === 'trace-completion-total' || strongest.kind === 'final-response-duration';
      const tolerance = Math.max(slackSeconds, Math.ceil(strongest.seconds * 0.05));
      const signedDelta = Number((cardSeconds - strongest.seconds).toFixed(3));
      const absoluteDelta = Math.abs(signedDelta);
      const underreported = strongest.seconds > cardSeconds + tolerance;
      const overreported = exactEvidence && cardSeconds > strongest.seconds + tolerance;
      if (!underreported && !overreported) continue;
      findings.push({
        sampleIndex,
        ...timingFindingMeta(strongest.kind, timingStatusFromTurnStatus(card.status || card.state || card.phase, "business-turn-completed"), {
          cardElapsedSource: "dom-card-total-elapsed",
          expectedElapsedSource: strongest.kind,
        }),
        timestamp: sample.timestamp || sample.collectedAt || sample.time || sample.ts || null,
        pageRole: card.pageRole || sample.pageRole || sample.role || sample.contextRole || null,
        pageId: card.pageId || sample.pageId || sample.contextId || null,
        sessionId: card.sessionId || sample.sessionId || sample.workbenchSessionId || null,
        traceId: card.traceId || strongest.traceId || null,
        status: card.status || card.state || card.phase || null,
        direction: underreported ? 'underreported' : 'overreported',
        cardTotalElapsedSeconds: cardSeconds,
        expectedElapsedSeconds: strongest.seconds,
        signedDeltaSeconds: signedDelta,
        deltaSeconds: Number(absoluteDelta.toFixed(3)),
        toleranceSeconds: tolerance,
        evidenceKind: strongest.kind,
        exactEvidence,
        evidencePreview: strongest.preview,
        cardPreview: card.preview || compactOneLine(cardText || ''),
      });
    }
  }
  return findings.slice(0, 100);
}

function traceTimingRowsForSample(sample, timelineItem) {
  const rows = [];
  const seen = new Set();
  const appendRowsFromText = (text, source, baseIndex, meta = {}) => {
    for (const extracted of extractTraceRowsFromText(text, source, baseIndex, meta)) {
      const key = [extracted.pageRole || '', extracted.pageId || '', extracted.rowIndex, extracted.preview].join('|');
      if (seen.has(key)) continue;
      seen.add(key);
      rows.push(extracted);
    }
  };
  for (const candidate of traceRowCandidateArrays(sample, timelineItem)) {
    const array = Array.isArray(candidate.rows) ? candidate.rows : [];
    array.forEach((item, index) => {
      if (typeof item === 'string') {
        appendRowsFromText(item, candidate.source, index, candidate.meta || {});
        return;
      }
      if (!item || typeof item !== 'object') return;
      const text = objectText(item);
      if (!text) return;
      appendRowsFromText(text, candidate.source, Number.isFinite(Number(item.index)) ? Number(item.index) : index, {
        ...(candidate.meta || {}),
        pageRole: item.pageRole || item.role || candidate.meta?.pageRole || null,
        pageId: item.pageId || item.contextId || candidate.meta?.pageId || null,
        sessionId: item.sessionId || item.workbenchSessionId || candidate.meta?.sessionId || null,
        traceId: item.traceId || item.trace_id || candidate.meta?.traceId || null,
        projectedSeq: item.projectedSeq ?? item.projected_seq ?? item.projectedSequence ?? null,
        sourceSeq: item.sourceSeq ?? item.source_seq ?? item.sourceSequence ?? null,
        eventSeq: item.eventSeq ?? item.event_seq ?? item.sequence ?? null,
        eventTimestamp: item.eventTimestamp ?? item.event_ts ?? item.timestamp ?? item.ts ?? null,
        eventTimeText: item.eventTimeText ?? item.timeText ?? null,
        eventKind: item.eventKind ?? item.kind ?? item.status ?? null,
      });
    });
  }
  if (!rows.length) {
    appendRowsFromText(sampleVisibleText(sample, timelineItem), 'visible-text', 0, {
      pageRole: sample.pageRole || sample.role || sample.contextRole || null,
      pageId: sample.pageId || sample.contextId || null,
      sessionId: sample.sessionId || sample.workbenchSessionId || null,
    });
  }
  rows.sort((a, b) => (a.rowIndex ?? 0) - (b.rowIndex ?? 0));
  return rows;
}

function extractTraceRowsFromText(text, source, baseIndex, meta = {}) {
  const result = [];
  const normalized = String(text || '').replace(/\r/g, '\n');
  if (!normalized.trim()) return result;
  const lines = normalized.split('\n').map((line) => line.trim()).filter(Boolean);
  for (let index = 0; index < lines.length; index += 1) {
    const line = lines[index];
    if (!traceLineLooksRelevant(line)) continue;
    const nextLine = index + 1 < lines.length && !/^\d{1,2}:\d{2}:\d{2}\b/.test(lines[index + 1]) ? lines[index + 1] : '';
    const preview = compactOneLine(nextLine ? line + ' ' + nextLine : line);
    result.push(normalizeTraceTimingRow(preview, source, Number(baseIndex || 0) * 1000 + index, meta));
  }
  return result;
}

function normalizeTraceTimingRow(text, source, rowIndex, meta = {}) {
  const preview = compactOneLine(text).slice(0, 240);
  const projectedSeq = firstFiniteNumber(meta.projectedSeq, parseTraceRowProjectedSeq(preview));
  const sourceSeq = firstFiniteNumber(meta.sourceSeq);
  const eventSeq = firstFiniteNumber(meta.eventSeq);
  const timestampMs = parseTraceRowTimestampMs(meta.eventTimestamp || meta.eventTimeText || preview);
  return {
    source,
    rowIndex,
    preview,
    pageRole: meta.pageRole || null,
    pageId: meta.pageId || null,
    sessionId: meta.sessionId || null,
    traceId: meta.traceId || parseTraceRowTraceId(preview),
    clockSeconds: parseTraceRowClockSeconds(preview) ?? parseTraceRowClockSeconds(meta.eventTimeText || ""),
    timestampMs,
    totalSeconds: parseTraceRowTotalSeconds(preview),
    projectedSeq,
    sourceSeq,
    eventSeq,
    eventTimestamp: meta.eventTimestamp || null,
    eventTimeText: meta.eventTimeText || null,
    eventKind: meta.eventKind || null,
    isCompletion: traceRowIsTerminalCompletionText(preview, meta.eventKind || ""),
  };
}

function traceRowIsTerminalCompletionText(preview, eventKind = "") {
  const value = [preview, eventKind].map((item) => String(item || "")).join(" ");
  if (/\bnon[-_ ]?terminal\b/i.test(value)) return false;
  if (/轮次完成|turn\s+completed|completed\s+turn|backend[_: -]?turn[_: -]?finished/i.test(value)) return true;
  return /\bterminal(?:[_: -]?status|Status)?\s*[=: -]\s*(?:completed|failed|cancelled|canceled|timeout)\b/i.test(value);
}

function traceRowIsRoundCompletionText(preview, eventKind = "") {
  const value = [preview, eventKind].map((item) => String(item || "")).join(" ");
  if (/\bnon[-_ ]?terminal\b/i.test(value)) return false;
  return /轮次完成|turn\s+completed|completed\s+turn|backend[_: -]?turn[_: -]?finished/i.test(value);
}

function traceRowCandidateArrays(sample, timelineItem) {
  const candidates = [];
  const pushArray = (rows, source, meta = {}) => {
    if (Array.isArray(rows) && rows.length) candidates.push({ rows, source, meta });
  };
  const directSources = [
    [sample?.traceRows, 'sample.traceRows'],
    [sample?.eventRows, 'sample.eventRows'],
    [sample?.activityRows, 'sample.activityRows'],
    [sample?.timelineRows, 'sample.timelineRows'],
    [sample?.dom?.traceRows, 'sample.dom.traceRows'],
    [sample?.dom?.eventRows, 'sample.dom.eventRows'],
    [sample?.dom?.activityRows, 'sample.dom.activityRows'],
    [sample?.dom?.timelineRows, 'sample.dom.timelineRows'],
    [timelineItem?.traceRows, 'timeline.traceRows'],
    [timelineItem?.eventRows, 'timeline.eventRows'],
    [timelineItem?.activityRows, 'timeline.activityRows'],
    [timelineItem?.rows, 'timeline.rows'],
    [timelineItem?.events, 'timeline.events'],
  ];
  for (const [rows, source] of directSources) pushArray(rows, source, {});
  if (!candidates.length) collectNamedTraceArrays(sample, candidates, 'sample', 0);
  if (!candidates.length) collectNamedTraceArrays(timelineItem, candidates, 'timeline', 0);
  return candidates;
}

function collectNamedTraceArrays(value, candidates, path, depth) {
  if (!value || depth > 5) return;
  if (Array.isArray(value)) {
    const pathLooksTrace = /trace|timeline|activity|event|log|record/i.test(path);
    const valueLooksTrace = value.slice(0, 5).some((item) => traceLineLooksRelevant(typeof item === 'string' ? item : objectText(item)));
    if (pathLooksTrace || valueLooksTrace) candidates.push({ rows: value, source: path, meta: {} });
    return;
  }
  if (typeof value !== 'object') return;
  for (const [key, child] of Object.entries(value)) {
    if (!child) continue;
    if (Array.isArray(child)) {
      const childPath = path + '.' + key;
      const pathLooksTrace = /trace|timeline|activity|event|log|record/i.test(key);
      const valueLooksTrace = child.slice(0, 5).some((item) => traceLineLooksRelevant(typeof item === 'string' ? item : objectText(item)));
      if (pathLooksTrace || valueLooksTrace) candidates.push({ rows: child, source: childPath, meta: {} });
      continue;
    }
    if (typeof child === 'object' && /dom|trace|timeline|activity|event|log|record|page|card|message|panel|diagnostic/i.test(key)) {
      collectNamedTraceArrays(child, candidates, path + '.' + key, depth + 1);
    }
  }
}

function traceLineLooksRelevant(text) {
  const value = String(text || '').trim();
  if (!value) return false;
  if (/^\d{1,2}:\d{2}:\d{2}\b/.test(value)) return true;
  if (/\btotal=\d/.test(value)) return true;
  if (/轮次完成（总耗时/.test(value)) return true;
  if (/\bseq(?:uence)?[=:]\s*\d+/i.test(value)) return true;
  return false;
}

function parseTraceRowClockSeconds(text) {
  const match = String(text || '').match(/^\s*(\d{1,2}):(\d{2}):(\d{2})\b/);
  if (!match) return null;
  return Number(match[1]) * 3600 + Number(match[2]) * 60 + Number(match[3]);
}

function parseTraceRowTotalSeconds(text) {
  const value = String(text || '');
  const totalMatch = value.match(/\btotal=([0-9:.]+)/i);
  if (totalMatch) return parseTraceDurationSeconds(totalMatch[1]);
  const completionMatch = value.match(/总耗时\s*([0-9:.]+)/);
  if (completionMatch) return parseTraceDurationSeconds(completionMatch[1]);
  return null;
}

function parseTraceDurationSeconds(value) {
  const text = String(value || '').trim();
  if (!text) return null;
  const parts = text.split(':').map((part) => Number(part));
  if (parts.some((part) => !Number.isFinite(part))) return null;
  if (parts.length === 3) return parts[0] * 3600 + parts[1] * 60 + parts[2];
  if (parts.length === 2) return parts[0] * 60 + parts[1];
  if (parts.length === 1) return parts[0];
  return null;
}

function parseTraceRowProjectedSeq(text) {
  const value = String(text || '');
  const match = value.match(/\b(?:projected[_-]?seq|seq(?:uence)?|event[_-]?seq)\s*[=:]\s*(\d+)/i);
  return match ? Number(match[1]) : null;
}

function parseTraceRowTimestampMs(value) {
  const text = String(value || '').trim();
  if (!text) return null;
  const parsed = Date.parse(text);
  return Number.isFinite(parsed) ? parsed : null;
}

function firstFiniteNumber(...values) {
  for (const value of values) {
    const numeric = Number(value);
    if (Number.isFinite(numeric)) return numeric;
  }
  return null;
}

function parseTraceRowTraceId(text) {
  const match = String(text || '').match(/\b(?:trace_id=|traceId[:=]?\s*)(trc_[a-z0-9_-]+|[a-f0-9]{16,})\b/i);
  return match ? match[1] : null;
}

function traceRowGroupKey(row) {
  const identity = row.traceId ? 'trace:' + row.traceId : 'sample:' + (row.sampleIndex ?? '-') + ':' + (row.source || 'unknown');
  return [row.pageRole || '', row.pageId || '', row.sessionId || '', row.source || '', row.sampleIndex ?? '', identity].join('|');
}

function traceRowMatchesCard(row, card, terminalCardCount) {
  if (!row) return false;
  if (card.traceId) return row.traceId === card.traceId;
  if (row.traceId) return false;
  if (row.sessionId && card.sessionId) return terminalCardCount === 1 && row.sessionId === card.sessionId;
  if (terminalCardCount === 1) return true;
  return false;
}

function maxTraceDurationEvidence(rows) {
  const finiteTotals = rows.map((row) => Number(row.totalSeconds)).filter(Number.isFinite);
  const finiteClocks = rows.map((row) => Number(row.clockSeconds)).filter(Number.isFinite);
  const evidences = [];
  if (finiteTotals.length) {
    const maxTotal = Math.max(...finiteTotals);
    const source = rows.find((row) => Number(row.totalSeconds) === maxTotal);
    const exact = source?.isCompletion === true;
    evidences.push({ kind: exact ? 'trace-completion-total' : 'trace-total', seconds: maxTotal, traceId: source?.traceId || null, preview: source?.preview || '', exact });
  }
  if (finiteClocks.length >= 2) {
    const minClock = Math.min(...finiteClocks);
    const maxClock = Math.max(...finiteClocks);
    const span = maxClock - minClock;
    if (span >= 0 && span < 43200) evidences.push({ kind: 'trace-clock-span', seconds: span, traceId: null, preview: 'visible trace row clock span', exact: false });
  }
  if (!evidences.length) return null;
  evidences.sort((a, b) => b.seconds - a.seconds);
  return evidences[0];
}

function maxSelfReportedDurationEvidence(text) {
  const value = String(text || '');
  const lines = value.split(/\n+/).map((line) => line.trim()).filter(Boolean);
  let best = null;
  for (let index = 0; index < lines.length; index += 1) {
    const line = lines[index];
    const previous = index > 0 ? lines[index - 1] : '';
    const next = index + 1 < lines.length ? lines[index + 1] : '';
    const candidateText = selfReportedDurationCandidateText(previous, line, next);
    if (!candidateText) continue;
    const seconds = parseSelfReportedRoundDurationSeconds(candidateText);
    if (!Number.isFinite(seconds)) continue;
    if (!best || seconds > best.seconds) {
      best = { kind: 'final-response-duration', seconds, preview: compactOneLine(candidateText).slice(0, 240), exact: true };
    }
  }
  return best;
}

function selfReportedDurationCandidateText(previous, line, next) {
  const current = String(line || '');
  const before = String(previous || '');
  const after = String(next || '');
  const windowText = [before, current, after].filter(Boolean).join(' ');
  const hasDurationKeyword = /耗时|用时|duration|elapsed/i.test(current);
  const hasNearbyDurationHeading = /(?:本轮|整轮|全程|任务|round|turn)?\s*(?:耗时|用时|duration|elapsed)/i.test(before)
    || /(?:本轮|整轮|全程|任务|round|turn)?\s*(?:耗时|用时|duration|elapsed)/i.test(after);
  const hasDurationValue = /(?:约|大约|around|about)?\s*\d+(?:\.\d+)?\s*(?:小时|分钟|分|秒|hour|hours|hr|hrs|min|mins|minute|minutes|sec|secs|second|seconds)/i.test(windowText);
  const hasRoundContext = /本轮|整轮|全程|从.+到|全部通过|smoke|benchmark|round|turn|completed|passed/i.test(windowText);
  if (hasDurationKeyword && hasDurationValue) return current;
  if (hasNearbyDurationHeading && hasDurationValue) return windowText;
  if (hasRoundContext && hasDurationValue && /(?:约|大约|around|about)\s*\d|\d+(?:\.\d+)?\s*(?:分钟|小时|minute|hour)/i.test(current)) return windowText;
  return '';
}

function parseSelfReportedRoundDurationSeconds(text) {
  const value = String(text || '');
  const clock = value.match(/(?:耗时|用时|duration|elapsed)[^0-9]{0,24}(\d{1,2}:\d{2}:\d{2}|\d{1,2}:\d{2})/i);
  if (clock) return parseTraceDurationSeconds(clock[1]);
  const hour = value.match(/(?:约|大约|around|about)?\s*(\d+(?:\.\d+)?)\s*(?:小时|hour|hours|hr|hrs)/i);
  const minute = value.match(/(?:约|大约|around|about)?\s*(\d+(?:\.\d+)?)\s*(?:分钟|分|min|mins|minute|minutes)/i);
  const second = value.match(/(?:约|大约|around|about)?\s*(\d+(?:\.\d+)?)\s*(?:秒|sec|secs|second|seconds)/i);
  let total = 0;
  if (hour) total += Number(hour[1]) * 3600;
  if (minute) total += Number(minute[1]) * 60;
  if (second) total += Number(second[1]);
  return total > 0 ? total : null;
}

function sampleVisibleText(sample, timelineItem) {
  const chunks = [];
  for (const source of [sample?.visibleText, sample?.text, sample?.innerText, sample?.dom?.visibleText, sample?.dom?.text, timelineItem?.visibleText, timelineItem?.text, timelineItem?.message, timelineItem?.summary]) {
    if (typeof source === 'string' && source.trim()) chunks.push(source);
  }
  return chunks.join('\n');
}

function objectText(value) {
  if (!value || typeof value !== 'object') return typeof value === 'string' ? value : '';
  const keys = ['text', 'innerText', 'visibleText', 'label', 'title', 'summary', 'message', 'content', 'body', 'preview', 'description'];
  const chunks = [];
  for (const key of keys) {
    const part = value[key];
    if (typeof part === 'string' && part.trim()) chunks.push(part);
  }
  return chunks.join('\n');
}

function compactOneLine(value) {
  return String(value || '').replace(/\s+/g, ' ').trim();
}

function buildCodeAgentCardTimingMetrics(samples, timeline, turnTiming) {
  const missingElapsed = [];
  const missingRecentUpdate = [];
  const cardRows = [];
  for (let index = 0; index < (Array.isArray(samples) ? samples : []).length; index += 1) {
    const sample = samples[index];
    const timelineItem = timeline[index] || {};
    for (const card of codeAgentCardsForSample(sample)) {
      const text = codeAgentCardText(card);
      const totalElapsedValues = parseTotalElapsedSeconds(card?.durationText).filter(Number.isFinite);
      const recentUpdateValues = parseRecentUpdateSeconds(card?.activityText).filter(Number.isFinite);
      const terminal = isCodeAgentCardTerminal(card);
      const row = {
        ...ref(sample),
        promptIndex: timelineItem.promptIndex ?? 0,
        source: card.source ?? "turn",
        status: card.status ?? null,
        messageId: card.messageId ?? null,
        traceId: card.traceId ?? firstTraceId([text]),
        sessionId: card.sessionId ?? sample.sessionId ?? sample.workbenchSessionId ?? sample.routeSessionId ?? sample.activeSessionId ?? null,
        durationText: limitText(card.durationText, 120),
        activityText: limitText(card.activityText, 120),
        totalElapsedSeconds: totalElapsedValues.length > 0 ? Math.max(...totalElapsedValues) : null,
        recentUpdateSeconds: recentUpdateValues.length > 0 ? Math.max(...recentUpdateValues) : null,
        terminal,
        textHash: card.textHash ?? sha256(text),
        textPreview: limitText(text, 180),
        valuesRedacted: true
      };
      cardRows.push(row);
      if (row.totalElapsedSeconds === null) missingElapsed.push(row);
      if (!terminal && row.recentUpdateSeconds === null) missingRecentUpdate.push(row);
    }
  }
  const roundCompletion = buildRoundCompletionMetrics(samples, timeline, turnTiming);
  return {
    summary: {
      cardSampleCount: cardRows.length,
      terminalCardSampleCount: cardRows.filter((item) => item.terminal).length,
      runningCardSampleCount: cardRows.filter((item) => !item.terminal).length,
      missingElapsedCount: missingElapsed.length,
      missingRecentUpdateCount: missingRecentUpdate.length,
      roundCompletionEventCount: roundCompletion.events.length,
      roundCompletionElapsedMismatchCount: roundCompletion.elapsedMismatches.length,
      roundCompletionFinalResponseMissingCount: roundCompletion.finalResponseMissing.length,
      roundCompletionPostTimingChangeCount: roundCompletion.postCompletionTimingChanges.length,
      roundCompletionPostRecentUpdateVisibleCount: roundCompletion.postCompletionRecentUpdateVisible.length,
      elapsedMismatchToleranceSeconds: alertThresholds.turnTimingSampleSlackSeconds,
    },
    cardSamples: cardRows.slice(0, 200),
    missingElapsed: missingElapsed.slice(0, 200),
    missingRecentUpdate: missingRecentUpdate.slice(0, 200),
    roundCompletion,
    valuesRedacted: true
  };
}

function codeAgentCardsForSample(sample) {
  const turnCards = (Array.isArray(sample?.turns) ? sample.turns : [])
    .map((item) => ({ ...item, source: item?.source || "turn" }))
    .filter(isCodeAgentCardLike);
  if (turnCards.length > 0) return turnCards;
  return (Array.isArray(sample?.messages) ? sample.messages : [])
    .map((item) => ({ ...item, source: item?.source || "message" }))
    .filter(isCodeAgentCardLike);
}

function isCodeAgentCardLike(item) {
  const text = codeAgentCardText(item);
  const role = String(item?.dataRole || item?.role || "").toLowerCase();
  if (/agent|assistant/u.test(role)) return true;
  return /Code Agent|运行记录|耗时|最近\s*(?:\d+|一|两|三)|轮次完成|trace_id=trc_/iu.test(text);
}

function codeAgentCardText(item) {
  return [
    item?.durationText,
    item?.activityText,
    item?.text,
    item?.textPreview,
    item?.status
  ].map((value) => String(value || "")).filter((value) => value.trim().length > 0).join("\n");
}

function isCodeAgentCardTerminal(item) {
  const status = String(item?.status ?? item?.state ?? item?.phase ?? "").trim().toLowerCase().replace(/_/gu, "-");
  if (isActiveTurnStatus(status)) return false;
  if (isTerminalTurnStatus(status)) return true;
  if (item?.terminal === true || item?.sealed === true) return true;
  const text = codeAgentCardText(item);
  return isTerminalTraceText(text) || /轮次完成|轮次失败|轮次取消|已记录|completed|failed|canceled|cancelled|blocked/iu.test(text);
}

function timingFindingMeta(sourceOfTruth, status, extra = {}) {
  return {
    timingSourceOfTruth: sourceOfTruth,
    timingStatus: status || "non-blocking-timing-alert",
    timingAlert: true,
    blocking: false,
    ...extra,
  };
}

function timingStatusFromTurnStatus(status, fallback = "observer-timeout") {
  const normalized = String(status ?? "").trim().toLowerCase().replace(/_/gu, "-");
  if (isSuccessfulTurnStatus(normalized)) return "business-turn-completed";
  if (isTerminalTurnStatus(normalized)) return "scenario-incomplete";
  if (isActiveTurnStatus(normalized)) return "observer-timeout";
  return fallback;
}

function timingStatusFromRows(rows, fallback = "observer-timeout") {
  const list = Array.isArray(rows) ? rows : [];
  if (list.some((item) => isSuccessfulTurnStatus(item?.status ?? item?.toStatus ?? item?.fromStatus))) return "business-turn-completed";
  if (list.some((item) => Number(item?.finalTextSamples ?? 0) > 0)) return "business-turn-completed";
  if (list.some((item) => isTerminalTurnStatus(item?.status ?? item?.toStatus ?? item?.fromStatus))) return "scenario-incomplete";
  if (list.some((item) => isActiveTurnStatus(item?.status ?? item?.toStatus ?? item?.fromStatus))) return "observer-timeout";
  return fallback;
}

function isSuccessfulTurnStatus(status) {
  const normalized = String(status ?? "").trim().toLowerCase().replace(/_/gu, "-");
  return ["completed", "complete", "succeeded", "success", "done", "ok", "passed"].includes(normalized);
}

function isActiveTurnStatus(value) {
  const status = String(value ?? "").trim().toLowerCase().replace(/_/gu, "-");
  return ["pending", "running", "queued", "admitted", "dispatching", "in-progress", "inprogress", "executing", "progress", "thinking", "working", "active", "streaming", "created", "started"].includes(status);
}

function buildRoundCompletionMetrics(samples, timeline, turnTiming) {
  const events = [];
  const elapsedMismatchToleranceSeconds = Math.max(5, Number(alertThresholds.turnTimingSampleSlackSeconds || 0));
  for (let index = 0; index < (Array.isArray(samples) ? samples : []).length; index += 1) {
    const sample = samples[index];
    const timelineItem = timeline[index] || {};
    for (const event of roundCompletionEventsForSample(sample, timelineItem)) events.push(event);
  }
  const completionEvents = dedupeRoundCompletionEvents(events);
  const elapsedMismatches = [];
  const finalResponseMissing = [];
  const postCompletionTimingChanges = [];
  const postCompletionRecentUpdateVisible = [];
  for (const event of completionEvents) {
    const sampleIndex = samples.findIndex((sample) => sample?.seq === event.seq && sample?.pageRole === event.pageRole && sample?.pageId === event.pageId);
    const sameSample = sampleIndex >= 0 ? samples[sampleIndex] : null;
    const sameTimelineItem = sampleIndex >= 0 ? timeline[sampleIndex] || {} : {};
    const cards = sameSample ? cardMetricItemsForCompletion(sameSample, sameTimelineItem, event) : [];
    const bestCard = cards.filter((card) => Number.isFinite(Number(card.totalElapsedSeconds)))[0] || null;
    if (Number.isFinite(Number(event.elapsedSeconds)) && bestCard) {
      const delta = Math.abs(Number(bestCard.totalElapsedSeconds) - Number(event.elapsedSeconds));
      if (delta > elapsedMismatchToleranceSeconds) {
        elapsedMismatches.push({
          ...eventRef(event),
          ...timingFindingMeta("trace-round-completion-total", timingStatusFromTurnStatus(bestCard.status, "business-turn-completed"), {
            cardElapsedSource: bestCard.source ?? "dom-card",
            completionElapsedSource: "trace-round-completion",
          }),
          cardTotalElapsedSeconds: Number(bestCard.totalElapsedSeconds),
          completionElapsedSeconds: Number(event.elapsedSeconds),
          deltaSeconds: Number(delta.toFixed(3)),
          toleranceSeconds: elapsedMismatchToleranceSeconds,
          cardTraceId: bestCard.traceId ?? null,
          cardMessageId: bestCard.messageId ?? null,
          valuesRedacted: true
        });
      }
    }
    if (!(sameSample && sampleHasTerminalAgentResultCard(sameSample, event)) && !(sameSample && sampleHasVisibleFinalResponse(sameSample, event)) && !hasFinalResponseAfterCompletion(samples, timeline, event)) {
      finalResponseMissing.push({
        ...eventRef(event),
        completionElapsedSeconds: event.elapsedSeconds,
        finalResponseProbe: sameSample ? terminalAgentResultProbe(sameSample, event) : { ok: false, reason: "sample-not-found" },
        valuesRedacted: true
      });
    }
    const postTiming = detectPostCompletionTimingChanges(turnTiming, event);
    postCompletionTimingChanges.push(...postTiming.timingChanges);
    postCompletionRecentUpdateVisible.push(...postTiming.recentUpdateVisible);
  }
  return {
    events: completionEvents.slice(0, 200),
    elapsedMismatches: dedupeRoundCompletionRows(elapsedMismatches).slice(0, 200),
    finalResponseMissing: dedupeRoundCompletionRows(finalResponseMissing).slice(0, 200),
    postCompletionTimingChanges: dedupeRoundCompletionRows(postCompletionTimingChanges).slice(0, 200),
    postCompletionRecentUpdateVisible: dedupeRoundCompletionRows(postCompletionRecentUpdateVisible).slice(0, 200),
    valuesRedacted: true
  };
}

function roundCompletionEventsForSample(sample, timelineItem) {
  const rows = [];
  for (const item of traceTimingRowsForSample(sample, timelineItem)) {
    const text = String(item?.preview || item?.text || item?.textPreview || "");
    if (!traceRowIsRoundCompletionText(text, item?.eventKind || "")) continue;
    const elapsedValues = [
      Number(item?.totalSeconds),
      ...parseTotalElapsedSeconds(text).filter(Number.isFinite)
    ].filter(Number.isFinite);
    const attributed = inferRoundCompletionCard(sample, text);
    rows.push({
      ...ref(sample),
      promptIndex: timelineItem.promptIndex ?? 0,
      traceId: item?.traceId ?? firstTraceId([text]) ?? attributed?.traceId ?? null,
      messageId: item?.messageId ?? attributed?.messageId ?? null,
      attributed: Boolean(item?.traceId || item?.messageId || attributed?.traceId || attributed?.messageId),
      traceRowIndex: item?.rowIndex ?? item?.index ?? null,
      elapsedSeconds: elapsedValues.length > 0 ? Math.max(...elapsedValues) : null,
      timingSourceOfTruth: "trace-round-completion-total",
      timingStatus: "business-turn-completed",
      textHash: item?.textHash ?? sha256(text),
      preview: limitText(text, 180),
      valuesRedacted: true
    });
  }
  return rows;
}

function inferRoundCompletionCard(sample, text) {
  const cards = codeAgentCardsForSample(sample)
    .filter((card) => isCodeAgentCardTerminal(card))
    .filter((card) => card?.traceId || card?.messageId);
  const textHash = sha256(String(text || ""));
  const direct = cards.filter((card) => {
    const cardText = codeAgentCardText(card);
    return card?.textHash === textHash || cardText.includes(String(text || "").slice(0, 80)) || /轮次完成/iu.test(cardText);
  });
  const candidates = direct.length > 0 ? direct : cards;
  if (candidates.length !== 1) return null;
  const card = candidates[0];
  return { traceId: card.traceId ?? null, messageId: card.messageId ?? card.id ?? null };
}

function cardMetricItemsForCompletion(sample, timelineItem, event) {
  const metrics = turnMetricItems(sample, timelineItem)
    .filter((item) => item.promptIndex === event.promptIndex)
    .filter((item) => item.pageRole === event.pageRole || !event.pageRole)
    .filter((item) => item.pageId === event.pageId || !event.pageId);
  if (!event.traceId && !event.messageId) {
    const withElapsed = metrics.filter((item) => Number.isFinite(Number(item.totalElapsedSeconds)));
    return withElapsed.length === 1 ? withElapsed : [];
  }
  return metrics
    .filter((item) => !event.traceId || !item.traceId || item.traceId === event.traceId)
    .filter((item) => !event.messageId || !item.messageId || item.messageId === event.messageId)
    .sort((left, right) => {
      const leftTraceMatch = event.traceId && left.traceId === event.traceId ? 0 : 1;
      const rightTraceMatch = event.traceId && right.traceId === event.traceId ? 0 : 1;
      const leftMessageMatch = event.messageId && left.messageId === event.messageId ? 0 : 1;
      const rightMessageMatch = event.messageId && right.messageId === event.messageId ? 0 : 1;
      return leftTraceMatch - rightTraceMatch || leftMessageMatch - rightMessageMatch || String(left.source || "").localeCompare(String(right.source || ""));
    });
}

function hasFinalResponseAfterCompletion(samples, timeline, event) {
  if (!event.traceId && !event.messageId && !event.promptIndex) return true;
  const eventTsMs = Date.parse(String(event.ts || ""));
  for (let index = 0; index < (Array.isArray(samples) ? samples : []).length; index += 1) {
    const sample = samples[index];
    const tsMs = Date.parse(String(sample?.ts || ""));
    if (Number.isFinite(eventTsMs) && Number.isFinite(tsMs) && tsMs < eventTsMs) continue;
    if (sample?.pageRole !== event.pageRole) continue;
    const sampleSession = sample?.routeSessionId || sample?.activeSessionId || null;
    const eventSession = event.routeSessionId || event.activeSessionId || null;
    if (sampleSession && eventSession && sampleSession !== eventSession) continue;
    const promptIndex = timeline[index]?.promptIndex ?? 0;
    if (!event.traceId && !event.messageId && event.promptIndex && promptIndex !== event.promptIndex) continue;
    if (sampleHasTerminalAgentResultCard(sample, event)) return true;
    if (sampleHasVisibleFinalResponse(sample, event)) return true;
  }
  return false;
}

function sampleHasTerminalAgentResultCard(sample, event = {}) {
  return terminalAgentResultProbe(sample, event).ok === true;
}

function terminalAgentResultProbe(sample, event = {}) {
  const decisions = [];
  for (const item of codeAgentCardsForSample(sample)) {
    const text = normalizedText(codeAgentCardText(item));
    const traceMatched = Boolean(event.traceId && item?.traceId && item.traceId === event.traceId);
    const decision = {
      source: item?.source || null,
      role: item?.role ?? null,
      dataRole: item?.dataRole ?? null,
      status: item?.status ?? null,
      traceId: item?.traceId ?? null,
      messageId: item?.messageId ?? null,
      textBytes: Buffer.byteLength(text),
      valuesRedacted: true
    };
    if (event.traceId && item?.traceId && item.traceId !== event.traceId) {
      decisions.push({ ...decision, decision: "skip-trace" });
      continue;
    }
    if (!traceMatched && event.messageId && item?.messageId && item.messageId !== event.messageId) {
      decisions.push({ ...decision, decision: "skip-message" });
      continue;
    }
    if (!isAssistantFinalResponseCandidate(item, item?.source || "turn")) {
      decisions.push({ ...decision, decision: "skip-role" });
      continue;
    }
    if (!isCodeAgentCardTerminal(item)) {
      decisions.push({ ...decision, decision: "skip-non-terminal" });
      continue;
    }
    if (text.length < 24) {
      decisions.push({ ...decision, decision: "skip-short" });
      continue;
    }
    decisions.push({ ...decision, decision: "accept-terminal-agent-card" });
    return { ok: true, decisions: decisions.slice(-8), valuesRedacted: true };
  }
  return { ok: false, decisions: decisions.slice(-8), valuesRedacted: true };
}

function sampleHasVisibleFinalResponse(sample, event = {}) {
  for (const [groupName, group] of [["messages", sample?.messages], ["turns", sample?.turns]]) {
    if (!Array.isArray(group)) continue;
    for (const item of group) {
      const traceMatched = Boolean(event.traceId && item?.traceId && item.traceId === event.traceId);
      if (event.traceId && item?.traceId && item.traceId !== event.traceId) continue;
      if (!traceMatched && event.messageId && item?.messageId && item.messageId !== event.messageId) continue;
      if (!isAssistantFinalResponseCandidate(item, groupName)) continue;
      const text = normalizedText([item?.text, item?.textPreview].filter(Boolean).join(" "));
      if (text.length < 24) continue;
      if (groupName === "messages" && isTerminalTurnStatus(item?.status)) return true;
      if (isDiagnosticText(text)) continue;
      if (isFinalResultText(text)) return true;
      if (/运行记录/iu.test(text) && /(?:已完成|完成|新增|实现|验证|测试|结果|README|文件|summary)/iu.test(text)) return true;
    }
  }
  return false;
}

function normalizedDomRole(item) {
  return String(item?.dataRole ?? item?.role ?? item?.ariaRole ?? "")
    .trim()
    .toLowerCase()
    .replace(/[_\s]+/gu, "-");
}

function isAssistantFinalResponseCandidate(item, groupName) {
  const role = normalizedDomRole(item);
  if (/agent|assistant|code-agent|bot/iu.test(role)) return true;
  if (/user|human|client|prompt/iu.test(role)) return false;
  if (groupName === "turns") return isCodeAgentCardLike(item);
  const text = codeAgentCardText(item);
  if (isTerminalTurnStatus(item?.status) && /Code Agent|运行记录|assistant|agent/iu.test(text)) return true;
  return false;
}

function detectPostCompletionTimingChanges(turnTiming, event) {
  const timingChanges = [];
  const recentUpdateVisible = [];
  if (!event.traceId && !event.messageId) return { timingChanges, recentUpdateVisible };
  const rows = Array.isArray(turnTiming?.rows) ? turnTiming.rows : [];
  const columns = Array.isArray(turnTiming?.columns) ? turnTiming.columns : [];
  const eventTsMs = Date.parse(String(event.ts || ""));
  for (const column of columns) {
    if (column.pageRole && event.pageRole && column.pageRole !== event.pageRole) continue;
    if (event.traceId && column.traceId && column.traceId !== event.traceId) continue;
    if (event.messageId && column.messageId && column.messageId !== event.messageId) continue;
    if (event.promptIndex && column.promptIndex && column.promptIndex !== event.promptIndex && column.lastPromptIndex !== event.promptIndex) continue;
    let previousTotal = null;
    let previousRecent = null;
    for (const row of rows) {
      const rowTsMs = Date.parse(String(row.ts || ""));
      if (Number.isFinite(eventTsMs) && Number.isFinite(rowTsMs) && rowTsMs < eventTsMs) continue;
      if (row.pageRole && event.pageRole && row.pageRole !== event.pageRole) continue;
      const cell = row.cells?.[column.id];
      if (!cell) continue;
      if (event.traceId && cell.traceId && cell.traceId !== event.traceId) continue;
      if (event.messageId && cell.messageId && cell.messageId !== event.messageId) continue;
      const total = cell.totalElapsedSeconds === null || cell.totalElapsedSeconds === undefined ? NaN : Number(cell.totalElapsedSeconds);
      if (Number.isFinite(total)) {
        if (previousTotal && Math.abs(total - previousTotal.value) > alertThresholds.turnTimingSampleSlackSeconds) {
          timingChanges.push({
            ...eventRef(event),
            columnId: column.id,
            columnLabel: column.label,
            metric: "totalElapsedSeconds",
            fromSeq: previousTotal.seq,
            fromTs: previousTotal.ts,
            fromValue: previousTotal.value,
            toSeq: row.seq ?? null,
            toTs: row.ts ?? null,
            toValue: total,
            delta: Number((total - previousTotal.value).toFixed(3)),
            toleranceSeconds: alertThresholds.turnTimingSampleSlackSeconds,
            traceId: cell.traceId ?? column.traceId ?? event.traceId ?? null,
            messageId: cell.messageId ?? column.messageId ?? null,
            valuesRedacted: true
          });
        }
        previousTotal = { value: total, seq: row.seq ?? null, ts: row.ts ?? null };
      }
      const recent = cell.recentUpdateSeconds === null || cell.recentUpdateSeconds === undefined ? NaN : Number(cell.recentUpdateSeconds);
      if (Number.isFinite(recent)) {
        recentUpdateVisible.push({
          ...eventRef(event),
          columnId: column.id,
          columnLabel: column.label,
          metric: "recentUpdateSeconds",
          seq: row.seq ?? null,
          ts: row.ts ?? null,
          value: recent,
          traceId: cell.traceId ?? column.traceId ?? event.traceId ?? null,
          messageId: cell.messageId ?? column.messageId ?? null,
          valuesRedacted: true
        });
        if (previousRecent && recent !== previousRecent.value) {
          timingChanges.push({
            ...eventRef(event),
            columnId: column.id,
            columnLabel: column.label,
            metric: "recentUpdateSeconds",
            fromSeq: previousRecent.seq,
            fromTs: previousRecent.ts,
            fromValue: previousRecent.value,
            toSeq: row.seq ?? null,
            toTs: row.ts ?? null,
            toValue: recent,
            delta: Number((recent - previousRecent.value).toFixed(3)),
            traceId: cell.traceId ?? column.traceId ?? event.traceId ?? null,
            messageId: cell.messageId ?? column.messageId ?? null,
            valuesRedacted: true
          });
        }
        previousRecent = { value: recent, seq: row.seq ?? null, ts: row.ts ?? null };
      }
    }
  }
  return { timingChanges, recentUpdateVisible };
}

function dedupeRoundCompletionEvents(rows) {
  const result = [];
  const seen = new Set();
  for (const row of Array.isArray(rows) ? rows : []) {
    const key = [
      row?.pageRole ?? "",
      row?.pageId ?? "",
      row?.promptIndex ?? "",
      row?.traceId ?? "",
      row?.messageId ?? "",
      row?.textHash ?? "",
      row?.elapsedSeconds ?? ""
    ].join("|");
    if (seen.has(key)) continue;
    seen.add(key);
    result.push(row);
  }
  return result;
}

function eventRef(event) {
  return {
    seq: event?.seq ?? null,
    sampleGroupSeq: event?.sampleGroupSeq ?? null,
    ts: event?.ts ?? null,
    pageRole: event?.pageRole ?? null,
    pageId: event?.pageId ?? null,
    routeSessionId: event?.routeSessionId ?? null,
    activeSessionId: event?.activeSessionId ?? null,
    promptIndex: event?.promptIndex ?? null,
    traceId: event?.traceId ?? null,
    messageId: event?.messageId ?? null,
  };
}

function dedupeRoundCompletionRows(rows) {
  const result = [];
  const seen = new Set();
  for (const row of Array.isArray(rows) ? rows : []) {
    const key = [
      row?.seq ?? row?.fromSeq ?? "",
      row?.toSeq ?? "",
      row?.pageRole ?? "",
      row?.promptIndex ?? "",
      row?.traceId ?? "",
      row?.metric ?? "",
      row?.textHash ?? "",
      row?.columnId ?? ""
    ].join("|");
    if (seen.has(key)) continue;
    seen.add(key);
    result.push(row);
  }
  return result;
}

function turnMetricItems(sample, timelineItem) {
  const promptIndex = timelineItem.promptIndex ?? 0;
  const pageRole = sample?.pageRole || "control";
  const pageId = sample?.pageId || "unknown-page";
  const sessionKey = pageRole + ":" + pageId + ":" + (sample?.routeSessionId || sample?.activeSessionId || "unknown-session");
  const roundKey = String(promptIndex);
  const items = [];
  if (Array.isArray(sample?.turns) && sample.turns.length > 0) {
    for (const turn of sample.turns) {
      const texts = turnTexts(turn);
      const totalElapsedValues = texts.flatMap(parseTotalElapsedSeconds).filter(Number.isFinite);
      const recentUpdateValues = texts.flatMap(parseRecentUpdateSeconds).filter(Number.isFinite);
      const traceId = turn.traceId || firstTraceId(texts);
      const messageId = turn.messageId || null;
      const turnId = turn.turnId || traceId || null;
      const stableId = traceId || messageId || turnId || null;
      const domIndex = Number.isFinite(Number(turn.index)) ? Number(turn.index) : items.length;
      const key = stableId
        ? "timing:" + sessionKey + ":id-" + stableId
        : "turn:" + sessionKey + ":round-" + roundKey + ":dom-index-" + String(domIndex);
      items.push({
        key,
        source: "turn",
        pageRole,
        pageId,
        promptIndex,
        traceId,
        messageId,
        turnId,
        domIndex,
        status: turn.status ?? null,
        totalElapsedSeconds: totalElapsedValues.length > 0 ? Math.max(...totalElapsedValues) : null,
        recentUpdateSeconds: recentUpdateValues.length > 0 ? Math.max(...recentUpdateValues) : null,
        textHash: turn.textHash || sha256(texts.join("\n"))
      });
    }
    return items;
  }
  if (Array.isArray(sample?.messages) && sample.messages.length > 0) {
    for (const message of sample.messages) {
      const text = [message?.durationText, message?.activityText].map((value) => String(value || "")).filter((value) => value.trim().length > 0).join("\n");
      const totalElapsedValues = parseTotalElapsedSeconds(text).filter(Number.isFinite);
      const recentUpdateValues = parseRecentUpdateSeconds(text).filter(Number.isFinite);
      if (totalElapsedValues.length === 0 && recentUpdateValues.length === 0) continue;
      const domIndex = Number.isFinite(Number(message.index)) ? Number(message.index) : items.length;
      const traceId = message.traceId || firstTraceId([text]);
      const messageId = message.messageId || null;
      const stableId = traceId || messageId || message.turnId || null;
      items.push({
        key: stableId
          ? "timing:" + sessionKey + ":id-" + stableId
          : "message:" + sessionKey + ":round-" + roundKey + ":dom-index-" + String(domIndex),
        source: "message",
        pageRole,
        pageId,
        promptIndex,
        traceId,
        messageId,
        turnId: message.turnId || traceId || null,
        domIndex,
        status: message.status ?? null,
        totalElapsedSeconds: totalElapsedValues.length > 0 ? Math.max(...totalElapsedValues) : null,
        recentUpdateSeconds: recentUpdateValues.length > 0 ? Math.max(...recentUpdateValues) : null,
        textHash: message.textHash || sha256(text)
      });
    }
    if (items.length > 0) return items;
  }
  if (timelineItem.totalElapsedSeconds !== null || timelineItem.recentUpdateSeconds !== null) {
    return [{
      key: "aggregate:" + sessionKey + ":round-" + roundKey,
      source: "aggregate",
      pageRole,
      pageId,
      promptIndex,
      traceId: null,
      messageId: null,
      domIndex: null,
      status: null,
      totalElapsedSeconds: timelineItem.totalElapsedSeconds ?? null,
      recentUpdateSeconds: timelineItem.recentUpdateSeconds ?? null,
      textHash: timelineItem.textDigest ?? null
    }];
  }
  return [];
}

function turnTexts(turn) {
  return [
    turn?.durationText,
    turn?.activityText
  ].map((value) => String(value || "")).filter((value) => value.trim().length > 0);
}

function firstTraceId(texts) {
  for (const text of texts) {
    const match = String(text || "").match(/\btrc_[A-Za-z0-9_-]+\b/u);
    if (match) return match[0];
  }
  return null;
}

function buildRoundMetricSummaries(timeline, promptCommands, timing = {}) {
  const rounds = [];
  const timingColumns = Array.isArray(timing.columns) ? timing.columns : [];
  const timingRows = Array.isArray(timing.rows) ? timing.rows : [];
  const nonMonotonic = Array.isArray(timing.nonMonotonic) ? timing.nonMonotonic : [];
  const totalElapsedForwardJumps = Array.isArray(timing.totalElapsedForwardJumps) ? timing.totalElapsedForwardJumps : [];
  const elapsedZeroResets = Array.isArray(timing.elapsedZeroResets) ? timing.elapsedZeroResets : [];
  const terminalElapsedGrowth = Array.isArray(timing.terminalElapsedGrowth) ? timing.terminalElapsedGrowth : [];
  const recentUpdateResets = Array.isArray(timing.recentUpdateResets) ? timing.recentUpdateResets : [];
  const recentUpdateSteps = Array.isArray(timing.recentUpdateSteps) ? timing.recentUpdateSteps : [];
  for (let index = 0; index < promptCommands.length; index += 1) {
    const promptIndex = index + 1;
    const items = timeline.filter((item) => item.promptIndex === promptIndex);
    const aggregateTotalElapsed = items.map((item) => item.totalElapsedSeconds).filter((value) => value !== null);
    const aggregateRecentUpdate = items.map((item) => item.recentUpdateSeconds).filter((value) => value !== null);
    const promptTurnTiming = roundPromptTurnTimingValues(timingRows, timingColumns, promptIndex, {
      firstSeq: items[0]?.seq ?? null,
      firstSampleAt: items[0]?.ts ?? null
    });
    const totalElapsed = promptTurnTiming.totalElapsed.length > 0 ? promptTurnTiming.totalElapsed : aggregateTotalElapsed;
    const recentUpdate = promptTurnTiming.recentUpdate.length > 0 ? promptTurnTiming.recentUpdate : aggregateRecentUpdate;
    const loadingCounts = items.map((item) => Number(item.loadingCount ?? 0)).filter(Number.isFinite);
    const loadingOwners = new Set();
    for (const item of items) {
      for (const owner of Array.isArray(item.loadingOwners) ? item.loadingOwners : []) {
        if (owner?.ownerKey) loadingOwners.add(owner.ownerKey);
      }
    }
    const timingAnomalies = nonMonotonic.filter((item) => item.promptIndex === promptIndex);
    const timingForwardJumps = totalElapsedForwardJumps.filter((item) => item.promptIndex === promptIndex);
    const timingZeroResets = elapsedZeroResets.filter((item) => item.promptIndex === promptIndex);
    const timingTerminalGrowth = terminalElapsedGrowth.filter((item) => item.promptIndex === promptIndex);
    const timingResets = recentUpdateResets.filter((item) => item.promptIndex === promptIndex);
    const timingSteps = recentUpdateSteps.filter((item) => item.promptIndex === promptIndex);
    const terminalGrowthDeltas = timingTerminalGrowth.map((item) => Number(item.delta)).filter((value) => Number.isFinite(value) && value > 0);
    const timingStepDeltas = timingSteps.map((item) => Number(item.delta)).filter((value) => Number.isFinite(value) && value >= 0);
    const timingStepExcess = timingSteps.map((item) => Number(item.excessiveIncreaseSeconds)).filter((value) => Number.isFinite(value) && value > 0);
    rounds.push({
      promptIndex,
      promptCommandId: promptCommands[index].commandId,
      promptTextHash: promptCommands[index].textHash,
      promptTextBytes: promptCommands[index].textBytes,
      promptCompletedAt: promptCommands[index].ts,
      sampleCount: items.length,
      firstSeq: items[0]?.seq ?? null,
      lastSeq: items[items.length - 1]?.seq ?? null,
      firstSampleAt: items[0]?.ts ?? null,
      lastSampleAt: items[items.length - 1]?.ts ?? null,
      withTotalElapsed: totalElapsed.length,
      withRecentUpdate: recentUpdate.length,
      loadingSamples: loadingCounts.filter((value) => value > 0).length,
      maxLoadingCount: loadingCounts.length > 0 ? Math.max(...loadingCounts) : 0,
      loadingOwnerCount: loadingOwners.size,
      maxTotalElapsedSeconds: totalElapsed.length > 0 ? Math.max(...totalElapsed) : null,
      lastTotalElapsedSeconds: lastNonNull(totalElapsed),
      maxRecentUpdateSeconds: recentUpdate.length > 0 ? Math.max(...recentUpdate) : null,
      lastRecentUpdateSeconds: lastNonNull(recentUpdate),
      diagnosticSamples: items.filter((item) => item.diagnosticSeen).length,
      terminalSamples: items.filter((item) => item.terminalSeen).length,
      finalTextSamples: items.filter((item) => item.finalResultTextSeen).length,
      turnTimingNonMonotonicCount: timingAnomalies.length,
      turnTimingTotalElapsedDecreaseCount: timingAnomalies.filter((item) => item.metric === "totalElapsedSeconds").length,
      turnTimingTotalElapsedZeroResetCount: timingZeroResets.length,
      turnTimingTotalElapsedForwardJumpCount: timingForwardJumps.length,
      turnTimingTotalElapsedForwardJumpMaxSeconds: maxPositiveDelta(timingForwardJumps),
      turnTimingTerminalElapsedGrowthCount: timingTerminalGrowth.length,
      turnTimingTerminalElapsedGrowthMaxSeconds: terminalGrowthDeltas.length > 0 ? Math.max(...terminalGrowthDeltas) : 0,
      turnTimingRecentUpdateJumpCount: timingAnomalies.filter((item) => item.metric === "recentUpdateSeconds" && item.anomaly === "jump").length,
      turnTimingRecentUpdateSawtoothJumpCount: timingAnomalies.filter((item) => item.metric === "recentUpdateSeconds" && item.anomaly === "jump").length,
      turnTimingRecentUpdateStepCount: timingSteps.length,
      turnTimingRecentUpdateMaxIncreaseSeconds: timingStepDeltas.length > 0 ? Math.max(...timingStepDeltas) : null,
      turnTimingRecentUpdateMaxExcessSeconds: timingStepExcess.length > 0 ? Math.max(...timingStepExcess) : 0,
      turnTimingRecentUpdateResetCount: timingResets.length,
      turnTimingRecentUpdateDecreaseCount: timingResets.length
    });
  }
  return rounds;
}

function roundPromptTurnTimingValues(rows, columns, promptIndex, round = {}) {
  const roundFirstSeq = Number(round.firstSeq);
  const roundFirstMs = Date.parse(String(round.firstSampleAt ?? ""));
  const seqSlack = 3;
  const timeSlackMs = 3000;
  const promptColumnIds = new Set(columns
    .filter((column) => {
      if (Number(column?.promptIndex) === Number(promptIndex)) return true;
      const firstSeq = Number(column?.firstSeq);
      if (Number.isFinite(roundFirstSeq) && Number.isFinite(firstSeq) && firstSeq >= roundFirstSeq - seqSlack) return true;
      const firstMs = Date.parse(String(column?.firstTs ?? ""));
      return Number.isFinite(roundFirstMs) && Number.isFinite(firstMs) && firstMs >= roundFirstMs - timeSlackMs;
    })
    .map((column) => String(column?.id || ""))
    .filter(Boolean));
  if (promptColumnIds.size === 0) return { totalElapsed: [], recentUpdate: [] };
  const totalElapsed = [];
  const recentUpdate = [];
  for (const row of rows) {
    if (Number(row?.promptIndex ?? 0) !== Number(promptIndex)) continue;
    const cells = row?.cells && typeof row.cells === "object" ? row.cells : {};
    for (const [columnId, cell] of Object.entries(cells)) {
      if (!promptColumnIds.has(columnId)) continue;
      const total = Number(cell?.totalElapsedSeconds);
      if (Number.isFinite(total)) totalElapsed.push(total);
      const recent = Number(cell?.recentUpdateSeconds);
      if (Number.isFinite(recent)) recentUpdate.push(recent);
    }
  }
  return { totalElapsed, recentUpdate };
}

function sampleTexts(sample) {
  const rows = [];
  for (const group of [sample?.messages, sample?.traceRows, sample?.diagnostics]) {
    if (!Array.isArray(group)) continue;
    for (const item of group) {
      const text = String(item?.textPreview || "");
      if (text.trim()) rows.push(text);
    }
  }
  return rows;
}

function sampleTurnTimingTexts(sample) {
  const rows = [];
  for (const group of [sample?.turns, sample?.messages]) {
    if (!Array.isArray(group)) continue;
    for (const item of group) {
      for (const value of [item?.durationText, item?.activityText]) {
        const text = String(value || "");
        if (text.trim()) rows.push(text);
      }
    }
  }
  return rows;
}

function parseTotalElapsedSeconds(text) {
  const values = [];
  for (const match of String(text || "").matchAll(/(?:总耗时|耗时)\s*[=:：]?\s*(\d{1,2}):(\d{2}):(\d{2})/giu)) {
    values.push(Number(match[1]) * 3600 + Number(match[2]) * 60 + Number(match[3]));
  }
  for (const match of String(text || "").matchAll(/(?:总耗时|耗时)\s*[=:：]?\s*(\d{1,2}):(\d{2})(?!:)/giu)) {
    values.push(Number(match[1]) * 60 + Number(match[2]));
  }
  for (const match of String(text || "").matchAll(/(?:总耗时|耗时)\s*[=:：]?\s*(?:(\d+)\s*天)?\s*(?:(\d+)\s*小时)?\s*(?:(\d+)\s*(?:分钟|分))?\s*(?:(\d+)\s*秒)?/giu)) {
    const days = Number(match[1] || 0);
    const hours = Number(match[2] || 0);
    const minutes = Number(match[3] || 0);
    const seconds = Number(match[4] || 0);
    if (days || hours || minutes || seconds || /(?:天|小时|分钟|分|秒)/u.test(match[0] || "")) values.push(days * 86400 + hours * 3600 + minutes * 60 + seconds);
  }
  return values;
}

function lastNonNull(values) {
  for (let index = values.length - 1; index >= 0; index -= 1) if (values[index] !== null && values[index] !== undefined) return values[index];
  return null;
}

function parseRecentUpdateSeconds(text) {
  const values = [];
  for (const match of String(text || "").matchAll(/最近\s*(?:(\d+)\s*天)?\s*(?:(\d+)\s*小时)?\s*(?:(\d+)\s*(?:分钟|分))?\s*(?:(\d+)\s*秒)?\s*前/giu)) {
    const days = Number(match[1] || 0);
    const hours = Number(match[2] || 0);
    const minutes = Number(match[3] || 0);
    const seconds = Number(match[4] || 0);
    values.push(days * 86400 + hours * 3600 + minutes * 60 + seconds);
  }
  return values;
}

function latestPromptIndex(promptTimes, tsMs) {
  let index = 0;
  for (let i = 0; i < promptTimes.length; i += 1) {
    if (promptTimes[i] <= tsMs) index = i + 1;
    else break;
  }
  return index;
}

function promptIndexForTs(promptTimes, ts) {
  const tsMs = Date.parse(ts);
  return Number.isFinite(tsMs) ? latestPromptIndex(promptTimes, tsMs) : 0;
}

function buildTransitions(samples) {
  const rows = [];
  let last = null;
  for (const sample of samples) {
    const digest = digestSample(sample);
    if (digest !== last) {
      rows.push({ seq: sample.seq, ts: sample.ts, url: sample.url, routeSessionId: sample.routeSessionId || null, activeSessionId: sample.activeSessionId || null, messageCount: Array.isArray(sample.messages) ? sample.messages.length : 0, traceRowCount: Array.isArray(sample.traceRows) ? sample.traceRows.length : 0, digest });
      last = digest;
    }
  }
  return rows.slice(0, 200);
}

function detectFinalFlicker(samples) {
  const flickers = [];
  const lastNonEmptyByScope = new Map();
  for (const sample of samples) {
    const scope = finalFlickerScope(sample);
    if (!scope) continue;
    const messageText = Array.isArray(sample.messages) ? sample.messages.map((item) => item.textPreview || "").join("\n") : "";
    const nonEmpty = messageText.trim().length > 0;
    const finalLike = /轮次完成|已记录|已完成第\d+轮|final response|terminal result/iu.test(messageText);
    const diagnosticLike = /temporarily|timeout|无法连接|暂时|error|failed|超时/iu.test(messageText);
    const lastNonEmpty = lastNonEmptyByScope.get(scope);
    if (nonEmpty && finalLike && !diagnosticLike) lastNonEmptyByScope.set(scope, { sample, messageText });
    if (lastNonEmpty && nonEmpty && diagnosticLike) flickers.push({ scope, from: ref(lastNonEmpty.sample), to: ref(sample) });
    if (lastNonEmpty && !nonEmpty) flickers.push({ scope, from: ref(lastNonEmpty.sample), to: ref(sample), reason: "text-disappeared" });
  }
  return flickers;
}

function finalFlickerScope(sample) {
  const pathname = samplePathname(sample);
  const sessionId = sample?.routeSessionId || sample?.activeSessionId || workbenchSessionIdFromPath(pathname);
  if (!sessionId) return null;
  if (!pathname.startsWith("/workbench/sessions/" + sessionId)) return null;
  return (sample?.pageRole || "control") + ":" + sessionId;
}

function samplePathname(sample) {
  const raw = String(sample?.path || sample?.url || "").trim();
  if (!raw) return "";
  try {
    return new URL(raw, "http://hwlab.local").pathname || raw;
  } catch {
    return raw.split(/[?#]/u, 1)[0] || raw;
  }
}

function workbenchSessionIdFromPath(pathname) {
  const match = String(pathname || "").match(/^\/workbench\/sessions\/([^/?#]+)/u);
  return match ? match[1] : null;
}

function detectTerminalZeroElapsed(samples) {
  const rows = [];
  for (const sample of samples) {
    const turns = Array.isArray(sample?.turns) ? sample.turns : [];
    const messages = Array.isArray(sample?.messages) ? sample.messages : [];
    for (const item of [...turns, ...messages]) {
      const text = [item?.durationText, item?.activityText, item?.status, item?.textPreview, item?.text].filter(Boolean).join("\n");
      if (!/(?:Code Agent|运行记录|completed|failed|canceled|blocked)/iu.test(text)) continue;
      if (!/(?:completed|failed|canceled|blocked|已完成|失败|取消)/iu.test(text)) continue;
      const timingText = [item?.durationText, item?.activityText].filter(Boolean).join("\n");
      const elapsedValues = parseTotalElapsedSeconds(timingText);
      if (!elapsedValues.includes(0)) continue;
      rows.push({
        ...ref(sample),
        status: item?.status ?? null,
        messageId: item?.messageId ?? null,
        traceId: item?.traceId ?? null,
        durationText: item?.durationText ?? null,
        activityText: item?.activityText ?? null,
        textPreview: limitText(item?.textPreview || item?.text || "", 180)
      });
    }
  }
  return rows;
}

function detectCrossPageProjectionDiffs(samples) {
  const groups = new Map();
  for (const sample of samples) {
    const key = sample?.sampleGroupSeq ?? sample?.seq;
    if (key === null || key === undefined) continue;
    const group = groups.get(key) || {};
    if (sample?.pageRole === "control") group.control = sample;
    else if (sample?.pageRole === "observer") group.observer = sample;
    groups.set(key, group);
  }
  const rows = [];
  for (const [sampleGroupSeq, group] of groups.entries()) {
    const control = group.control;
    const observer = group.observer;
    if (!control || !observer) continue;
    const controlTraceIds = visibleTraceIds(control);
    const observerTraceIds = visibleTraceIds(observer);
    const missingInObserver = [...controlTraceIds].filter((item) => !observerTraceIds.has(item));
    const controlMessages = Array.isArray(control.messages) ? control.messages.length : 0;
    const observerMessages = Array.isArray(observer.messages) ? observer.messages.length : 0;
    const controlTraceRows = Array.isArray(control.traceRows) ? control.traceRows.length : 0;
    const observerTraceRows = Array.isArray(observer.traceRows) ? observer.traceRows.length : 0;
    const controlZero = detectTerminalZeroElapsed([control]).length > 0;
    const observerZero = detectTerminalZeroElapsed([observer]).length > 0;
    const sameSession = (control.routeSessionId || control.activeSessionId || null) && (control.routeSessionId || control.activeSessionId || null) === (observer.routeSessionId || observer.activeSessionId || null);
    const controlMessageDigest = digestMessageTexts(control);
    const observerMessageDigest = digestMessageTexts(observer);
    const messageTextDigestDiff = controlMessageDigest !== observerMessageDigest;
    const projectionDivergent = sameSession && (Math.abs(controlMessages - observerMessages) > 0 || controlZero !== observerZero);
    const traceVisibilityDivergent = sameSession && !projectionDivergent && (missingInObserver.length > 0 || Math.abs(controlTraceRows - observerTraceRows) > 0);
    if (!projectionDivergent && !traceVisibilityDivergent) continue;
    rows.push({
      sampleGroupSeq,
      diffKind: traceVisibilityDivergent ? "trace-visibility" : "projection",
      control: ref(control),
      observer: ref(observer),
      controlTraceIds: [...controlTraceIds].slice(0, 8),
      observerTraceIds: [...observerTraceIds].slice(0, 8),
      missingTraceIdsInObserver: missingInObserver.slice(0, 8),
      controlMessageCount: controlMessages,
      observerMessageCount: observerMessages,
      controlTraceRowCount: controlTraceRows,
      observerTraceRowCount: observerTraceRows,
      terminalZeroElapsedDiff: controlZero !== observerZero,
      messageTextDigestDiff,
      controlMessageDigest,
      observerMessageDigest
    });
  }
  return rows;
}

function mergeCrossPageDiffRows(...groups) {
  const rows = [];
  const seen = new Set();
  for (const group of groups) {
    if (!Array.isArray(group)) continue;
    for (const row of group) {
      const key = [
        row?.diffKind || "projection",
        row?.control?.seq ?? null,
        row?.observer?.seq ?? null,
        row?.controlMessageCount ?? null,
        row?.observerMessageCount ?? null,
        row?.controlTraceRowCount ?? null,
        row?.observerTraceRowCount ?? null
      ].join(":");
      if (seen.has(key)) continue;
      seen.add(key);
      rows.push(row);
    }
  }
  return rows;
}

function annotateCrossPageDiffTiming(rows) {
  const groups = new Map();
  for (const row of Array.isArray(rows) ? rows : []) {
    const controlAt = Date.parse(String(row?.control?.ts || ""));
    const observerAt = Date.parse(String(row?.observer?.ts || ""));
    const timestamps = [controlAt, observerAt].filter(Number.isFinite);
    const startMs = timestamps.length > 0 ? Math.min(...timestamps) : null;
    const endMs = timestamps.length > 0 ? Math.max(...timestamps) : null;
    const sessionId = row?.control?.routeSessionId || row?.control?.activeSessionId || row?.observer?.routeSessionId || row?.observer?.activeSessionId || "unknown-session";
    const key = [row?.diffKind || "projection", sessionId].join(":");
    const group = groups.get(key) || { rows: [], firstMs: null, lastMs: null };
    const annotated = {
      ...row,
      sampleStartAt: startMs === null ? null : new Date(startMs).toISOString(),
      sampleEndAt: endMs === null ? null : new Date(endMs).toISOString(),
      pairSkewMs: startMs === null || endMs === null ? null : endMs - startMs,
    };
    group.rows.push(annotated);
    if (startMs !== null && (group.firstMs === null || startMs < group.firstMs)) group.firstMs = startMs;
    if (endMs !== null && (group.lastMs === null || endMs > group.lastMs)) group.lastMs = endMs;
    groups.set(key, group);
  }
  const result = [];
  for (const group of groups.values()) {
    const sortedRows = group.rows.slice().sort((a, b) => Number(Date.parse(String(a.sampleStartAt || ""))) - Number(Date.parse(String(b.sampleStartAt || ""))));
    const segments = [];
    const splitGapMs = Math.max(1000, Number(alertThresholds.crossPageProjectionDivergenceRedMs || alertThresholds.visibleLoadingSlowMs || 10_000));
    for (const row of sortedRows) {
      const startMs = Date.parse(String(row.sampleStartAt || ""));
      const endMs = Date.parse(String(row.sampleEndAt || row.sampleStartAt || ""));
      const last = segments.at(-1);
      const lastEndMs = last && last.lastMs !== null ? last.lastMs : null;
      if (!last || (Number.isFinite(startMs) && lastEndMs !== null && startMs - lastEndMs > splitGapMs)) {
        segments.push({ rows: [row], firstMs: Number.isFinite(startMs) ? startMs : null, lastMs: Number.isFinite(endMs) ? endMs : Number.isFinite(startMs) ? startMs : null });
        continue;
      }
      last.rows.push(row);
      if (Number.isFinite(startMs) && (last.firstMs === null || startMs < last.firstMs)) last.firstMs = startMs;
      const effectiveEndMs = Number.isFinite(endMs) ? endMs : Number.isFinite(startMs) ? startMs : null;
      if (effectiveEndMs !== null && (last.lastMs === null || effectiveEndMs > last.lastMs)) last.lastMs = effectiveEndMs;
    }
    for (let segmentIndex = 0; segmentIndex < segments.length; segmentIndex += 1) {
      const segment = segments[segmentIndex];
      const observedSpanMs = segment.firstMs === null || segment.lastMs === null ? null : segment.lastMs - segment.firstMs;
      for (const row of segment.rows) {
      result.push({
        ...row,
        segmentIndex,
        observedFirstAt: segment.firstMs === null ? null : new Date(segment.firstMs).toISOString(),
        observedLastAt: segment.lastMs === null ? null : new Date(segment.lastMs).toISOString(),
        observedSpanMs,
      });
      }
    }
  }
  return result;
}

function detectAdjacentCrossPageProjectionDiffs(samples) {
  const rows = [];
  const ordered = (Array.isArray(samples) ? samples : []).slice().sort((a, b) => Number(a?.seq ?? 0) - Number(b?.seq ?? 0));
  for (let i = 1; i < ordered.length; i += 1) {
    const a = ordered[i - 1];
    const b = ordered[i];
    const roles = new Set([a?.pageRole, b?.pageRole]);
    if (!roles.has("control") || !roles.has("observer")) continue;
    const control = a?.pageRole === "control" ? a : b;
    const observer = a?.pageRole === "observer" ? a : b;
    const controlSession = control.routeSessionId || control.activeSessionId || null;
    const observerSession = observer.routeSessionId || observer.activeSessionId || null;
    if (!controlSession || controlSession !== observerSession) continue;
    const controlAt = Date.parse(String(control.ts || ""));
    const observerAt = Date.parse(String(observer.ts || ""));
    if (Number.isFinite(controlAt) && Number.isFinite(observerAt) && Math.abs(controlAt - observerAt) > 1500) continue;
    const controlMessages = Array.isArray(control.messages) ? control.messages.length : 0;
    const observerMessages = Array.isArray(observer.messages) ? observer.messages.length : 0;
    const controlTraceRows = Array.isArray(control.traceRows) ? control.traceRows.length : 0;
    const observerTraceRows = Array.isArray(observer.traceRows) ? observer.traceRows.length : 0;
    const controlZero = detectTerminalZeroElapsed([control]).length > 0;
    const observerZero = detectTerminalZeroElapsed([observer]).length > 0;
    const missingInObserver = [...visibleTraceIds(control)].filter((item) => !visibleTraceIds(observer).has(item));
    const controlTraceIds = visibleTraceIds(control);
    const observerTraceIds = visibleTraceIds(observer);
    const controlMessageDigest = digestMessageTexts(control);
    const observerMessageDigest = digestMessageTexts(observer);
    const messageTextDigestDiff = controlMessageDigest !== observerMessageDigest;
    const projectionDivergent = controlMessages !== observerMessages || controlZero !== observerZero;
    const traceVisibilityDivergent = !projectionDivergent && (missingInObserver.length > 0 || controlTraceRows !== observerTraceRows);
    if (!projectionDivergent && !traceVisibilityDivergent) continue;
    rows.push({
      sampleGroupSeq: control.sampleGroupSeq ?? observer.sampleGroupSeq ?? null,
      adjacentPair: true,
      diffKind: traceVisibilityDivergent ? "trace-visibility" : "projection",
      control: ref(control),
      observer: ref(observer),
      controlTraceIds: [...controlTraceIds].slice(0, 8),
      observerTraceIds: [...observerTraceIds].slice(0, 8),
      missingTraceIdsInObserver: missingInObserver.slice(0, 8),
      controlMessageCount: controlMessages,
      observerMessageCount: observerMessages,
      controlTraceRowCount: controlTraceRows,
      observerTraceRowCount: observerTraceRows,
      terminalZeroElapsedDiff: controlZero !== observerZero,
      messageTextDigestDiff,
      controlMessageDigest,
      observerMessageDigest
    });
  }
  return rows;
}

function detectTraceMessageDuplication(samples) {
  const rows = [];
  for (const sample of samples) {
    const traceRows = Array.isArray(sample?.traceRows) ? sample.traceRows : [];
    const groups = new Map();
    for (let fallbackIndex = 0; fallbackIndex < traceRows.length; fallbackIndex += 1) {
      const row = traceRows[fallbackIndex];
      const rowTextRaw = String(row?.textPreview || row?.text || "");
      if (!/(?:助手消息|assistant\s+message|assistant)/iu.test(rowTextRaw)) continue;
      const rowText = normalizedText(rowTextRaw);
      if (rowText.length < 24) continue;
      const traceId = row?.traceId === undefined || row?.traceId === null ? "" : String(row.traceId);
      const key = traceId + "\u0000" + rowText;
      const group = groups.get(key) ?? { traceId: traceId || null, rowText, rowTextRaw, rows: [] };
      group.rows.push({ row, fallbackIndex });
      groups.set(key, group);
    }
    for (const group of groups.values()) {
      if (group.rows.length < 2) continue;
      rows.push({
        ...ref(sample),
        traceId: group.traceId,
        visibleAssistantFinalRowCount: group.rows.length,
        rowIndexes: group.rows.map((item) => item.row?.index ?? item.fallbackIndex).slice(0, 12),
        rowTextHash: sha256(group.rowText),
        rowTextPreview: limitText(group.rowTextRaw, 180),
        finalResponseSummaryBlockCounted: false,
        traceFrameSource: "traceRows-only"
      });
    }
  }
  return rows;
}

function detectTurnTraceIdMissing(samples) {
  const rows = [];
  for (const sample of samples) {
    for (const item of Array.isArray(sample?.turns) ? sample.turns : []) {
      const text = [item?.status, item?.durationText, item?.activityText, item?.textPreview, item?.text].filter(Boolean).join("\n");
      if (!/(?:Code Agent|运行记录|耗时|最近)/iu.test(text)) continue;
      if (item?.traceId) continue;
      rows.push({ ...ref(sample), status: item?.status ?? null, messageId: item?.messageId ?? null, textPreview: limitText(item?.textPreview || item?.text || "", 180) });
    }
  }
  return rows;
}

function visibleTraceIds(sample) {
  const ids = new Set();
  for (const group of [sample?.turns, sample?.messages, sample?.traceRows]) {
    if (!Array.isArray(group)) continue;
    for (const item of group) if (item?.traceId) ids.add(String(item.traceId));
  }
  return ids;
}

function digestMessageTexts(sample) {
  return sha256((Array.isArray(sample?.messages) ? sample.messages : []).map((item) => item?.textHash || normalizedText(item?.textPreview || item?.text || "")).join("|"));
}

function normalizedText(value) {
  return String(value || "").replace(/\s+/gu, " ").trim();
}

function longestSharedSubstringLength(a, b) {
  if (!a || !b) return 0;
  const left = a.length <= b.length ? a : b;
  const right = a.length <= b.length ? b : a;
  const max = Math.min(left.length, 280);
  let best = 0;
  for (let start = 0; start < max; start += 1) {
    for (let end = Math.min(max, start + 160); end > start + best; end -= 1) {
      if (right.includes(left.slice(start, end))) {
        best = end - start;
        break;
      }
    }
  }
  return best;
}

function digestSample(sample) {
  const messages = Array.isArray(sample.messages) ? sample.messages.map((item) => stableDigestItem(item, ["dataRole", "role", "status", "sessionId", "messageId", "traceId", "turnId"])).join("|") : "";
  const trace = Array.isArray(sample.traceRows) ? sample.traceRows.map((item) => stableDigestItem(item, ["status", "sessionId", "messageId", "traceId", "turnId", "projectedSeq", "sourceSeq", "eventSeq", "eventKind"])).join("|") : "";
  const diagnostics = Array.isArray(sample.diagnostics) ? sample.diagnostics.map((item) => stableDigestItem(item, ["className", "status", "sessionId", "messageId", "traceId", "turnId", "diagnosticCode"])).join("|") : "";
  return sha256((sample.routeSessionId || "") + "|" + (sample.activeSessionId || "") + "|" + messages + "|" + trace + "|" + diagnostics);
}

function samplePageKey(sample) {
  return String(sample?.pageRole || "control") + ":" + String(sample?.pageId || "default");
}

function stableDigestItem(item, fields) {
  if (!item || typeof item !== "object") return "";
  const identity = fields.map((field) => String(item?.[field] ?? "")).join(":");
  return identity + ":" + stableVisibleDigestText(item?.textPreview || item?.text || item?.textHash || "");
}

function stableVisibleDigestText(value) {
  return normalizedText(value)
    .replace(/\btotal=\d{1,2}:\d{2}:\d{2}\b/giu, "total=<duration>")
    .replace(/(?:总耗时|耗时)\s*[=:：]?\s*(?:(?:\d+\s*天)?\s*(?:\d+\s*小时)?\s*(?:\d+\s*(?:分钟|分))?\s*(?:\d+\s*秒)?|\d{1,2}:\d{2}(?::\d{2})?)/giu, "耗时 <duration>")
    .replace(/最近\s*(?:(?:\d+\s*天)?\s*(?:\d+\s*小时)?\s*(?:\d+\s*(?:分钟|分))?\s*(?:\d+\s*秒)?)\s*前/giu, "最近 <duration>前");
}

function nearCommand(sample, commandTimes, windowMs) {
  const ts = Date.parse(sample.ts);
  return Number.isFinite(ts) && commandTimes.some((item) => Math.abs(ts - item) <= windowMs);
}

function sampleRefs(samples, pick) {
  const seen = new Set();
  const refs = [];
  for (const sample of samples) {
    const value = pick(sample);
    if (!value || seen.has(value)) continue;
    seen.add(value);
    refs.push({ ...ref(sample), value });
  }
  return refs.slice(0, 20);
}

function ref(sample) {
  if (!sample) return null;
  return { seq: sample.seq ?? null, sampleGroupSeq: sample.sampleGroupSeq ?? null, ts: sample.ts ?? null, pageRole: sample.pageRole ?? null, pageId: sample.pageId ?? null, url: sample.url ?? null, routeSessionId: sample.routeSessionId ?? null, activeSessionId: sample.activeSessionId ?? null };
}

async function artifactSummary(artifacts) {
  const items = artifacts.slice(-30).map((item) => ({ kind: item.kind, reason: item.reason, sampleSeq: item.sampleSeq, path: item.path, sha256: item.sha256, byteCount: item.byteCount }));
  return { count: artifacts.length, latest: items };
}

function compactManifest(value) {
  if (!value) return null;
  return { jobId: value.jobId, stateDir: value.stateDir, baseUrl: value.baseUrl, targetPath: value.targetPath, startedAt: value.startedAt, status: value.status, pageAuthority: value.pageAuthority ?? null, navigation: value.navigation ?? null, sampling: value.sampling, pageProvenance: value.pageProvenance ?? null, safety: value.safety };
}

function compactHeartbeat(value) {
  if (!value) return null;
  return { jobId: value.jobId, pid: value.pid, status: value.status, sampleSeq: value.sampleSeq, commandSeq: value.commandSeq, pageId: value.pageId ?? null, observerPageId: value.observerPageId ?? null, currentUrl: value.currentUrl, observerUrl: value.observerUrl ?? null, observerRefreshIntervalMs: value.observerRefreshIntervalMs ?? null, lastObserverRefreshAt: value.lastObserverRefreshAt ?? null, pageProvenance: value.pageProvenance ?? null, updatedAt: value.updatedAt, uptimeMs: value.uptimeMs };
}

function renderTurnTimingTable(sampleMetrics) {
  const columns = Array.isArray(sampleMetrics?.turnColumns) ? sampleMetrics.turnColumns : [];
  const rows = Array.isArray(sampleMetrics?.turnTimingTable) ? sampleMetrics.turnTimingTable : [];
  const disclosure = sampleMetrics?.turnTimingTableDisclosure || null;
  if (columns.length === 0 || rows.length === 0) return "- 无 turn 时间表。";
  const header = ["时间戳"];
  for (const column of columns) {
    const columnLabel = formatTurnColumnDisplayLabel(column);
    header.push(columnLabel + " 总耗时(s)");
    header.push(columnLabel + " 最近更新(s)");
  }
  const lines = [];
  lines.push("| " + header.map(escapeMarkdownCell).join(" | ") + " |");
  lines.push("| " + header.map(() => "---").join(" | ") + " |");
  for (const row of rows) {
    const cells = [row.ts || "-"];
    for (const column of columns) {
      const cell = row.cells?.[column.id] || {};
      cells.push(formatMetricCell(cell.totalElapsedSeconds));
      cells.push(formatMetricCell(cell.recentUpdateSeconds));
    }
    lines.push("| " + cells.map(escapeMarkdownCell).join(" | ") + " |");
  }
  const columnLines = columns.map((column) => "- " + formatTurnColumnDisplayLabel(column) + ": pageRole=" + (column.pageRole || "-") + " pageId=" + (column.pageId || "-") + " source=" + (column.source || "-") + " prompt=" + (column.promptIndex ?? "-") + " lastPrompt=" + (column.lastPromptIndex ?? "-") + " firstSeq=" + (column.firstSeq ?? "-") + " lastSeq=" + (column.lastSeq ?? "-") + " traceId=" + (column.traceId || "-") + " messageId=" + (column.messageId || "-")).join("\n");
  const nonMonotonic = Array.isArray(sampleMetrics?.turnTimingNonMonotonic) ? sampleMetrics.turnTimingNonMonotonic : [];
  const nonMonotonicLines = nonMonotonic.length > 0
    ? nonMonotonic.slice(0, 80).map((item) => "- " + formatTurnEventDisplayLabel(item) + " " + item.metric + (item.anomaly ? " " + item.anomaly : "") + " " + (item.fromValue ?? "-") + " -> " + (item.toValue ?? "-") + " delta=" + (item.delta ?? "-") + " sampleDelta=" + (item.sampleDeltaSeconds ?? "-") + " allowed=" + (item.allowedIncreaseSeconds ?? "-") + formatTimingMeta(item) + " seq " + (item.fromSeq ?? "-") + " -> " + (item.toSeq ?? "-") + " ts " + (item.fromTs || "-") + " -> " + (item.toTs || "-") + " traceId=" + (item.traceId || "-")).join("\n")
    : "- 未观察到总耗时下降或最近更新异常跳增。";
  const terminalGrowth = Array.isArray(sampleMetrics?.turnTimingTerminalElapsedGrowth) ? sampleMetrics.turnTimingTerminalElapsedGrowth : [];
  const terminalGrowthLines = terminalGrowth.length > 0
    ? terminalGrowth.slice(0, 80).map((item) => "- " + formatTurnEventDisplayLabel(item) + " terminal totalElapsed growth " + (item.fromValue ?? "-") + " -> " + (item.toValue ?? "-") + " delta=" + (item.delta ?? "-") + " status " + (item.fromStatus || "-") + " -> " + (item.toStatus || "-") + formatTimingMeta(item) + " seq " + (item.fromSeq ?? "-") + " -> " + (item.toSeq ?? "-") + " ts " + (item.fromTs || "-") + " -> " + (item.toTs || "-") + " traceId=" + (item.traceId || "-")).join("\n")
    : "- 未观察到 terminal 后总耗时增长。";
  const elapsedZeroResets = Array.isArray(sampleMetrics?.turnTimingElapsedZeroResets) ? sampleMetrics.turnTimingElapsedZeroResets : [];
  const elapsedZeroResetLines = elapsedZeroResets.length > 0
    ? elapsedZeroResets.slice(0, 80).map((item) => "- " + formatTurnEventDisplayLabel(item) + " totalElapsed zero-reset " + (item.fromValue ?? "-") + " -> " + (item.toValue ?? "-") + " delta=" + (item.delta ?? "-") + formatTimingMeta(item) + " seq " + (item.fromSeq ?? "-") + " -> " + (item.toSeq ?? "-") + " ts " + (item.fromTs || "-") + " -> " + (item.toTs || "-") + " traceId=" + (item.traceId || "-")).join("\n")
    : "- 未观察到总耗时从非零跳回 0 秒。";
  const totalElapsedForwardJumps = Array.isArray(sampleMetrics?.turnTimingTotalElapsedForwardJumps) ? sampleMetrics.turnTimingTotalElapsedForwardJumps : [];
  const totalElapsedForwardJumpLines = totalElapsedForwardJumps.length > 0
    ? totalElapsedForwardJumps.slice(0, 80).map((item) => "- " + formatTurnEventDisplayLabel(item) + " totalElapsed forward-jump " + (item.fromValue ?? "-") + " -> " + (item.toValue ?? "-") + " delta=" + (item.delta ?? "-") + " sampleDelta=" + (item.sampleDeltaSeconds ?? "-") + " allowed=" + (item.allowedIncreaseSeconds ?? "-") + formatTimingMeta(item) + " seq " + (item.fromSeq ?? "-") + " -> " + (item.toSeq ?? "-") + " ts " + (item.fromTs || "-") + " -> " + (item.toTs || "-") + " traceId=" + (item.traceId || "-")).join("\n")
    : "- 未观察到总耗时超出采样间隔的异常前跳。";
  const sawtoothJumps = Array.isArray(sampleMetrics?.turnTimingRecentUpdateSawtoothJumps)
    ? sampleMetrics.turnTimingRecentUpdateSawtoothJumps
    : nonMonotonic.filter((item) => item.metric === "recentUpdateSeconds" && item.anomaly === "jump");
  const sawtoothJumpLines = sawtoothJumps.length > 0
    ? sawtoothJumps.slice(0, 80).map((item) => "- " + formatTurnEventDisplayLabel(item) + " recentUpdate sawtooth-jump " + (item.fromValue ?? "-") + " -> " + (item.toValue ?? "-") + " delta=" + (item.delta ?? "-") + " sampleDelta=" + (item.sampleDeltaSeconds ?? "-") + " allowed=" + (item.allowedIncreaseSeconds ?? "-") + " seq " + (item.fromSeq ?? "-") + " -> " + (item.toSeq ?? "-") + " ts " + (item.fromTs || "-") + " -> " + (item.toTs || "-") + " traceId=" + (item.traceId || "-")).join("\n")
    : "- 未观察到最近更新三角波异常跳增。";
  const recentUpdateSteps = Array.isArray(sampleMetrics?.turnTimingRecentUpdateLargestSteps)
    ? sampleMetrics.turnTimingRecentUpdateLargestSteps
    : Array.isArray(sampleMetrics?.turnTimingRecentUpdateSteps)
      ? sampleMetrics.turnTimingRecentUpdateSteps.filter((item) => Number.isFinite(Number(item.delta))).slice().sort((a, b) => Number(b.delta) - Number(a.delta)).slice(0, 200)
      : [];
  const stepLines = recentUpdateSteps.length > 0
    ? recentUpdateSteps.slice(0, 80).map((item) => "- " + formatTurnEventDisplayLabel(item) + " recentUpdate step " + (item.fromValue ?? "-") + " -> " + (item.toValue ?? "-") + " delta=" + (item.delta ?? "-") + " sampleDelta=" + (item.sampleDeltaSeconds ?? "-") + " allowed=" + (item.allowedIncreaseSeconds ?? "-") + " excess=" + (item.excessiveIncreaseSeconds ?? 0) + " event=" + (item.event || "-") + " seq " + (item.fromSeq ?? "-") + " -> " + (item.toSeq ?? "-") + " ts " + (item.fromTs || "-") + " -> " + (item.toTs || "-") + " traceId=" + (item.traceId || "-")).join("\n")
    : "- 未观察到最近更新相邻采样 step。";
  const recentUpdateResets = Array.isArray(sampleMetrics?.turnTimingRecentUpdateResets) ? sampleMetrics.turnTimingRecentUpdateResets : [];
  const resetLines = recentUpdateResets.length > 0
    ? recentUpdateResets.slice(0, 80).map((item) => "- " + formatTurnEventDisplayLabel(item) + " reset " + (item.fromValue ?? "-") + " -> " + (item.toValue ?? "-") + " delta=" + (item.delta ?? "-") + " sampleDelta=" + (item.sampleDeltaSeconds ?? "-") + " seq " + (item.fromSeq ?? "-") + " -> " + (item.toSeq ?? "-") + " ts " + (item.fromTs || "-") + " -> " + (item.toTs || "-") + " traceId=" + (item.traceId || "-")).join("\n")
    : "- 未观察到最近更新归零/回落。";
  const disclosureLine = disclosure?.truncated
    ? "表格披露：已按 head/tail 有界输出，totalRows=" + disclosure.totalRows + " includedRows=" + disclosure.includedRows + " omittedRows=" + disclosure.omittedRows + "；异常计数在截断前基于全量采样计算。"
    : "表格披露：完整输出当前分析窗口的采样点。";
  return disclosureLine + "\n\n" + lines.join("\n") + "\n\n列说明：\n" + columnLines + "\n\n时间源说明：totalElapsed 异常以 DOM Code Agent card 采样序列为观察源；completion/final-response 可用时作为 sealed source-of-truth；status=business-turn-completed 表示 timing 仅为非阻塞告警，status=observer-timeout 表示观察等待超预算，status=scenario-incomplete 表示业务回合失败或未完成。\n\n异常事件（仅报表暴露，不做下游 repair；最近更新按三角波模型检测异常跳增）：\n" + nonMonotonicLines + "\n\nTerminal 后总耗时增长事件（终态 turn 的总耗时应 sealed，不应继续增长）：\n" + terminalGrowthLines + "\n\n总耗时归零跳变事件（例如已显示真实耗时后又变成 0 秒）：\n" + elapsedZeroResetLines + "\n\n总耗时异常前跳事件（预期按采样间隔近似递增；例如 14 秒 -> 1137 秒应被列入这里）：\n" + totalElapsedForwardJumpLines + "\n\n最近更新 sawtooth jump 事件（预期每秒增长约 1，遇到新活动归零；例如 1 秒 -> 1 分 4 秒应被列入这里）：\n" + sawtoothJumpLines + "\n\n最近更新相邻采样 step（按 delta 降序；用于人工识别一秒跳几十秒/一分钟的瞬态）：\n" + stepLines + "\n\n最近更新 reset 事件（预期三角波归零，不计为异常）：\n" + resetLines;
}

function formatTurnColumnDisplayLabel(column) {
  const base = String(column?.label || column?.id || "-");
  const role = String(column?.pageRole || "unknown");
  const pageId = compactPageId(column?.pageId);
  return pageId ? base + "@" + role + "/" + pageId : base + "@" + role;
}

function formatTurnEventDisplayLabel(item) {
  const base = String(item?.columnLabel || item?.columnId || "-");
  const role = String(item?.pageRole || "unknown");
  const pageId = compactPageId(item?.pageId);
  return pageId ? base + "@" + role + "/" + pageId : base + "@" + role;
}

function compactPageId(value) {
  if (value === null || value === undefined || value === "") return "";
  const text = String(value);
  if (text.length <= 18) return text;
  return text.slice(0, 12) + ".." + text.slice(-4);
}

function formatMetricCell(value) {
  if (value === null || value === undefined || !Number.isFinite(Number(value))) return "-";
  return String(Number(value));
}

function escapeMarkdownCell(value) {
  return String(value ?? "-").replace(/\|/gu, "\\|");
}

function formatTimingMeta(item) {
  const source = item?.timingSourceOfTruth || item?.expectedElapsedSource || item?.evidenceKind || "-";
  const status = item?.timingStatus || "-";
  return " source=" + source + " status=" + status;
}

function renderMarkdown(report) {
  const findingLines = report.findings.length === 0 ? "- 无红灯项。" : report.findings.map((item) => "- " + item.severity + ": " + item.id + " - " + item.summary).join("\n");
  const commandLines = report.commandTimeline.length === 0 ? "- 无控制命令。" : report.commandTimeline.map((item) => "- " + item.ts + " " + item.phase + " " + item.type + " " + item.commandId + " " + (item.afterUrl || "")).join("\n");
  const commandFailureLines = Array.isArray(report.commandFailures) && report.commandFailures.length > 0
    ? report.commandFailures.slice(0, 80).map((item) => "- " + (item.ts || "-") + " type=" + (item.type || "-") + " commandId=" + (item.commandId || "-") + " durationMs=" + (item.durationMs ?? "-") + " sampleSeq=" + (item.sampleSeq ?? "-") + " path=" + (item.beforePath || "-") + "->" + (item.afterPath || "-") + " message=" + escapeMarkdownCell(item.message || item.failureKind || item.name || "-")).join("\n")
    : "- 无失败控制命令。";
  const transitionLines = report.transitions.length === 0 ? "- 无状态变化。" : report.transitions.slice(0, 80).map((item) => "- #" + item.seq + " " + item.ts + " messages=" + item.messageCount + " traceRows=" + item.traceRowCount + " route=" + (item.routeSessionId || "-") + " active=" + (item.activeSessionId || "-")).join("\n");
  const metricSummary = report.sampleMetrics?.summary || {};
  const loading = report.sampleMetrics?.loading || {};
  const loadingSummary = loading.summary || {};
  const sessionRailTitles = report.sampleMetrics?.sessionRailTitles || {};
  const sessionRailTitleSummary = sessionRailTitles.summary || {};
  const workbenchTurnStateTriad = report.sampleMetrics?.workbenchTurnStateTriad || {};
  const workbenchTurnStateTriadSummary = workbenchTurnStateTriad.summary || {};
  const workbenchTurnStateTriadDrilldown = workbenchTurnStateTriad.drilldown || {};
  const codeAgentCardTiming = report.sampleMetrics?.codeAgentCardTiming || {};
  const codeAgentCardTimingSummary = codeAgentCardTiming.summary || {};
  const roundCompletion = codeAgentCardTiming.roundCompletion || {};
  const traceOrder = report.sampleMetrics?.traceOrder || {};
  const traceOrderSummary = traceOrder.summary || {};
  const alertSummary = report.runtimeAlerts?.summary || {};
  const apiDomLag = report.apiDomLag || {};
  const apiDomLagSummary = apiDomLag.summary || {};
  const browserProcess = report.browserProcess || {};
  const browserProcessSummary = browserProcess.summary || {};
  const browserProcessLines = Array.isArray(browserProcess.memorySamples) && browserProcess.memorySamples.length > 0
    ? browserProcess.memorySamples.slice(-40).map((item) => "- " + (item.ts || "-") + " seq=" + (item.seq ?? "-") + " totalRssMb=" + (item.totalRssMb ?? "-") + " maxProcessRssMb=" + (item.maxProcessRssMb ?? "-") + " totalGrowthMb=" + (item.totalRssGrowthMb ?? "-") + " processGrowthMb=" + (item.maxProcessRssGrowthMb ?? "-") + " processes=" + (item.processCount ?? "-")).join("\n")
    : "- 无 browser-process RSS 样本。";
  const browserResponsivenessLines = Array.isArray(browserProcess.responsivenessEvents) && browserProcess.responsivenessEvents.length > 0
    ? browserProcess.responsivenessEvents.slice(-40).map((item) => "- " + (item.ts || "-") + " role=" + (item.pageRole || "-") + " pageId=" + (item.pageId || "-") + " latencyMs=" + (item.responsivenessLatencyMs ?? "-") + " timeout=" + String(item.responsivenessTimeout === true) + " cdpTimeouts=" + (item.cdpTimeoutCount ?? 0)).join("\n")
    : "- 无 Playwright/CDP 响应性超阈值样本。";
  const projectManagement = report.projectManagement || {};
  const projectSummary = projectManagement.summary || {};
  const projectCommandLines = Array.isArray(projectManagement.commands) && projectManagement.commands.length > 0
    ? projectManagement.commands.slice(0, 40).map((item) => "- " + (item.ts || "-") + " " + (item.phase || "-") + " " + (item.type || "-") + " command=" + (item.commandId || "-") + " status=" + (item.launchStatus ?? "-") + " session=" + (item.sessionId || "-") + " otel=" + (item.otelTraceId || "-") + " taskHash=" + (item.selectedTaskRefHash || "-")).join("\n")
    : "- 无项目管理控制命令。";
  const projectApiLines = Array.isArray(projectManagement.projectApiByPath) && projectManagement.projectApiByPath.length > 0
    ? projectManagement.projectApiByPath.slice(0, 40).map((item) => "- " + (item.method || "-") + " " + (item.path || "-") + " type=" + (item.type || "-") + " status=" + (item.status ?? "-") + " count=" + (item.count ?? 0) + " first=" + (item.firstAt || "-") + " last=" + (item.lastAt || "-")).join("\n")
    : "- 无项目管理自然 API 记录。";
  const projectSampleLines = Array.isArray(projectManagement.samples) && projectManagement.samples.length > 0
    ? projectManagement.samples.slice(-40).map((item) => "- #" + (item.seq ?? "-") + " " + (item.ts || "-") + " role=" + (item.pageRole || "-") + " kind=" + (item.pageKind || "-") + " src=" + (item.sourceCount ?? "-") + " files=" + (item.fileCount ?? "-") + " tasks=" + (item.taskCount ?? "-") + " selectedTask=" + (item.selectedTaskRefHash || "-") + " launchEnabled=" + String(item.launchButtonEnabled === true) + " links=" + (item.workbenchLinkCount ?? 0)).join("\n")
    : "- 无项目管理 DOM 采样。";
  const httpAlertLines = Array.isArray(report.runtimeAlerts?.networkHttpErrorsByPath) && report.runtimeAlerts.networkHttpErrorsByPath.length > 0
    ? report.runtimeAlerts.networkHttpErrorsByPath.slice(0, 40).map((item) => "- HTTP " + (item.status ?? "-") + " " + item.method + " " + item.urlPath + " count=" + item.count + " prompts=" + (item.promptIndexes?.join(",") || "-") + " first=" + (item.firstAt || "-") + " last=" + (item.lastAt || "-")).join("\n")
    : "- 无 HTTP 错误。";
  const requestFailedLines = Array.isArray(report.runtimeAlerts?.networkRequestFailedByPath) && report.runtimeAlerts.networkRequestFailedByPath.length > 0
    ? report.runtimeAlerts.networkRequestFailedByPath.slice(0, 40).map((item) => "- requestfailed " + item.method + " " + item.urlPath + " count=" + item.count + " failure=" + (item.failureKinds?.slice(0, 4).join(",") || "-") + " prompts=" + (item.promptIndexes?.join(",") || "-") + " first=" + (item.firstAt || "-") + " last=" + (item.lastAt || "-")).join("\n")
    : "- 无 requestfailed。";
  const domDiagnosticLines = Array.isArray(report.runtimeAlerts?.domDiagnostics) && report.runtimeAlerts.domDiagnostics.length > 0
    ? report.runtimeAlerts.domDiagnostics.slice(0, 40).map((item) => "- #" + (item.seq ?? "-") + " " + (item.ts || "-") + " prompt=" + (item.promptIndex ?? "-") + " source=" + (item.source || "-") + " code=" + (item.diagnosticCode || "-") + " traceId=" + (item.traceId || "-") + " http=" + (item.httpStatus ?? "-") + " idle=" + (item.idleSeconds ?? "-") + " waitingFor=" + (item.waitingFor || "-") + " lastEventLabel=" + (item.lastEventLabel || "-") + " textHash=" + (item.textHash || "-") + " preview=" + escapeMarkdownCell(item.preview || "")).join("\n")
    : "- 无 DOM 诊断文本。";
  const consoleAlertLines = Array.isArray(report.runtimeAlerts?.consoleAlerts) && report.runtimeAlerts.consoleAlerts.length > 0
    ? report.runtimeAlerts.consoleAlerts.slice(0, 40).map((item) => "- " + (item.ts || "-") + " prompt=" + (item.promptIndex ?? "-") + " type=" + (item.type || "-") + " status=" + (item.status ?? "-") + " path=" + (item.urlPath || "-") + " traceId=" + (item.traceId || "-") + " textHash=" + (item.textHash || "-") + " preview=" + escapeMarkdownCell(item.preview || "")).join("\n")
    : "- 无 console warning/error。";
  const consoleAlertGroupLines = Array.isArray(report.runtimeAlerts?.consoleAlertsByPath) && report.runtimeAlerts.consoleAlertsByPath.length > 0
    ? report.runtimeAlerts.consoleAlertsByPath.slice(0, 40).map((item) => "- console " + (item.type || "-") + " status=" + (item.status ?? "-") + " path=" + (item.urlPath || "-") + " count=" + item.count + " prompts=" + (item.promptIndexes?.join(",") || "-") + " traces=" + (item.traceIds?.slice(0, 6).join(",") || "-")).join("\n")
    : "- 无 console 分组。";
  const promptNetworkLines = Array.isArray(report.promptNetwork?.rounds) && report.promptNetwork.rounds.length > 0
    ? report.promptNetwork.rounds.map((item) => "- round " + item.promptIndex + " promptHash=" + (item.promptTextHash || "-") + " chatPostOk=" + String(item.chatPostOk) + " modes=" + (Array.isArray(item.submitModes) && item.submitModes.length > 0 ? item.submitModes.join(",") : "-") + " failure=" + (item.failureKind || "-") + " statuses=" + (Array.isArray(item.responseStatuses) && item.responseStatuses.length > 0 ? item.responseStatuses.join(",") : "-") + " firstChat=" + (item.firstChatEventAt || "-") + " lastChat=" + (item.lastChatEventAt || "-")).join("\n")
    : "- 无 prompt 网络记录。";
  const roundLines = Array.isArray(report.sampleMetrics?.rounds) && report.sampleMetrics.rounds.length > 0
    ? report.sampleMetrics.rounds.map((item) => "- round " + item.promptIndex + " promptHash=" + (item.promptTextHash || "-") + " samples=" + item.sampleCount + " loadingSamples=" + (item.loadingSamples ?? 0) + " maxLoading=" + (item.maxLoadingCount ?? 0) + " loadingOwners=" + (item.loadingOwnerCount ?? 0) + " totalMax=" + (item.maxTotalElapsedSeconds ?? "-") + " totalLast=" + (item.lastTotalElapsedSeconds ?? "-") + " recentMax=" + (item.maxRecentUpdateSeconds ?? "-") + " recentLast=" + (item.lastRecentUpdateSeconds ?? "-") + " totalDecrease=" + (item.turnTimingTotalElapsedDecreaseCount ?? 0) + " totalForwardJump=" + (item.turnTimingTotalElapsedForwardJumpCount ?? 0) + " totalForwardJumpMax=" + (item.turnTimingTotalElapsedForwardJumpMaxSeconds ?? 0) + " terminalGrowth=" + (item.turnTimingTerminalElapsedGrowthCount ?? 0) + " terminalGrowthMax=" + (item.turnTimingTerminalElapsedGrowthMaxSeconds ?? 0) + " recentJump=" + (item.turnTimingRecentUpdateJumpCount ?? 0) + " recentSawtoothJump=" + (item.turnTimingRecentUpdateSawtoothJumpCount ?? item.turnTimingRecentUpdateJumpCount ?? 0) + " recentStep=" + (item.turnTimingRecentUpdateStepCount ?? 0) + " recentMaxIncrease=" + (item.turnTimingRecentUpdateMaxIncreaseSeconds ?? "-") + " recentMaxExcess=" + (item.turnTimingRecentUpdateMaxExcessSeconds ?? 0) + " recentReset=" + (item.turnTimingRecentUpdateResetCount ?? 0) + " diagnostics=" + item.diagnosticSamples + " terminal=" + item.terminalSamples + " finalText=" + item.finalTextSamples).join("\n")
    : "- 无轮次指标。";
  const cardMissingElapsedLines = Array.isArray(codeAgentCardTiming.missingElapsed) && codeAgentCardTiming.missingElapsed.length > 0
    ? codeAgentCardTiming.missingElapsed.slice(0, 80).map((item) => "- #" + (item.seq ?? "-") + " " + (item.ts || "-") + " prompt=" + (item.promptIndex ?? "-") + " role=" + (item.pageRole || "-") + " status=" + (item.status || "-") + " traceId=" + (item.traceId || "-") + " messageId=" + (item.messageId || "-") + " preview=" + escapeMarkdownCell(item.textPreview || "")).join("\n")
    : "- 未观察到 Code Agent 卡片缺少耗时。";
  const cardMissingRecentLines = Array.isArray(codeAgentCardTiming.missingRecentUpdate) && codeAgentCardTiming.missingRecentUpdate.length > 0
    ? codeAgentCardTiming.missingRecentUpdate.slice(0, 80).map((item) => "- #" + (item.seq ?? "-") + " " + (item.ts || "-") + " prompt=" + (item.promptIndex ?? "-") + " role=" + (item.pageRole || "-") + " status=" + (item.status || "-") + " traceId=" + (item.traceId || "-") + " messageId=" + (item.messageId || "-") + " total=" + (item.totalElapsedSeconds ?? "-") + " preview=" + escapeMarkdownCell(item.textPreview || "")).join("\n")
    : "- 未观察到未终态 Code Agent 卡片缺少最近更新。";
  const roundCompletionLines = Array.isArray(roundCompletion.events) && roundCompletion.events.length > 0
    ? roundCompletion.events.slice(0, 80).map((item) => "- #" + (item.seq ?? "-") + " " + (item.ts || "-") + " prompt=" + (item.promptIndex ?? "-") + " role=" + (item.pageRole || "-") + " traceId=" + (item.traceId || "-") + " completionElapsed=" + (item.elapsedSeconds ?? "-") + " preview=" + escapeMarkdownCell(item.preview || "")).join("\n")
    : "- 未观察到“轮次完成（总耗时 ...）”trace 行。";
  const roundCompletionMismatchLines = Array.isArray(roundCompletion.elapsedMismatches) && roundCompletion.elapsedMismatches.length > 0
    ? roundCompletion.elapsedMismatches.slice(0, 80).map((item) => "- #" + (item.seq ?? "-") + " " + (item.ts || "-") + " prompt=" + (item.promptIndex ?? "-") + " traceId=" + (item.traceId || "-") + " completion=" + (item.completionElapsedSeconds ?? "-") + " card=" + (item.cardTotalElapsedSeconds ?? "-") + " delta=" + (item.deltaSeconds ?? "-") + " tolerance=" + (item.toleranceSeconds ?? "-") + formatTimingMeta(item)).join("\n")
    : "- 未观察到轮次完成耗时与卡片耗时不一致。";
  const roundCompletionFinalMissingLines = Array.isArray(roundCompletion.finalResponseMissing) && roundCompletion.finalResponseMissing.length > 0
    ? roundCompletion.finalResponseMissing.slice(0, 80).map((item) => "- #" + (item.seq ?? "-") + " " + (item.ts || "-") + " prompt=" + (item.promptIndex ?? "-") + " role=" + (item.pageRole || "-") + " traceId=" + (item.traceId || "-") + " completionElapsed=" + (item.completionElapsedSeconds ?? "-")).join("\n")
    : "- 未观察到轮次完成后 final response 缺失。";
  const roundCompletionPostTimingLines = Array.isArray(roundCompletion.postCompletionTimingChanges) && roundCompletion.postCompletionTimingChanges.length > 0
    ? roundCompletion.postCompletionTimingChanges.slice(0, 80).map((item) => "- " + (item.columnLabel || item.columnId || "-") + " " + (item.metric || "-") + " " + (item.fromValue ?? "-") + " -> " + (item.toValue ?? "-") + " delta=" + (item.delta ?? "-") + " completionSeq=" + (item.seq ?? "-") + " seq " + (item.fromSeq ?? "-") + " -> " + (item.toSeq ?? "-") + " traceId=" + (item.traceId || "-")).join("\n")
    : "- 未观察到轮次完成后耗时/最近更新继续变化。";
  const durationUnderreportedLines = Array.isArray(codeAgentCardTiming.durationUnderreported) && codeAgentCardTiming.durationUnderreported.length > 0
    ? codeAgentCardTiming.durationUnderreported.slice(0, 80).map((item) => "- sample=" + (item.sampleIndex ?? "-") + " " + (item.timestamp || "-") + " role=" + (item.pageRole || "-") + " status=" + (item.status || "-") + " traceId=" + (item.traceId || "-") + " card=" + (item.cardTotalElapsedSeconds ?? "-") + "s expected=" + (item.expectedElapsedSeconds ?? "-") + "s delta=" + (item.deltaSeconds ?? "-") + "s evidence=" + (item.evidenceKind || "-") + formatTimingMeta(item) + " preview=" + escapeMarkdownCell(item.evidencePreview || item.cardPreview || "")).join("\n")
    : "- 未观察到 Code Agent 卡片耗时低于 trace/final-response 证据。";
  const durationMismatchLines = Array.isArray(codeAgentCardTiming.durationMismatches) && codeAgentCardTiming.durationMismatches.length > 0
    ? codeAgentCardTiming.durationMismatches.slice(0, 80).map((item) => "- sample=" + (item.sampleIndex ?? "-") + " " + (item.timestamp || "-") + " role=" + (item.pageRole || "-") + " status=" + (item.status || "-") + " traceId=" + (item.traceId || "-") + " direction=" + (item.direction || "-") + " card=" + (item.cardTotalElapsedSeconds ?? "-") + "s expected=" + (item.expectedElapsedSeconds ?? "-") + "s signedDelta=" + (item.signedDeltaSeconds ?? "-") + "s delta=" + (item.deltaSeconds ?? "-") + "s tolerance=" + (item.toleranceSeconds ?? "-") + "s evidence=" + (item.evidenceKind || "-") + " exact=" + String(item.exactEvidence === true) + formatTimingMeta(item) + " preview=" + escapeMarkdownCell(item.evidencePreview || item.cardPreview || "")).join("\n")
    : "- 未观察到 Code Agent 卡片耗时与 completion/final-response 封口证据不一致。";
  const traceOrderAnomalyLines = Array.isArray(traceOrder.orderAnomalies) && traceOrder.orderAnomalies.length > 0
    ? traceOrder.orderAnomalies.slice(0, 80).map((item) => "- sample=" + (item.sampleIndex ?? "-") + " " + (item.timestamp || "-") + " role=" + (item.pageRole || "-") + " traceId=" + (item.traceId || "-") + " rows=" + (item.previousRowIndex ?? "-") + "->" + (item.currentRowIndex ?? "-") + " reasons=" + (Array.isArray(item.reasons) ? item.reasons.join(",") : "-") + " total=" + (item.previousTotalSeconds ?? "-") + "->" + (item.currentTotalSeconds ?? "-") + " clock=" + (item.previousClockSeconds ?? "-") + "->" + (item.currentClockSeconds ?? "-") + " preview=" + escapeMarkdownCell((item.previousPreview || "") + " / " + (item.currentPreview || ""))).join("\n")
    : "- 未观察到可见 trace 行顺序非单调。";
  const traceCompletionNotLastLines = Array.isArray(traceOrder.completionNotLast) && traceOrder.completionNotLast.length > 0
    ? traceOrder.completionNotLast.slice(0, 80).map((item) => "- sample=" + (item.sampleIndex ?? "-") + " " + (item.timestamp || "-") + " role=" + (item.pageRole || "-") + " traceId=" + (item.traceId || "-") + " rows=" + (item.completionRowIndex ?? "-") + "->" + (item.laterRowIndex ?? "-") + " total=" + (item.completionTotalSeconds ?? "-") + "->" + (item.laterTotalSeconds ?? "-") + " completion=" + escapeMarkdownCell(item.completionPreview || "") + " later=" + escapeMarkdownCell(item.laterPreview || "")).join("\n")
    : "- 未观察到 completion 行后还有同 trace 后续行。";
  const loadingSegmentLines = Array.isArray(loading.segments) && loading.segments.length > 0
    ? loading.segments.slice(0, 80).map((item) => "- observedDuration=" + (item.durationSeconds ?? 0) + "s upperBound=" + (item.upperBoundSeconds ?? item.durationSeconds ?? 0) + "s endedGap=" + (item.endedGapSeconds ?? "-") + "s samples=" + (item.sampleCount ?? 0) + " countMax=" + (item.maxCount ?? 0) + " owners=" + (item.ownerCount ?? 0) + " seq=" + (item.firstSeq ?? "-") + ".." + (item.lastSeq ?? "-") + " ts=" + (item.firstAt || "-") + ".." + (item.lastAt || "-") + " endedAt=" + (item.endedAt || (item.ongoing ? "ongoing" : "-")) + " ownerLabels=" + ((Array.isArray(item.owners) ? item.owners : []).slice(0, 6).map((owner) => (owner.ownerKind || "-") + ":" + (owner.ownerLabel || "-") + "x" + (owner.count ?? 0)).join(",") || "-")).join("\n")
    : "- 未观察到“加载中”可见区间。";
  const loadingOwnerLines = Array.isArray(loading.owners) && loading.owners.length > 0
    ? loading.owners.slice(0, 80).map((item) => "- " + (item.ownerKind || "-") + " " + escapeMarkdownCell(item.ownerLabel || item.ownerKey || "-") + " traceId=" + (item.ownerTraceId || "-") + " messageId=" + (item.ownerMessageId || "-") + " sessionId=" + (item.ownerSessionId || "-") + " samples=" + (item.sampleCount ?? 0) + " occurrences=" + (item.occurrenceCount ?? 0) + " maxCount=" + (item.maxSimultaneousCount ?? 0) + " longest=" + (item.longestContinuousSeconds ?? 0) + "s seq=" + (item.firstSeq ?? "-") + ".." + (item.lastSeq ?? "-") + " prompts=" + (Array.isArray(item.promptIndexes) ? item.promptIndexes.join(",") : "-")).join("\n")
    : "- 未观察到“加载中”归属。";
  const loadingTimelineLines = Array.isArray(loading.timeline) && loading.timeline.length > 0
    ? loading.timeline.slice(0, 160).map((item) => "- #" + (item.seq ?? "-") + " " + (item.ts || "-") + " prompt=" + (item.promptIndex ?? "-") + " loadingCount=" + (item.loadingCount ?? 0) + " ownerCount=" + (item.ownerCount ?? 0) + " owners=" + ((Array.isArray(item.owners) ? item.owners : []).slice(0, 6).map((owner) => (owner.ownerKind || "-") + ":" + (owner.ownerLabel || "-") + " trace=" + (owner.ownerTraceId || "-") + "x" + (owner.count ?? 0)).join(",") || "-")).join("\n")
    : "- 未观察到“加载中”采样点。";
  const sessionRailTitleSampleLines = Array.isArray(sessionRailTitles.samples) && sessionRailTitles.samples.length > 0
    ? sessionRailTitles.samples.slice(0, 80).map((item) => "- #" + (item.seq ?? "-") + " " + (item.ts || "-") + " role=" + (item.pageRole || "-") + " visible=" + (item.visibleCount ?? 0) + " fallback=" + (item.fallbackTitleCount ?? 0) + " ratio=" + (item.fallbackTitleRatio ?? 0) + " examples=" + ((Array.isArray(item.examples) ? item.examples : []).slice(0, 4).map((example) => escapeMarkdownCell(example.titlePreview || example.titleHash || "-")).join(",") || "-")).join("\n")
    : "- 未观察到超过一半 fallback 的 session 列表采样点。";
  const sessionRailTitleExampleLines = Array.isArray(sessionRailTitles.examples) && sessionRailTitles.examples.length > 0
    ? sessionRailTitles.examples.slice(0, 80).map((item) => "- firstSeq=" + (item.firstSeq ?? "-") + " role=" + (item.pageRole || "-") + " active=" + String(item.active === true) + " sessionPrefix=" + (item.sessionIdPrefix || "-") + " titleHash=" + (item.titleHash || "-") + " preview=" + escapeMarkdownCell(item.titlePreview || "")).join("\n")
    : "- 无 fallback 标题示例。";
  const workbenchTurnStateTriadGroupLines = Array.isArray(workbenchTurnStateTriadDrilldown.groups) && workbenchTurnStateTriadDrilldown.groups.length > 0
    ? workbenchTurnStateTriadDrilldown.groups.slice(0, 80).map((item) => "- mismatch=" + (item.mismatchKind || "-") + " tuple=" + (item.statusTuple || "-") + " traceId=" + (item.traceId || "-") + " session=" + (item.sessionIdPrefix || "-") + " role=" + (item.pageRole || "-") + " count=" + (item.count ?? 0) + " spanMs=" + (item.observedSpanMs ?? 0) + " seq=" + (item.firstSeq ?? "-") + ".." + (item.lastSeq ?? "-") + " commands=" + ((Array.isArray(item.commandIds) ? item.commandIds : []).slice(0, 4).join(",") || "-") + " railRaw=" + ((Array.isArray(item.rawRailStatuses) ? item.rawRailStatuses : []).slice(0, 4).join(",") || "-") + " cardRaw=" + ((Array.isArray(item.rawCardStatuses) ? item.rawCardStatuses : []).slice(0, 4).join(",") || "-") + " finalBytes=" + ((Array.isArray(item.finalResponseTextBytes) ? item.finalResponseTextBytes : []).slice(0, 4).join(",") || "-")).join("\n")
    : "- 无三态不一致聚合分组。";
  const workbenchTurnStateTriadOtelLines = Array.isArray(workbenchTurnStateTriadDrilldown.otelDrilldown?.commands) && workbenchTurnStateTriadDrilldown.otelDrilldown.commands.length > 0
    ? workbenchTurnStateTriadDrilldown.otelDrilldown.commands.slice(0, 16).map((item) => "- command=" + String(item).replaceAll(String.fromCharCode(96), "'")).join("\n")
    : "- 无可用 traceId 生成 OTel drill-down 命令。";
  const workbenchTurnStateTriadStaticLines = Array.isArray(workbenchTurnStateTriadDrilldown.staticSourceHints) && workbenchTurnStateTriadDrilldown.staticSourceHints.length > 0
    ? workbenchTurnStateTriadDrilldown.staticSourceHints.map((item) => "- " + (item.repo || "-") + " " + (item.path || "-") + ": " + escapeMarkdownCell(item.reason || "")).join("\n")
    : "- 无静态源码候选。";
  const workbenchTurnStateTriadUnitLines = Array.isArray(workbenchTurnStateTriadDrilldown.unitTestReproHints) && workbenchTurnStateTriadDrilldown.unitTestReproHints.length > 0
    ? workbenchTurnStateTriadDrilldown.unitTestReproHints.map((item) => "- " + escapeMarkdownCell(item)).join("\n")
    : "- 无单元测试复现提示。";
  const provenanceLines = Array.isArray(report.pageProvenance?.segments) && report.pageProvenance.segments.length > 0
    ? report.pageProvenance.segments.slice(0, 40).map((item) => "- fingerprint=" + (item.assetFingerprint || "-") + " samples=" + item.sampleCount + " seq=" + (item.firstSeq ?? "-") + ".." + (item.lastSeq ?? "-") + " ts=" + (item.firstAt || "-") + ".." + (item.lastAt || "-") + " scripts=" + (item.scriptCount ?? "-") + " styles=" + (item.stylesheetCount ?? "-") + " urlPaths=" + (Array.isArray(item.urlPaths) ? item.urlPaths.slice(0, 4).join(",") : "-")).join("\n")
    : "- 无页面 provenance segment。";
  const ordinaryPerformanceItems = Array.isArray(report.pagePerformance?.sameOriginApiByPath) ? report.pagePerformance.sameOriginApiByPath.filter((item) => item.isLongLivedStream !== true) : [];
  const streamPerformanceItems = Array.isArray(report.pagePerformance?.sameOriginApiByPath) ? report.pagePerformance.sameOriginApiByPath.filter((item) => item.isLongLivedStream === true) : [];
  const sameOriginApiBudgetMs = Number(report.alertThresholds?.sameOriginApiSlowMs ?? report.pagePerformance?.summary?.budgetMs);
  const streamOpenBudgetMs = Number(report.alertThresholds?.longLivedStreamOpenSlowMs);
  const performanceLines = ordinaryPerformanceItems.length > 0
    ? ordinaryPerformanceItems.slice(0, 80).map((item) => "- " + item.path + " kind=" + (item.routeKind || "same-origin-api") + " budgetMetric=" + (item.budgetMetric || "durationMs") + " samples=" + item.sampleCount + " p50=" + (item.p50Ms ?? "-") + "ms p75=" + (item.p75Ms ?? "-") + "ms p95=" + (item.p95Ms ?? "-") + "ms max=" + (item.maxMs ?? "-") + "ms >budget=" + (item.overBudgetCount ?? item.overFiveSecondCount ?? 0) + " budgetMs=" + (item.budgetMs ?? sameOriginApiBudgetMs) + " legacy>5s=" + (item.overFiveSecondCount ?? 0) + " window=" + (item.firstAt || "-") + ".." + (item.lastAt || "-")).join("\n")
    : "- 无同源 API Resource Timing 样本。";
  const streamPerformanceLines = streamPerformanceItems.length > 0
    ? streamPerformanceItems.slice(0, 80).map((item) => "- " + item.path + " kind=" + (item.routeKind || "same-origin-api-stream") + " samples=" + item.sampleCount + " streamOpenP50=" + (item.streamOpenP50Ms ?? "-") + "ms streamOpenP75=" + (item.streamOpenP75Ms ?? "-") + "ms streamOpenP95=" + (item.streamOpenP95Ms ?? "-") + "ms streamOpenMax=" + (item.streamOpenMaxMs ?? "-") + "ms streamOpen>budget=" + (item.streamOpenOverBudgetCount ?? item.streamOpenOverFiveSecondCount ?? 0) + " streamOpenBudgetMs=" + (item.streamOpenBudgetMs ?? streamOpenBudgetMs) + " streamOpenLegacy>5s=" + (item.streamOpenOverFiveSecondCount ?? 0) + " streamLifetime>5s=" + (item.streamLifetimeOverFiveSecondCount ?? 0) + " lifetimeMax=" + (item.maxMs ?? "-") + "ms window=" + (item.firstAt || "-") + ".." + (item.lastAt || "-")).join("\n")
    : "- 无同源长连接 Resource Timing 样本。";
  const apiDomLagGroupLines = Array.isArray(apiDomLag.groups) && apiDomLag.groups.length > 0
    ? apiDomLag.groups.slice(0, 80).map((item) => "- " + (item.method || "-") + " " + (item.path || "-") + " status=" + (item.status ?? "-") + " kind=" + (item.routeKind || "-") + " confidence=" + (item.confidence || "-") + " count=" + (item.count ?? 0) + " changed=" + (item.domChangedCount ?? 0) + " noChange=" + (item.noDomChangeWithinWindowCount ?? 0) + " p50=" + (item.p50DomChangeDeltaMs ?? "-") + "ms p95=" + (item.p95DomChangeDeltaMs ?? "-") + "ms max=" + (item.maxDomChangeDeltaMs ?? "-") + "ms overBudget=" + (item.overBudgetCount ?? 0) + " window=" + (item.firstAt || "-") + ".." + (item.lastAt || "-")).join("\n")
    : "- 无 API-DOM 候选分组。";
  const apiDomLagWorstLines = Array.isArray(apiDomLag.worstCandidates) && apiDomLag.worstCandidates.length > 0
    ? apiDomLag.worstCandidates.slice(0, 40).map((item) => "- " + (item.ts || "-") + " " + (item.method || "-") + " " + (item.path || "-") + " status=" + (item.status ?? "-") + " confidence=" + (item.confidence || "-") + " domChange=" + (item.domChangeDeltaMs ?? "-") + "ms firstSample=" + (item.firstSampleDeltaMs ?? "-") + "ms session=" + (item.sessionId || "-") + " traceId=" + (item.traceId || "-") + " beforeSeq=" + (item.beforeSample?.seq ?? "-") + " changeSeq=" + (item.changeSample?.seq ?? "-")).join("\n")
    : "- 无 API-DOM digest 变化候选。";
  const metricLines = Array.isArray(report.sampleMetrics?.timeline) && report.sampleMetrics.timeline.length > 0
    ? report.sampleMetrics.timeline.slice(0, 120).map((item) => "- #" + item.seq + " " + item.ts + " prompt=" + item.promptIndex + " loadingCount=" + (item.loadingCount ?? 0) + " loadingOwners=" + (item.loadingOwnerCount ?? 0) + " totalElapsedSeconds=" + (item.totalElapsedSeconds ?? "-") + " recentUpdateSeconds=" + (item.recentUpdateSeconds ?? "-") + " terminal=" + item.terminalSeen + " finalText=" + item.finalResultTextSeen + " diagnostic=" + item.diagnosticSeen).join("\n")
    : "- 无采样指标。";
  const turnTimingTable = renderTurnTimingTable(report.sampleMetrics);
  return "# web-probe observe analysis\n\n"
    + "- stateDir: " + report.stateDir + "\n"
    + "- generatedAt: " + report.generatedAt + "\n"
    + "- samples: " + report.counts.samples + "\n"
    + "- control: " + report.counts.control + "\n"
    + "- network: " + report.counts.network + "\n"
    + "- console: " + (report.counts.console ?? 0) + "\n"
    + "- errors: " + report.counts.errors + "\n\n"
    + "## Findings\n\n" + findingLines + "\n\n"
    + "## Browser process\n\n"
    + "- browserProcessSamples: " + (browserProcessSummary.sampleCount ?? 0) + "\n"
    + "- pageMetricCount: " + (browserProcessSummary.pageMetricCount ?? 0) + "\n"
    + "- maxTotalRssMb: " + (browserProcessSummary.maxTotalRssMb ?? "-") + " / red=" + (browserProcessSummary.totalRssRedMb ?? "-") + "\n"
    + "- maxProcessRssMb: " + (browserProcessSummary.maxProcessRssMb ?? "-") + " / red=" + (browserProcessSummary.processRssRedMb ?? "-") + "\n"
    + "- maxTotalRssGrowthMb: " + (browserProcessSummary.maxTotalRssGrowthMb ?? "-") + " / red=" + (browserProcessSummary.growthRedMb ?? "-") + " windowMs=" + (browserProcessSummary.growthWindowMs ?? "-") + "\n"
    + "- responsivenessSlowCount: " + (browserProcessSummary.responsivenessSlowCount ?? 0) + " timeoutCount=" + (browserProcessSummary.responsivenessTimeoutCount ?? 0) + " redMs=" + (browserProcessSummary.responsivenessRedMs ?? "-") + "\n"
    + "- cdpMetricsTimeoutCount: " + (browserProcessSummary.cdpMetricsTimeoutCount ?? 0) + "\n\n"
    + "### Browser RSS samples\n\n" + browserProcessLines + "\n\n"
    + "### Browser responsiveness samples\n\n" + browserResponsivenessLines + "\n\n"
    + "## Project management\n\n"
    + "- enabled: " + String(projectSummary.enabled === true) + "\n"
    + "- projectSampleCount: " + (projectSummary.projectSampleCount ?? 0) + "\n"
    + "- mdtodoSampleCount: " + (projectSummary.mdtodoSampleCount ?? 0) + "\n"
    + "- latestPageKind: " + (projectSummary.latestPageKind || "-") + "\n"
    + "- latestPath: " + (projectSummary.latestPath || "-") + "\n"
    + "- latestCounts: source=" + (projectSummary.latestSourceCount ?? "-") + " file=" + (projectSummary.latestFileCount ?? "-") + " task=" + (projectSummary.latestTaskCount ?? "-") + "\n"
    + "- latestSelectedTaskRefHash: " + (projectSummary.latestSelectedTaskRefHash || "-") + "\n"
    + "- paneGap: actionable=" + (projectSummary.severePaneGapSampleCount ?? 0) + " ignoredInitialEmptyDetail=" + (projectSummary.ignoredPaneGapSampleCount ?? 0) + "\n"
    + "- launch: commands=" + (projectSummary.launchCommandCount ?? 0) + " success=" + (projectSummary.launchSuccessCount ?? 0) + " failure=" + (projectSummary.launchFailureCount ?? 0) + " otelTraceHeader=" + (projectSummary.launchWithOtelTraceHeaderCount ?? 0) + "\n"
    + "- projectApi: responses=" + (projectSummary.projectApiResponseCount ?? 0) + " failures=" + (projectSummary.projectApiFailureCount ?? 0) + " requestfailed=" + (projectSummary.projectApiRequestFailedCount ?? 0) + " slowPaths=" + (projectSummary.projectApiSlowPathCount ?? 0) + "\n\n"
    + "### Project samples\n\n" + projectSampleLines + "\n\n"
    + "### Project commands\n\n" + projectCommandLines + "\n\n"
    + "### Project API\n\n" + projectApiLines + "\n\n"
    + "## Command failures\n\n" + commandFailureLines + "\n\n"
    + "## Sample metrics\n\n"
    + "- sampleCount: " + (metricSummary.sampleCount ?? 0) + "\n"
    + "- withTotalElapsed: " + (metricSummary.withTotalElapsed ?? 0) + "\n"
    + "- withRecentUpdate: " + (metricSummary.withRecentUpdate ?? 0) + "\n"
    + "- diagnostics: " + (metricSummary.diagnostics ?? 0) + "\n"
    + "- loadingSamples: " + (metricSummary.loadingSampleCount ?? 0) + "\n"
    + "- loadingMaxCount: " + (metricSummary.loadingMaxCount ?? 0) + "\n"
    + "- loadingMaxOwnerCount: " + (metricSummary.loadingMaxOwnerCount ?? 0) + "\n"
    + "- loadingOwnerCount: " + (metricSummary.loadingOwnerCount ?? 0) + "\n"
    + "- loadingLongestContinuousSeconds: " + (metricSummary.loadingLongestContinuousSeconds ?? 0) + "\n"
    + "- loadingCurrentContinuousSeconds: " + (metricSummary.loadingCurrentContinuousSeconds ?? 0) + "\n"
    + "- loadingOverFiveSecondSegmentCount: " + (metricSummary.loadingOverFiveSecondSegmentCount ?? 0) + "\n"
    + "- sessionRailFallbackMajoritySampleCount: " + (metricSummary.sessionRailFallbackMajoritySampleCount ?? 0) + "\n"
    + "- sessionRailFallbackMaxRatio: " + (metricSummary.sessionRailFallbackMaxRatio ?? 0) + "\n"
    + "- sessionRailFallbackMaxCount: " + (metricSummary.sessionRailFallbackMaxCount ?? 0) + "\n"
    + "- promptSegments: " + (metricSummary.promptSegments ?? 0) + "\n\n"
    + "- turnColumns: " + (metricSummary.turnColumns ?? 0) + "\n"
    + "- turnTimingRows: " + (metricSummary.turnTimingRows ?? 0) + "\n"
    + "- turnTimingNonMonotonicCount: " + (metricSummary.turnTimingNonMonotonicCount ?? 0) + "\n"
    + "- turnTimingTotalElapsedDecreaseCount: " + (metricSummary.turnTimingTotalElapsedDecreaseCount ?? 0) + "\n"
    + "- turnTimingTotalElapsedForwardJumpCount: " + (metricSummary.turnTimingTotalElapsedForwardJumpCount ?? 0) + "\n"
    + "- turnTimingTotalElapsedForwardJumpMaxSeconds: " + (metricSummary.turnTimingTotalElapsedForwardJumpMaxSeconds ?? 0) + "\n"
    + "- turnTimingTerminalElapsedGrowthCount: " + (metricSummary.turnTimingTerminalElapsedGrowthCount ?? 0) + "\n"
    + "- turnTimingTerminalElapsedGrowthMaxSeconds: " + (metricSummary.turnTimingTerminalElapsedGrowthMaxSeconds ?? 0) + "\n"
    + "- turnTimingRecentUpdateJumpCount: " + (metricSummary.turnTimingRecentUpdateJumpCount ?? 0) + "\n"
    + "- turnTimingRecentUpdateSawtoothJumpCount: " + (metricSummary.turnTimingRecentUpdateSawtoothJumpCount ?? metricSummary.turnTimingRecentUpdateJumpCount ?? 0) + "\n"
    + "- turnTimingRecentUpdateStepCount: " + (metricSummary.turnTimingRecentUpdateStepCount ?? 0) + "\n"
    + "- turnTimingRecentUpdateMaxIncreaseSeconds: " + (metricSummary.turnTimingRecentUpdateMaxIncreaseSeconds ?? "-") + "\n"
    + "- turnTimingRecentUpdateMaxExcessSeconds: " + (metricSummary.turnTimingRecentUpdateMaxExcessSeconds ?? 0) + "\n"
    + "- turnTimingRecentUpdateResetCount: " + (metricSummary.turnTimingRecentUpdateResetCount ?? 0) + "\n\n"
    + "- codeAgentCardSampleCount: " + (metricSummary.codeAgentCardSampleCount ?? 0) + "\n"
    + "- codeAgentCardMissingElapsedCount: " + (metricSummary.codeAgentCardMissingElapsedCount ?? 0) + "\n"
    + "- codeAgentCardMissingRecentUpdateCount: " + (metricSummary.codeAgentCardMissingRecentUpdateCount ?? 0) + "\n"
    + "- codeAgentCardDurationUnderreportedCount: " + (metricSummary.codeAgentCardDurationUnderreportedCount ?? 0) + "\n"
    + "- codeAgentCardDurationMismatchCount: " + (metricSummary.codeAgentCardDurationMismatchCount ?? 0) + "\n"
    + "- traceRowCount: " + (metricSummary.traceRowCount ?? 0) + "\n"
    + "- traceRowOrderAnomalyCount: " + (metricSummary.traceRowOrderAnomalyCount ?? 0) + "\n"
    + "- traceRowCompletionNotLastCount: " + (metricSummary.traceRowCompletionNotLastCount ?? 0) + "\n"
    + "- roundCompletionEventCount: " + (metricSummary.roundCompletionEventCount ?? 0) + "\n"
    + "- roundCompletionElapsedMismatchCount: " + (metricSummary.roundCompletionElapsedMismatchCount ?? 0) + "\n"
    + "- roundCompletionFinalResponseMissingCount: " + (metricSummary.roundCompletionFinalResponseMissingCount ?? 0) + "\n"
    + "- roundCompletionPostTimingChangeCount: " + (metricSummary.roundCompletionPostTimingChangeCount ?? 0) + "\n\n"
    + "### Rounds\n\n" + roundLines + "\n\n"
    + "### Code Agent card timing display\n\n"
    + "- cardSampleCount: " + (codeAgentCardTimingSummary.cardSampleCount ?? 0) + "\n"
    + "- runningCardSampleCount: " + (codeAgentCardTimingSummary.runningCardSampleCount ?? 0) + "\n"
    + "- terminalCardSampleCount: " + (codeAgentCardTimingSummary.terminalCardSampleCount ?? 0) + "\n"
    + "- missingElapsedCount: " + (codeAgentCardTimingSummary.missingElapsedCount ?? 0) + "\n"
    + "- missingRecentUpdateCount: " + (codeAgentCardTimingSummary.missingRecentUpdateCount ?? 0) + "\n"
    + "- durationUnderreportedCount: " + (codeAgentCardTimingSummary.durationUnderreportedCount ?? 0) + "\n"
    + "- durationMismatchCount: " + (codeAgentCardTimingSummary.durationMismatchCount ?? 0) + "\n"
    + "- policy: Code Agent 卡片无论终态/非终态都必须显示耗时；非终态必须显示最近更新。completion/final-response 可用时是 sealed source-of-truth；DOM card elapsed 是显示源。该 analyzer 只报告采样到的页面表现，不做下游 repair。\n\n"
    + "#### Missing elapsed samples\n\n" + cardMissingElapsedLines + "\n\n"
    + "#### Missing recent update samples\n\n" + cardMissingRecentLines + "\n\n"
    + "#### Duration underreported samples\n\n" + durationUnderreportedLines + "\n\n"
    + "#### Duration mismatch samples\n\n" + durationMismatchLines + "\n\n"
    + "### Trace row visual order\n\n"
    + "- traceRowCount: " + (traceOrderSummary.traceRowCount ?? 0) + "\n"
    + "- orderAnomalyCount: " + (traceOrderSummary.orderAnomalyCount ?? 0) + "\n"
    + "- completionNotLastCount: " + (traceOrderSummary.completionNotLastCount ?? 0) + "\n"
    + "- policy: 可见 trace 行在同一 trace 内必须按 total/时钟/projected seq 单调展示；completion 行不得出现在同 trace 后续行之前。\n\n"
    + "#### Trace order anomalies\n\n" + traceOrderAnomalyLines + "\n\n"
    + "#### Completion row not last samples\n\n" + traceCompletionNotLastLines + "\n\n"
    + "### Round completion consistency\n\n"
    + "- completionEventCount: " + (codeAgentCardTimingSummary.roundCompletionEventCount ?? 0) + "\n"
    + "- elapsedMismatchCount: " + (codeAgentCardTimingSummary.roundCompletionElapsedMismatchCount ?? 0) + "\n"
    + "- finalResponseMissingCount: " + (codeAgentCardTimingSummary.roundCompletionFinalResponseMissingCount ?? 0) + "\n"
    + "- postTimingChangeCount: " + (codeAgentCardTimingSummary.roundCompletionPostTimingChangeCount ?? 0) + "\n"
    + "- postRecentUpdateVisibleCount: " + (codeAgentCardTimingSummary.roundCompletionPostRecentUpdateVisibleCount ?? 0) + "\n"
    + "- elapsedMismatchToleranceSeconds: " + (codeAgentCardTimingSummary.elapsedMismatchToleranceSeconds ?? "-") + "\n"
    + "- policy: 轮次完成（总耗时 ...） 是 trace sealed source-of-truth；卡片总耗时必须与它一致。完成后 final response 必须可见，耗时/最近更新不得继续跳变。\n\n"
    + "#### Round completion events\n\n" + roundCompletionLines + "\n\n"
    + "#### Completion elapsed mismatches\n\n" + roundCompletionMismatchLines + "\n\n"
    + "#### Final response missing after completion\n\n" + roundCompletionFinalMissingLines + "\n\n"
    + "#### Post-completion timing changes\n\n" + roundCompletionPostTimingLines + "\n\n"
    + "### Loading visibility: visible 加载中\n\n"
    + "- sampleCount: " + (loadingSummary.sampleCount ?? 0) + "\n"
    + "- loadingSampleCount: " + (loadingSummary.loadingSampleCount ?? 0) + "\n"
    + "- maxSimultaneousCount: " + (loadingSummary.maxSimultaneousCount ?? 0) + "\n"
    + "- maxSimultaneousOwnerCount: " + (loadingSummary.maxSimultaneousOwnerCount ?? 0) + "\n"
    + "- concurrentLoadingSampleCount: " + (loadingSummary.concurrentLoadingSampleCount ?? 0) + "\n"
    + "- ownerCount: " + (loadingSummary.ownerCount ?? 0) + "\n"
    + "- segmentCount: " + (loadingSummary.segmentCount ?? 0) + "\n"
    + "- overFiveSecondSegmentCount: " + (loadingSummary.overFiveSecondSegmentCount ?? 0) + "\n"
    + "- longestContinuousSeconds: " + (loadingSummary.longestContinuousSeconds ?? 0) + "\n"
    + "- currentContinuousSeconds: " + (loadingSummary.currentContinuousSeconds ?? 0) + "\n"
    + "- budgetSeconds: " + (loadingSummary.budgetSeconds ?? (Number.isFinite(Number(report.alertThresholds?.visibleLoadingSlowMs)) ? Number(report.alertThresholds.visibleLoadingSlowMs) / 1000 : "unconfigured")) + "\n"
    + "- policy: 该指标只能证明用户真实看到“加载中”的持续时间；修复必须降低真实请求/投影/渲染耗时，禁止提前展示未加载完内容来压低该指标。\n\n"
    + "#### Loading segments\n\n" + loadingSegmentLines + "\n\n"
    + "#### Loading owners\n\n" + loadingOwnerLines + "\n\n"
    + "#### Loading sample timeline\n\n" + loadingTimelineLines + "\n\n"
    + "### Session rail titles\n\n"
    + "- sampleCount: " + (sessionRailTitleSummary.sampleCount ?? 0) + "\n"
    + "- visibleSampleCount: " + (sessionRailTitleSummary.visibleSampleCount ?? 0) + "\n"
    + "- fallbackSampleCount: " + (sessionRailTitleSummary.fallbackSampleCount ?? 0) + "\n"
    + "- majorityFallbackSampleCount: " + (sessionRailTitleSummary.majorityFallbackSampleCount ?? 0) + "\n"
    + "- maxFallbackRatio: " + (sessionRailTitleSummary.maxFallbackRatio ?? 0) + "\n"
    + "- maxVisibleCount: " + (sessionRailTitleSummary.maxVisibleCount ?? 0) + "\n"
    + "- maxFallbackTitleCount: " + (sessionRailTitleSummary.maxFallbackTitleCount ?? 0) + "\n"
    + "- policy: 可见 session 列表中 'Session ses_...' fallback 标题超过一半必须报警；修复应让上游 session list projection 直接携带名称，不能靠点击详情后下游修补。\n\n"
    + "#### Session rail fallback samples\n\n" + sessionRailTitleSampleLines + "\n\n"
    + "#### Session rail fallback examples\n\n" + sessionRailTitleExampleLines + "\n\n"
    + "### Workbench turn-state triad\n\n"
    + "- rowCount: " + (workbenchTurnStateTriadSummary.rowCount ?? 0) + "\n"
    + "- invalidRowCount: " + (workbenchTurnStateTriadSummary.invalidRowCount ?? 0) + "\n"
    + "- invalidFullTriadCount: " + (workbenchTurnStateTriadSummary.invalidFullTriadCount ?? 0) + "\n"
    + "- cardFinalResponseMismatchCount: " + (workbenchTurnStateTriadSummary.cardFinalResponseMismatchCount ?? 0) + "\n"
    + "- invalidGroupCount: " + (workbenchTurnStateTriadSummary.invalidGroupCount ?? workbenchTurnStateTriadDrilldown.summary?.groupCount ?? 0) + "\n"
    + "- invalidTraceIdCount: " + (workbenchTurnStateTriadSummary.invalidTraceIdCount ?? workbenchTurnStateTriadDrilldown.summary?.traceIds?.length ?? 0) + "\n"
    + "- invalidMaxObservedSpanMs: " + (workbenchTurnStateTriadSummary.invalidMaxObservedSpanMs ?? workbenchTurnStateTriadDrilldown.summary?.maxObservedSpanMs ?? 0) + "\n"
    + "- allowedTuples: completed/completed/final-present 或 running/running/final-absent；其他组合都应按 projection seal/read-model 合同处理，禁止 UI fallback repair。\n\n"
    + "#### Triad mismatch groups\n\n" + workbenchTurnStateTriadGroupLines + "\n\n"
    + "#### Triad OTel drill-down\n\n" + workbenchTurnStateTriadOtelLines + "\n\n"
    + "#### Triad static source hints\n\n" + workbenchTurnStateTriadStaticLines + "\n\n"
    + "#### Triad unit-test repro hints\n\n" + workbenchTurnStateTriadUnitLines + "\n\n"
    + "### Page provenance\n\n"
    + "- segmentCount: " + (report.pageProvenance?.summary?.segmentCount ?? 0) + "\n"
    + "- controlSegmentCount: " + (report.pageProvenance?.summary?.controlSegmentCount ?? 0) + "\n\n"
    + provenanceLines + "\n\n"
    + "### Page performance: same-origin API Resource Timing\n\n"
    + "- budgetMs: " + (report.pagePerformance?.summary?.budgetMs ?? sameOriginApiBudgetMs) + "\n"
    + "- sameOriginApiPathCount: " + (report.pagePerformance?.summary?.sameOriginApiPathCount ?? 0) + "\n"
    + "- sameOriginApiSampleCount: " + (report.pagePerformance?.summary?.sameOriginApiSampleCount ?? 0) + "\n"
    + "- longLivedStreamPathCount: " + (report.pagePerformance?.summary?.longLivedStreamPathCount ?? 0) + "\n"
    + "- longLivedStreamSampleCount: " + (report.pagePerformance?.summary?.longLivedStreamSampleCount ?? 0) + "\n"
    + "- longLivedStreamOpenOverFiveSecondPathCount: " + (report.pagePerformance?.summary?.longLivedStreamOpenOverFiveSecondPathCount ?? 0) + "\n"
    + "- longLivedStreamOpenOverFiveSecondSampleCount: " + (report.pagePerformance?.summary?.longLivedStreamOpenOverFiveSecondSampleCount ?? 0) + "\n"
    + "- longLivedStreamLifetimeOverFiveSecondSampleCount: " + (report.pagePerformance?.summary?.longLivedStreamLifetimeOverFiveSecondSampleCount ?? 0) + "\n"
    + "- slowPathCount: " + (report.pagePerformance?.summary?.slowPathCount ?? 0) + "\n"
    + "- slowSampleCount: " + (report.pagePerformance?.summary?.slowSampleCount ?? 0) + "\n"
    + "- worstP95Ms: " + (report.pagePerformance?.summary?.worstP95Ms ?? "-") + "\n\n"
    + performanceLines + "\n\n"
    + "### Page performance: long-lived streams\n\n"
    + "- policy: SSE/long-lived stream lifetime is not ordinary API load latency; only stream open latency is compared with the YAML usability budget, while disconnects remain runtime alerts.\n\n"
    + streamPerformanceLines + "\n\n"
    + "### Natural API to DOM lag candidates\n\n"
    + "- naturalApiResponseCount: " + (apiDomLagSummary.naturalApiResponseCount ?? 0) + "\n"
    + "- stateRelevantResponseCount: " + (apiDomLagSummary.stateRelevantResponseCount ?? 0) + "\n"
    + "- candidateCount: " + (apiDomLagSummary.candidateCount ?? 0) + "\n"
    + "- domChangedCount: " + (apiDomLagSummary.domChangedCount ?? 0) + "\n"
    + "- noDomChangeWithinWindowCount: " + (apiDomLagSummary.noDomChangeWithinWindowCount ?? 0) + "\n"
    + "- budgetMs: " + (apiDomLagSummary.budgetMs ?? "-") + "\n"
    + "- p95DomChangeDeltaMs: " + (apiDomLagSummary.p95DomChangeDeltaMs ?? "-") + "\n"
    + "- maxDomChangeDeltaMs: " + (apiDomLagSummary.maxDomChangeDeltaMs ?? "-") + "\n"
    + "- overBudgetCount: " + (apiDomLagSummary.overBudgetCount ?? 0) + "\n"
    + "- lowConfidenceStreamOpenCount: " + (apiDomLagSummary.lowConfidenceStreamOpenCount ?? 0) + "\n"
    + "- policy: 该指标是调查证据，不作为 Code Agent 阻塞项；/v1/workbench/events 只能代表 SSE stream-open 到后续 DOM 变化的低置信度候选。\n\n"
    + "#### API-DOM groups\n\n" + apiDomLagGroupLines + "\n\n"
    + "#### Worst API-DOM candidates\n\n" + apiDomLagWorstLines + "\n\n"
    + "### Prompt network\n\n" + promptNetworkLines + "\n\n"
    + "### Runtime alerts\n\n"
    + "- httpErrorCount: " + (alertSummary.httpErrorCount ?? 0) + "\n"
    + "- requestFailedCount: " + (alertSummary.requestFailedCount ?? 0) + "\n"
    + "- domDiagnosticSampleCount: " + (alertSummary.domDiagnosticSampleCount ?? 0) + "\n"
    + "- consoleAlertCount: " + (alertSummary.consoleAlertCount ?? 0) + "\n"
    + "- pageErrorCount: " + (alertSummary.pageErrorCount ?? 0) + "\n\n"
    + "#### HTTP errors\n\n" + httpAlertLines + "\n\n"
    + "#### Request failed\n\n" + requestFailedLines + "\n\n"
    + "#### DOM diagnostics\n\n" + domDiagnosticLines + "\n\n"
    + "#### Console alerts\n\n" + consoleAlertLines + "\n\n"
    + "#### Console alert groups\n\n" + consoleAlertGroupLines + "\n\n"
    + "### Turn timing table\n\n"
    + turnTimingTable + "\n\n"
    + "### Aggregate timeline\n\n"
    + metricLines + "\n\n"
    + "## Command timeline\n\n" + commandLines + "\n\n"
    + "## State transitions\n\n" + transitionLines + "\n";
}

async function fileMeta(file) {
  const [buffer, stats] = await Promise.all([readFile(file), stat(file)]);
  return { byteCount: stats.size, sha256: "sha256:" + createHash("sha256").update(buffer).digest("hex") };
}

function sha256(value) {
  return "sha256:" + createHash("sha256").update(String(value)).digest("hex");
}

function urlPath(value) {
  try {
    const url = new URL(String(value || "http://invalid.local/"));
    return url.pathname;
  } catch {
    return "-";
  }
}

function compactLocation(value) {
  if (!value || typeof value !== "object") return null;
  return { urlPath: urlPath(value.url), lineNumber: value.lineNumber ?? null, columnNumber: value.columnNumber ?? null };
}

function limitText(value, limit) {
  const text = String(value ?? "");
  if (text.length <= limit) return text;
  return text.slice(0, Math.max(0, limit - 1)) + "…";
}
`;
}
