How a one-shot run ended. Everything a caller needs to decide what happens next, and nothing about how it should be announced — run neither writes a summary nor exits.
That is the point of the shape: it is what cli.ts turns into an exit code, what the daemon
ships back over its socket, and what the JS API builds its result from. Three consumers, one
return value, and no process.exit between them.
const outcome: RunOutcome = { exitCode: 1, durationMs: 1240, startedAt: 1_760_000_000_000, finishedAt: 1_760_000_001_240 }; outcome.exitCode === 0; // false — at least one test failed, or a group rejected
exitCode: number
0 when every test passed, 1 for any failure, group rejection, or empty filtered run.
durationMs: number
Wall-clock duration of the test phase in milliseconds.
startedAt: number
Epoch ms when the test phase began — after the bundle, at the first navigation.
finishedAt: number
Epoch ms when it ended. finishedAt - startedAt is durationMs modulo clock resolution.