// SPEC: PJ2026-01060505 Workbench Performance draft-2026-06-17-p0.
// SPEC: PJ2026-01060508 Web哨兵 draft-2026-06-26-p8-web-probe-sentinel-recovery.
// Responsibility: Redacted web-probe summaries and issue-ready compaction helpers.

function record(value: unknown): Record<string, unknown> {
  return typeof value === "object" && value !== null && !Array.isArray(value) ? value as Record<string, unknown> : {};
}

function nullableRecord(value: unknown): Record<string, unknown> | null {
  return typeof value === "object" && value !== null && !Array.isArray(value) ? value as Record<string, unknown> : null;
}

export function compactWebProbeScriptResult(report: Record<string, unknown> | null): Record<string, unknown> | null {
  if (report === null) return null;
  const browserRuntimeBlocker = classifyWebProbeBrowserRuntimeAuthFailure(report);
  const summary = withBrowserRuntimeBlockerEvidence(compactIssueSummary(record(report.summary)), browserRuntimeBlocker);
  const scriptResult = record(record(report.script).result);
  const scriptReport = record(scriptResult.report);
  const scriptScreenshot = nullableRecord(scriptResult.screenshot);
  const issueEvidence = withBrowserRuntimeBlockerEvidence(
    compactIssueEvidence(report.issueEvidence ?? scriptResult.issueEvidence ?? summary.issueEvidence ?? fallbackIssueEvidence(report, summary)),
    browserRuntimeBlocker,
  );
  const reportPath = typeof report.reportPath === "string"
    ? report.reportPath
    : typeof issueEvidence?.reportPath === "string"
      ? issueEvidence.reportPath
      : typeof scriptReport.path === "string" ? scriptReport.path : null;
  const reportSha256 = typeof report.reportSha256 === "string"
    ? report.reportSha256
    : typeof issueEvidence?.reportSha256 === "string"
      ? issueEvidence.reportSha256
      : typeof scriptReport.sha256 === "string" ? scriptReport.sha256 : null;
  const failureEvidence = compactProductSmokeFailureEvidence(report, reportPath, reportSha256);
  return {
    ok: report.ok === true,
    status: typeof report.status === "string" ? report.status : null,
    summary,
    issueEvidence,
    failureEvidence,
    baseUrl: typeof report.baseUrl === "string" ? report.baseUrl : null,
    finalUrl: typeof report.finalUrl === "string" ? report.finalUrl : null,
    lastUrl: typeof report.lastUrl === "string" ? report.lastUrl : null,
    scriptSha256: typeof report.scriptSha256 === "string" ? report.scriptSha256 : null,
    runDir: typeof report.runDir === "string" ? report.runDir : null,
    reportPath,
    reportSha256,
    auth: record(report.auth),
    script: compactWebProbeScriptBlock(report.script),
    steps: compactWebProbeSteps(report.steps),
    failureKind: browserRuntimeBlocker?.failureKind ?? (typeof report.failureKind === "string" ? report.failureKind : null),
    guidance: typeof report.guidance === "string" ? report.guidance : null,
    lastScreenshot: nullableRecord(report.lastScreenshot) ?? scriptScreenshot,
    readiness: record(report.readiness),
    artifacts: record(report.artifacts),
    error: browserRuntimeBlocker?.code ?? (typeof report.error === "string" ? report.error : null),
    errorMessage: typeof report.errorMessage === "string" ? report.errorMessage : null,
    safety: record(report.safety),
  };
}

export function compactProductSmokeFailureEvidence(
  report: Record<string, unknown>,
  reportPath: string | null = null,
  reportSha256: string | null = null,
): Record<string, unknown> | null {
  if (report.ok !== false) return null;
  const pdf = findPdfFailureEvidence(report);
  if (pdf === null) return null;
  const artifacts = record(report.artifacts);
  const artifactItems = Array.isArray(artifacts.items) ? artifacts.items.map(nullableRecord).filter((item): item is Record<string, unknown> => item !== null) : [];
  const screenshot = artifactItems.find((item) => item.kind === "screenshot")
    ?? nullableRecord(report.lastScreenshot)
    ?? nullableRecord(record(record(report.script).result).screenshot);
  return {
    kind: "pdf-verification",
    status: pdf.status,
    mediaType: pdf.mediaType,
    popupCreated: pdf.popupCreated,
    popupProtocol: pdf.popupProtocol,
    popupClosedBeforeBlob: pdf.popupClosedBeforeBlob,
    documentType: typeof pdf.documentType === "string" ? pdf.documentType.slice(0, 80) : null,
    path: typeof pdf.path === "string" ? pdf.path.slice(0, 240) : null,
    reportPath,
    reportSha256,
    screenshotPath: typeof screenshot?.path === "string" ? screenshot.path : null,
    screenshotSha256: typeof screenshot?.sha256 === "string" ? screenshot.sha256 : null,
    valuesRedacted: true,
  };
}

