src/orchestrator/run-artifacts.ts — --summarize + --profile writers
Purpose
Section titled “Purpose”Write the two optional run artifacts:
--summarize[=<path>]— per-run JSON describing every task’s outcome.--profile[=<path>]— Chrome-trace JSON forchrome://tracing/ Perfetto visualization.
Both are no-ops when the corresponding RunOptions field is
undefined.
Public surface
Section titled “Public surface”export interface SummarizeArgs { target: string // '' = default; else absolute or cwd-relative cacheDir: string cwd: string runId: string startedAtMs: number endedAtMs: number totalMs: number ok: boolean // the run's verdict, the CLI's exit code exitCode?: number // the exit code where it is not `ok ? 0 : 1`: a stopping signal's outcomes: readonly TaskOutcome[] flaky?: readonly FlakyFinding[] // detectFlaky's findings → per-task `flaky`}
export interface ProfileArgs { target: string // 'profile.json' default chosen by CLI parser cwd: string outcomes: readonly TaskOutcome[]}
export function writeRunSummary(args: SummarizeArgs): Promise<string> // returns final pathexport function writeRunProfile(args: ProfileArgs): Promise<string> // returns final pathBoth writers return the absolute path actually written; the
orchestrator surfaces it via log.status(vx: summary written to ${p}).
writeRunSummary
Section titled “writeRunSummary”Default path: <cacheDir>/runs/<runId>.json. Explicit path is
resolved against cwd (so a relative --summarize=./summary.json
DTRT).
Output shape — see cli.md § --summarize.
hrtime fields are stringified bigints (preserves ns precision through
JSON). summary block aggregates totals (successful / failed /
skipped / cachedLocal / restoredLocal / restoredRemote / upToDate /
cachedRemote / aborted / total). A task the run proved
flaky carries flaky: { passes, failures, attempts } (present only
then, like noCache).
writeRunProfile
Section titled “writeRunProfile”Chrome-trace format. One ph: 'X' event per task with ts and
dur in microseconds derived from wallclockStartNs /
wallclockEndNs. Tasks with missing hrtime data (legacy outcomes,
group tasks) are skipped.
Each project gets its own tid so overlapping tasks across packages
render on distinct lanes. The shared pid: 1 is arbitrary.
cat carries the task’s final status (e.g. cache-hit, failed)
so trace viewers can color-code.
Errors
Section titled “Errors”Both writers throw on FS failure. The orchestrator catches and surfaces
via log.status but does NOT fail the run — the work already
happened; an inability to write an audit artifact shouldn’t change
the exit code.
tests/run-artifacts.test.ts covers:
- Summary written to default path when
--summarizehas no value. - Summary written to explicit path when
--summarize=foo.json. - Profile written and parseable as JSON.
- Hrtime bigints preserved as strings.
- Profile writers skip tasks without hrtime spans.
- Group tasks excluded from both outputs.
Replacing this module
Section titled “Replacing this module”The two writers are independent. To replace --profile output (e.g.
emit OpenTelemetry instead), swap writeRunProfile and keep
SummarizeArgs / ProfileArgs shapes. The orchestrator only knows
about the two target fields.