{shortenBuildHashInMessage(event.message)}
+ {laterCorrection && ( ++ {laterCorrection === "foreign" + ? "Corrected later from IME's saved result: the output and exit code on this row belonged to another script." + : "Output completed later from IME's saved result."} +
+ )} {/* Exit code / HRESULT badge for app install events */} {(event.eventType === "app_install_failed" || event.eventType === "app_install_completed") && (() => { const ec = (event.data?.exitCode ?? event.data?.exit_code) as string | number | undefined; diff --git a/src/Web/autopilot-monitor-web/app/sessions/page.tsx b/src/Web/autopilot-monitor-web/app/sessions/page.tsx index 54db9a30..846003b0 100644 --- a/src/Web/autopilot-monitor-web/app/sessions/page.tsx +++ b/src/Web/autopilot-monitor-web/app/sessions/page.tsx @@ -234,6 +234,8 @@ function SessionDetailContent() { e => e.eventType === "script_started" || e.eventType === "script_completed" || e.eventType === "script_failed" + // Corrections of a platform run from IME's saved result (D-316) — applied by the reducer. + || e.eventType === "script_output_reconciliation" ), [events] ); diff --git a/src/Web/autopilot-monitor-web/components/ScriptExecutions.tsx b/src/Web/autopilot-monitor-web/components/ScriptExecutions.tsx index 614f608a..f91851ec 100644 --- a/src/Web/autopilot-monitor-web/components/ScriptExecutions.tsx +++ b/src/Web/autopilot-monitor-web/components/ScriptExecutions.tsx @@ -30,6 +30,14 @@ import PhaseDivider from "@/components/PhaseDivider"; // span is hours of offset error rather than run time (a 10 s script once read "1h 00m"). const DURATION_SUPPRESSED_TITLE = "Run time not measurable: the start and end log lines were resolved on different timezone assumptions, so their span would be offset error, not run time"; +// IME's saved result corrected the run (script_output_reconciliation): the log had attributed +// another script's end block to it, so its exit code is unknown and the output shown is IME's. +const EXIT_UNVERIFIED_TITLE = "Exit code unknown: the IME log had attributed another script's output and exit code to this run. The output shown is this script's own, as IME saved it."; +const OUTPUT_CORRECTED_TITLE: Record<"foreign" | "repaired", string> = { + foreign: "The IME log had attributed another script's output to this run. This is the script's own output, as IME saved it after reporting the result.", + repaired: "The IME log delivered this output incomplete. This is the full output, as IME saved it after reporting the result.", +}; + interface ScriptExecutionsProps { events: ScriptInputEvent[]; showScriptOutput?: boolean; @@ -528,6 +536,9 @@ function ScriptItemRow({ item, showScriptOutput, latestBootstrapVersion, nested, exit {item.exitCode} )} + {item.exitCode == null && item.outputCorrection === "foreign" && ( + exit n/a + )} {durationLabel && ( Context: {item.runContext}} {!nested && item.targetType != null && Target: {item.targetType === 2 ? "Device" : "User"}} {item.exitCode != null && Exit Code: {item.exitCode}} + {item.exitCode == null && item.outputCorrection === "foreign" && ( + Exit Code: n/a + )} {detailDurationLabel && Duration: {detailDurationLabel}} {!detailDurationLabel && item.durationSuppressedReason && ( Duration: n/a @@ -601,7 +615,12 @@ function ScriptItemRow({ item, showScriptOutput, latestBootstrapVersion, nested, {hasStdout && ({item.stdout}
{item.stderr}