function findPdfFailureEvidence(value: unknown, depth = 0): Record<string, unknown> | null {
  if (value === null || value === undefined || depth > 8) return null;
  if (typeof value === "string") {
    const first = value.indexOf("{");
    const last = value.lastIndexOf("}");
    if (first >= 0 && last > first) {
      try {
        return findPdfFailureEvidence(JSON.parse(value.slice(first, last + 1)), depth + 1);
      } catch {
        return null;
      }
    }
    return null;
  }
  if (Array.isArray(value)) {
    for (const item of value.slice(-16).reverse()) {
      const found = findPdfFailureEvidence(item, depth + 1);
      if (found !== null) return found;
    }
    return null;
  }
  const candidate = nullableRecord(value);
  if (candidate === null) return null;
  if (
    candidate.ok === false
    && typeof candidate.status === "number"
    && typeof candidate.mediaType === "string"
    && typeof candidate.popupCreated === "boolean"
    && typeof candidate.popupProtocol === "string"
    && typeof candidate.popupClosedBeforeBlob === "boolean"
  ) return candidate;
  for (const nested of Object.values(candidate).slice(0, 32).reverse()) {
    const found = findPdfFailureEvidence(nested, depth + 1);
    if (found !== null) return found;
  }
  return null;
}

export function classifyWebProbeBrowserRuntimeAuthFailure(report: Record<string, unknown>): Record<string, unknown> | null {
  const auth = nullableRecord(report.auth);
  if (auth === null || auth.method !== "ui-form-memory") return null;
  const attempts = Array.isArray(auth.attempts) ? auth.attempts.map(nullableRecord).filter((item): item is Record<string, unknown> => item !== null) : [];
  const firstAttempt = attempts[0] ?? null;
  const script = record(report.script);
  const stepCount = Array.isArray(script.steps)
    ? script.steps.length
    : Array.isArray(report.steps) ? report.steps.length : null;
  const authError = nullableRecord(auth.errorSummary);
  const message = typeof authError?.message === "string"
    ? authError.message
    : typeof report.errorMessage === "string" ? report.errorMessage : "";
  const credentialResolved = auth.credentialResolved === true || auth.usernamePresent === true;
  const explicitRequestReached = auth.requestReached === true || firstAttempt?.requestReached === true;
  const response = firstAttempt?.response ?? null;
  const apiResponseReached = auth.apiResponseReached === true
    || firstAttempt?.apiResponseReached === true
    || response !== null
    || (typeof auth.status === "number" && auth.status > 0);
  const firstNavigationClosed = /Target page, context or browser has been closed/iu.test(message);
  const browserResourceExhausted = /net::ERR_INSUFFICIENT_RESOURCES|net::ERR_OUT_OF_MEMORY/iu.test(message);
  if (!credentialResolved || (!firstNavigationClosed && !browserResourceExhausted) || auth.status !== 0 || response !== null || stepCount !== 0 || explicitRequestReached || apiResponseReached) {
    return null;
  }
  const code = browserResourceExhausted ? "browser-runtime-resource-exhausted" : "browser-runtime-closed";
  return {
    code,
    failureKind: "browser-runtime-blocker",
    credentialResolved: true,
    requestReached: false,
    apiResponseReached: false,
    errorSummary: {
      message: message.replace(/\s+/gu, " ").trim().slice(0, 600),
      status: 0,
      response: null,
      stepCount: 0,
      valuesRedacted: true,
    },
    valuesRedacted: true,
  };
}

function withBrowserRuntimeBlockerEvidence(
  evidence: Record<string, unknown> | null,
  blocker: Record<string, unknown> | null,
): Record<string, unknown> | null {
  if (blocker === null) return evidence;
  const source = evidence ?? {};
  const {
    ok: _ok,
    status: _status,
    credentialResolved: _credentialResolved,
    requestReached: _requestReached,
    apiResponseReached: _apiResponseReached,
    errorSummary: _errorSummary,
    degradedReason: _degradedReason,
    failureKind: _failureKind,
    failedCondition: _failedCondition,
    valuesRedacted: _valuesRedacted,
    ...rest
  } = source;
  return {
    ok: false,
    status: typeof source.status === "string" ? source.status : "blocked",
    credentialResolved: blocker.credentialResolved,
    requestReached: blocker.requestReached,
    apiResponseReached: blocker.apiResponseReached,
    errorSummary: blocker.errorSummary,
    ...rest,
    degradedReason: blocker.code,
    failureKind: blocker.failureKind,
    failedCondition: record(blocker.errorSummary).message,
    valuesRedacted: true,
  };
}

function compactWebProbeScriptBlock(value: unknown): Record<string, unknown> {
  const script = record(value);
  return {
    ok: script.ok === true,
    result: compactJsonForEvidence(script.result),
    stepCount: Array.isArray(script.steps) ? script.steps.length : null,
  };
}

function compactWebProbeSteps(value: unknown): Record<string, unknown>[] {
  if (!Array.isArray(value)) return [];
  return value.slice(-5).map((item) => {
    const step = record(item);
    return {
      index: typeof step.index === "number" ? step.index : null,
      name: typeof step.name === "string" ? step.name : null,
      ok: typeof step.ok === "boolean" ? step.ok : null,
      atMs: typeof step.atMs === "number" ? step.atMs : null,
      data: compactStepDataForIssue(step.data),
    };
  });
}

function compactIssueSummary(value: Record<string, unknown>): Record<string, unknown> {
  if (Object.keys(value).length === 0) return {};
  return {
    ok: value.ok === true,
    status: typeof value.status === "string" ? value.status : null,
    credentialResolved: typeof value.credentialResolved === "boolean" ? value.credentialResolved : null,
    requestReached: typeof value.requestReached === "boolean" ? value.requestReached : null,
    apiResponseReached: typeof value.apiResponseReached === "boolean" ? value.apiResponseReached : null,
    errorSummary: compactJsonForIssue(value.errorSummary),
    degradedReason: typeof value.degradedReason === "string" ? value.degradedReason : null,
    failureKind: typeof value.failureKind === "string" ? value.failureKind : null,
    failedCondition: typeof value.failedCondition === "string" ? value.failedCondition : null,
    nextAction: typeof value.nextAction === "string" ? value.nextAction : null,
    finalUrl: typeof value.finalUrl === "string" ? value.finalUrl : null,
    lastUrl: typeof value.lastUrl === "string" ? value.lastUrl : null,
    scriptSha256: typeof value.scriptSha256 === "string" ? value.scriptSha256 : null,
    runDir: typeof value.runDir === "string" ? value.runDir : null,
    reportPath: typeof value.reportPath === "string" ? value.reportPath : null,
    reportSha256: typeof value.reportSha256 === "string" ? value.reportSha256 : null,
    lastScreenshot: nullableRecord(value.lastScreenshot),
    screenshots: Array.isArray(value.screenshots) ? value.screenshots.slice(-5).map(nullableRecord).filter((item): item is Record<string, unknown> => item !== null) : [],
    apiMatrix: compactApiMatrixSummary(value.apiMatrix),
    stepCount: typeof value.stepCount === "number" ? value.stepCount : null,
    lastStep: compactStepForIssue(value.lastStep),
    issueEvidence: compactIssueEvidence(value.issueEvidence),
    valuesRedacted: value.valuesRedacted === true,
  };
}

function compactJsonForIssue(value: unknown, depth = 0): unknown {
  if (value === null || value === undefined) return value ?? null;
  if (typeof value === "string") return value.replace(/\s+/gu, " ").trim().slice(0, 240);
  if (typeof value === "number" || typeof value === "boolean") return value;
  if (depth >= 4) return "[max-depth]";
  if (Array.isArray(value)) return value.slice(0, 8).map((item) => compactJsonForIssue(item, depth + 1));
  if (typeof value === "object") {
    const out: Record<string, unknown> = {};
    for (const [key, nested] of Object.entries(value as Record<string, unknown>).slice(0, 16)) {
      out[key] = compactJsonForIssue(nested, depth + 1);
    }
    return out;
  }
  return String(value).slice(0, 240);
}

function fallbackIssueEvidence(report: Record<string, unknown>, summary: Record<string, unknown>): Record<string, unknown> {
  const script = record(report.script);
  return {
    ok: report.ok === true,
    status: typeof report.status === "string" ? report.status : summary.status ?? null,
    degradedReason: summary.degradedReason ?? null,
    failureKind: summary.failureKind ?? (typeof report.failureKind === "string" ? report.failureKind : null),
    failedCondition: summary.failedCondition ?? (typeof report.errorMessage === "string" ? report.errorMessage : null),
    nextAction: summary.nextAction ?? null,
    baseUrl: typeof report.baseUrl === "string" ? report.baseUrl : null,
    finalUrl: typeof report.finalUrl === "string" ? report.finalUrl : summary.finalUrl ?? null,
    lastUrl: typeof report.lastUrl === "string" ? report.lastUrl : summary.lastUrl ?? null,
    scriptSha256: typeof report.scriptSha256 === "string" ? report.scriptSha256 : summary.scriptSha256 ?? null,
    runDir: typeof report.runDir === "string" ? report.runDir : summary.runDir ?? null,
    reportPath: typeof report.reportPath === "string" ? report.reportPath : summary.reportPath ?? null,
    reportSha256: typeof report.reportSha256 === "string" ? report.reportSha256 : summary.reportSha256 ?? null,
    result: script.result,
    apiMatrix: summary.apiMatrix ?? null,
    lastStep: summary.lastStep ?? null,
    steps: Array.isArray(report.steps) ? report.steps.slice(-3) : [],
    lastScreenshot: report.lastScreenshot ?? summary.lastScreenshot ?? null,
    screenshots: summary.screenshots ?? [],
    valuesRedacted: true,
  };
}

function compactIssueEvidence(value: unknown): Record<string, unknown> | null {
  const evidence = nullableRecord(value);
  if (evidence === null) return null;
  return {
    ok: evidence.ok === true,
    status: typeof evidence.status === "string" ? evidence.status : null,
    credentialResolved: typeof evidence.credentialResolved === "boolean" ? evidence.credentialResolved : null,
    requestReached: typeof evidence.requestReached === "boolean" ? evidence.requestReached : null,
    apiResponseReached: typeof evidence.apiResponseReached === "boolean" ? evidence.apiResponseReached : null,
    errorSummary: compactJsonForEvidence(evidence.errorSummary),
    degradedReason: typeof evidence.degradedReason === "string" ? evidence.degradedReason : null,
    failureKind: typeof evidence.failureKind === "string" ? evidence.failureKind : null,
    failedCondition: typeof evidence.failedCondition === "string" ? evidence.failedCondition : null,
    nextAction: typeof evidence.nextAction === "string" ? evidence.nextAction : null,
    baseUrl: typeof evidence.baseUrl === "string" ? evidence.baseUrl : null,
    finalUrl: typeof evidence.finalUrl === "string" ? evidence.finalUrl : null,
    lastUrl: typeof evidence.lastUrl === "string" ? evidence.lastUrl : null,
    scriptSha256: typeof evidence.scriptSha256 === "string" ? evidence.scriptSha256 : null,
    runDir: typeof evidence.runDir === "string" ? evidence.runDir : null,
    reportPath: typeof evidence.reportPath === "string" ? evidence.reportPath : null,
    reportSha256: typeof evidence.reportSha256 === "string" ? evidence.reportSha256 : null,
    result: compactJsonForEvidence(evidence.result),
    apiMatrix: compactApiMatrixSummary(evidence.apiMatrix),
    lastStep: compactStepForEvidence(evidence.lastStep),
    steps: Array.isArray(evidence.steps) ? evidence.steps.slice(-3).map(compactStepForEvidence).filter((item): item is Record<string, unknown> => item !== null) : [],
    lastScreenshot: nullableRecord(evidence.lastScreenshot),
    screenshots: Array.isArray(evidence.screenshots) ? evidence.screenshots.slice(-5).map(nullableRecord).filter((item): item is Record<string, unknown> => item !== null) : [],
    valuesRedacted: evidence.valuesRedacted === true,
  };
}

function compactStepForEvidence(value: unknown): Record<string, unknown> | null {
  const step = nullableRecord(value);
  if (step === null) return null;
  return {
    index: typeof step.index === "number" ? step.index : null,
    name: typeof step.name === "string" ? step.name : null,
    ok: typeof step.ok === "boolean" ? step.ok : null,
    atMs: typeof step.atMs === "number" ? step.atMs : null,
    data: compactJsonForEvidence(step.data),
  };
}

function compactJsonForEvidence(value: unknown, depth = 0): unknown {
  if (value === null || value === undefined) return value ?? null;
  if (typeof value === "string") return value.replace(/\s+/gu, " ").trim().slice(0, 600);
  if (typeof value === "number" || typeof value === "boolean") return value;
  if (depth >= 8) return "[max-depth]";
  if (Array.isArray(value)) return value.slice(0, 16).map((item) => compactJsonForEvidence(item, depth + 1));
  if (typeof value === "object") {
    const out: Record<string, unknown> = {};
    for (const [key, nested] of Object.entries(value as Record<string, unknown>).slice(0, 32)) {
      out[key] = compactJsonForEvidence(nested, depth + 1);
    }
    return out;
  }
  return String(value).slice(0, 600);
}

function compactStepForIssue(value: unknown): Record<string, unknown> | null {
  const step = nullableRecord(value);
  if (step === null) return null;
  return {
    index: typeof step.index === "number" ? step.index : null,
    name: typeof step.name === "string" ? step.name : null,
    ok: typeof step.ok === "boolean" ? step.ok : null,
    atMs: typeof step.atMs === "number" ? step.atMs : null,
    data: compactStepDataForIssue(step.data),
  };
}

function compactStepDataForIssue(value: unknown): unknown {
  const data = nullableRecord(value);
  if (data === null) return compactJsonForIssue(value);
  if (Array.isArray(data.items) && typeof data.failedCount === "number") return compactApiMatrixSummary(data);
  return compactJsonForIssue(data);
}

function compactApiMatrixSummary(value: unknown): Record<string, unknown> | null {
  const matrix = nullableRecord(value);
  if (matrix === null) return null;
  return {
    ok: matrix.ok === true,
    count: typeof matrix.count === "number" ? matrix.count : null,
    okCount: typeof matrix.okCount === "number" ? matrix.okCount : null,
    failedCount: typeof matrix.failedCount === "number" ? matrix.failedCount : null,
    items: Array.isArray(matrix.items)
      ? matrix.items.slice(0, 12).map((item) => {
        const row = record(item);
        return {
          name: typeof row.name === "string" ? row.name : null,
          path: typeof row.path === "string" ? row.path : null,
          method: typeof row.method === "string" ? row.method : null,
          ok: row.ok === true,
          status: typeof row.status === "number" ? row.status : null,
          error: typeof row.error === "string" ? row.error : null,
          failureKind: typeof row.failureKind === "string" ? row.failureKind : null,
          bodyKeys: Array.isArray(row.bodyKeys) ? row.bodyKeys.filter((key) => typeof key === "string").slice(0, 12) : [],
        };
      })
      : [],
  };
}

export function compactWebProbeResult(report: Record<string, unknown> | null): Record<string, unknown> | null {
  if (report === null) return null;
  const dom = record(report.dom);
  const performance = compactWebProbePerformance(report.performance);
  const trace = compactWebProbeTrace(report.trace);
  const session = compactWebProbeSession(report.session);
  const artifacts = record(report.artifacts);
  const promptValidation = compactPromptValidation(report.promptValidation);
  const degradedReason = typeof report.degradedReason === "string" ? report.degradedReason : null;
  const summary = webProbeRunIssueSummary({ report, session, trace, promptValidation, artifacts, degradedReason });
  return {
    ok: report.ok === true,
    status: typeof report.status === "string" ? report.status : null,
    summary,
    finalUrl: typeof report.finalUrl === "string" ? report.finalUrl : null,
    error: typeof report.error === "string" ? report.error : null,
    degradedReason,
    failureKind: typeof summary.failureKind === "string" ? summary.failureKind : null,
    nextAction: typeof summary.nextAction === "string" ? summary.nextAction : null,
    actions: compactWebProbeActions(report.actions),
    session,
    trace,
    promptValidation,
    performance,
    traceSamples: compactWebProbeTraceSamples(report.traceSamples),
    dom: {
      authState: typeof dom.authState === "string" ? dom.authState : null,
      requiredSelectors: record(dom.requiredSelectors),
      messageCount: typeof dom.messageCount === "number" ? dom.messageCount : null,
      sessionRail: record(dom.sessionRail),
    },
    failureDom: record(report.failureDom),
    artifacts,
    safety: record(report.safety),
  };
}

function compactWebProbeSession(value: unknown): Record<string, unknown> {
  const session = record(value);
  const freshSession = record(session.freshSession);
  return {
    freshSessionRequested: session.freshSessionRequested === true,
    freshSessionAligned: typeof session.freshSessionAligned === "boolean" ? session.freshSessionAligned : null,
    conversationId: session.conversationId ?? null,
    routeConversationId: session.routeConversationId ?? null,
    selectedConversationId: session.selectedConversationId ?? null,
    sessionId: session.sessionId ?? null,
    revision: session.revision ?? null,
    messageCount: session.messageCount ?? null,
    degradedReason: session.degradedReason ?? null,
    freshSession: Object.keys(freshSession).length === 0 ? null : {
      settled: freshSession.settled === true,
      aligned: freshSession.aligned === true,
      reason: freshSession.reason ?? null,
    },
  };
}

function compactWebProbeTrace(value: unknown): Record<string, unknown> {
  const trace = record(value);
  const latestFetch = record(trace.latestFetch);
  return {
    requested: trace.requested === true,
    sampleCount: trace.sampleCount ?? null,
    conversationId: trace.conversationId ?? null,
    sessionId: trace.sessionId ?? null,
    traceId: trace.traceId ?? null,
    finalAgentStatus: trace.finalAgentStatus ?? null,
    finalTraceStatus: trace.finalTraceStatus ?? null,
    finalDomRowCount: trace.finalDomRowCount ?? null,
    firstDomRowVisibleAt: trace.firstDomRowVisibleAt ?? null,
    firstDomRowPreview: typeof trace.firstDomRowPreview === "string" ? trace.firstDomRowPreview.slice(0, 240) : null,
    firstRestEventVisibleAt: trace.firstRestEventVisibleAt ?? null,
    firstRestEventCount: trace.firstRestEventCount ?? null,
    restTraceOk: trace.restTraceOk === true,
    failedFetchCount: trace.failedFetchCount ?? null,
    latestFetch: Object.keys(latestFetch).length === 0 ? null : {
      ok: latestFetch.ok === true,
      httpStatus: latestFetch.httpStatus ?? null,
      eventCount: latestFetch.eventCount ?? null,
      traceStatus: latestFetch.traceStatus ?? null,
      degradedReason: latestFetch.degradedReason ?? null,
      attempts: Array.isArray(latestFetch.attempts) ? latestFetch.attempts.length : null,
      latestEventPreview: typeof latestFetch.latestEventPreview === "string" ? latestFetch.latestEventPreview.slice(0, 240) : null,
    },
    degradedReason: trace.degradedReason ?? null,
  };
}

function compactWebProbePerformance(value: unknown): Record<string, unknown> {
  const performance = record(value);
  return {
    startedAt: performance.startedAt ?? null,
    submittedAt: performance.submittedAt ?? null,
    firstDomTraceRowAt: performance.firstDomTraceRowAt ?? null,
    firstRestTraceEventAt: performance.firstRestTraceEventAt ?? null,
    submitToFirstDomTraceRowMs: performance.submitToFirstDomTraceRowMs ?? null,
    submitToFirstRestTraceEventMs: performance.submitToFirstRestTraceEventMs ?? null,
    totalSampleWindowMs: performance.totalSampleWindowMs ?? null,
  };
}

function compactPromptValidation(value: unknown): Record<string, unknown> {
  const prompt = record(value);
  const finalResponse = record(prompt.finalResponse);
  return {
    ok: prompt.ok === true,
    applicable: prompt.applicable === true,
    reason: typeof prompt.reason === "string" ? prompt.reason : null,
    failures: Array.isArray(prompt.failures) ? prompt.failures.filter((item) => typeof item === "string").slice(0, 20) : [],
    finalResponse: Object.keys(finalResponse).length === 0 ? null : {
      textChars: typeof finalResponse.textChars === "number" ? finalResponse.textChars : null,
      textPreview: typeof finalResponse.textPreview === "string" ? finalResponse.textPreview.slice(0, 500) : null,
      markdown: nullableRecord(finalResponse.markdown),
    },
  };
}

function webProbeRunIssueSummary(input: {
  report: Record<string, unknown>;
  session: Record<string, unknown>;
  trace: Record<string, unknown>;
  promptValidation: Record<string, unknown>;
  artifacts: Record<string, unknown>;
  degradedReason: string | null;
}): Record<string, unknown> {
  const failureKind = webProbeRunFailureKind(input.degradedReason, input.promptValidation);
  const failedCondition = webProbeRunFailedCondition(input.degradedReason, input.promptValidation);
  const promptSubmitted = record(input.report.safety).promptSubmitted === true;
  const traceRequested = input.trace.requested === true || record(input.report.safety).traceSamplingRequested === true;
  return {
    ok: input.report.status === "pass" && !input.degradedReason,
    status: typeof input.report.status === "string" ? input.report.status : null,
    degradedReason: input.degradedReason,
    failureKind,
    failedCondition,
    nextAction: webProbeRunNextAction(failureKind, input.degradedReason, input.promptValidation, promptSubmitted, traceRequested),
    finalUrl: typeof input.report.finalUrl === "string" ? input.report.finalUrl : null,
    conversationId: input.session.conversationId ?? input.trace.conversationId ?? null,
    sessionId: input.session.sessionId ?? input.trace.sessionId ?? null,
    traceId: input.trace.traceId ?? null,
    traceRequested,
    traceStatus: input.trace.finalTraceStatus ?? null,
    agentStatus: input.trace.finalAgentStatus ?? null,
    messageCount: input.session.messageCount ?? record(input.report.dom).messageCount ?? null,
    promptValidation: input.promptValidation,
    reportPath: typeof input.artifacts.reportPath === "string" ? input.artifacts.reportPath : null,
    reportSha256: typeof input.artifacts.reportSha256 === "string" ? input.artifacts.reportSha256 : null,
    screenshotPath: typeof input.artifacts.screenshotPath === "string" ? input.artifacts.screenshotPath : null,
    screenshotSha256: typeof input.artifacts.screenshotSha256 === "string" ? input.artifacts.screenshotSha256 : null,
    traceRecommendation: promptSubmitted && !traceRequested
      ? "rerun with --trace-sample-count 2 --trace-sample-interval-ms 1500, or rely on the new default for prompt probes"
      : null,
    valuesRedacted: true,
  };
}

function webProbeRunFailureKind(degradedReason: string | null, promptValidation: Record<string, unknown>): string | null {
  if (degradedReason === null) return null;
  if (degradedReason === "prompt-validation-failed") return "unmet-expectation";
  if (degradedReason === "agent-terminal-timeout") return "agent-runtime-timeout";
  if (/trace-fetch|api|fetch|http|network/iu.test(degradedReason)) return "network-or-api-fetch-bug";
  if (/auth|login|credential/iu.test(degradedReason)) return "target-auth-bug";
  if (/browser-timeout|selector-timeout|readiness|session|composer|navigation|load-jitter|timeout/iu.test(degradedReason)) return "target-page-readiness-timeout";
  if (/browser|playwright|chromium/iu.test(degradedReason)) return "browser-environment-bug";
  const failures = Array.isArray(promptValidation.failures) ? promptValidation.failures.join(" ") : "";
  if (/final-response|agent-message|markdown|completed/iu.test(failures)) return "unmet-expectation";
  return "user-facing-web-bug";
}

function webProbeRunFailedCondition(degradedReason: string | null, promptValidation: Record<string, unknown>): string | null {
  if (degradedReason === "prompt-validation-failed") {
    const failures = Array.isArray(promptValidation.failures) ? promptValidation.failures.filter((item) => typeof item === "string") : [];
    return failures.length > 0 ? failures.join(",") : "prompt final response validation failed";
  }
  return degradedReason;
}

function webProbeRunNextAction(
  failureKind: string | null,
  degradedReason: string | null,
  promptValidation: Record<string, unknown>,
  promptSubmitted: boolean,
  traceRequested: boolean,
): string | null {
  if (failureKind === null) return null;
  if (failureKind === "unmet-expectation") {
    const failures = Array.isArray(promptValidation.failures) ? promptValidation.failures.join(",") : "";
    if (/agent-not-completed/iu.test(failures)) return "Increase --wait-agent-terminal-ms or inspect the Code Agent terminal state for the conversation/trace ids in summary.";
    if (/final-response/iu.test(failures)) return "Inspect Workbench message projection and conversation detail; terminal messages must expose a final response.";
    if (/markdown/iu.test(failures)) return "Check whether the prompt expectation still requires markdown structure; stale assertions should be removed instead of preserved.";
    return "Inspect promptValidation.failures, screenshots, and reportPath to decide whether the Web behavior or the assertion is stale.";
  }
  if (failureKind === "network-or-api-fetch-bug") return "Inspect trace/session API fetch fields in reportPath and retry after checking target API availability.";
  if (failureKind === "agent-runtime-timeout") return "Inspect summary.traceId/sessionId and the corresponding Code Agent/AgentRun runtime; the browser probe submitted the prompt and observed trace events, but no terminal agent response arrived before the wait boundary.";
  if (failureKind === "target-auth-bug") return "Inspect credential sourceRef/fingerprint and /auth/login status; do not print secrets.";
  if (failureKind === "target-page-readiness-timeout") return "Inspect finalUrl, readiness/session-create state, Workbench loading indicators, network request failures, and session API evidence in reportPath before changing browser launcher settings.";
  if (failureKind === "browser-environment-bug") return "Inspect browser launcher and Playwright availability on the target workspace.";
  if (promptSubmitted && !traceRequested) return "Rerun with trace sampling if trace evidence is required.";
  return degradedReason === null ? null : "Inspect reportPath for full redacted details, then rerun the same node/lane entry.";
}

function compactWebProbeTraceSamples(value: unknown): Record<string, unknown>[] {
  if (!Array.isArray(value)) return [];
  return value.map(record).map((sample) => {
    const traceFetch = record(sample.traceFetch);
    const attempts = Array.isArray(traceFetch.attempts) ? traceFetch.attempts : [];
    return {
      index: sample.index ?? null,
      sampledAt: sample.sampledAt ?? null,
      messageCount: sample.messageCount ?? null,
      agentStatus: sample.agentStatus ?? null,
      tracePresent: sample.tracePresent === true,
      traceStatus: sample.traceStatus ?? null,
      rowCount: sample.rowCount ?? null,
      emptyLabel: sample.emptyLabel ?? null,
      latestRowPreview: sample.latestRowPreview ?? null,
      userVisibleRowCount: sample.userVisibleRowCount ?? null,
      latestUserVisibleRowPreview: sample.latestUserVisibleRowPreview ?? null,
      conversationId: sample.conversationId ?? null,
      sessionId: sample.sessionId ?? null,
      traceId: sample.traceId ?? null,
      traceFetch: {
        ok: traceFetch.ok === true,
        httpStatus: traceFetch.httpStatus ?? null,
        eventCount: traceFetch.eventCount ?? null,
        degradedReason: traceFetch.degradedReason ?? null,
        attempts: attempts.length,
        latestEventPreview: traceFetch.latestEventPreview ?? null,
      },
    };
  });
}

function compactWebProbeActions(value: unknown): Record<string, unknown>[] {
  if (!Array.isArray(value)) return [];
  return value.map(record).map((action) => {
    const name = typeof action.action === "string" ? action.action : "unknown";
    if (name === "fresh-session") {
      const alignment = record(action.alignment);
      const check = record(alignment.check);
      const repair = record(alignment.repair);
      return {
        action: name,
        settled: action.settled === true,
        aligned: action.aligned === true,
        reason: alignment.reason ?? check.reason ?? null,
        conversationId: check.conversationId ?? null,
        routeConversationId: check.routeConversationId ?? null,
        selectedConversationId: check.selectedConversationId ?? null,
        repaired: Object.keys(repair).length > 0,
        repairConversationId: repair.conversationId ?? null,
        attempts: Array.isArray(alignment.attempts) ? alignment.attempts.length : null,
      };
    }
    if (name === "trace-interval-samples") {
      return {
        action: name,
        count: action.count ?? null,
        intervalMs: action.intervalMs ?? null,
      };
    }
    if (name === "submit-prompt") {
      return {
        action: name,
        chars: action.chars ?? null,
        submittedAt: action.submittedAt ?? null,
      };
    }
    if (name === "wait-agent-terminal") {
      return {
        action: name,
        terminal: action.terminal === true,
        timeoutMs: action.timeoutMs ?? null,
      };
    }
    return {
      action: name,
      skipped: action.skipped ?? null,
      ready: action.ready ?? null,
      found: action.found ?? null,
      timeoutMs: action.timeoutMs ?? null,
    };
  });
}
