diff --git a/frontend/src/components/Runs/RunsScreen.tsx b/frontend/src/components/Runs/RunsScreen.tsx index 33cf1aa..cdd4c95 100644 --- a/frontend/src/components/Runs/RunsScreen.tsx +++ b/frontend/src/components/Runs/RunsScreen.tsx @@ -723,7 +723,7 @@ function ParamDiff({ rows }: { rows: RunRow[] }) { // declaration lookup per flow, and a sweep comparison never does. const one = rows.every((run) => run.flow === rows[0].flow) const { declared } = useFlowInputs(one ? rows[0].flow : undefined) - const varying = varyingKeys(rows) + const varying = varyingKeys(rows, declared) const keys = new Set() for (const run of rows) for (const key of Object.keys(run.params)) keys.add(key) diff --git a/frontend/src/components/Runs/queries.ts b/frontend/src/components/Runs/queries.ts index d679ba4..ac68873 100644 --- a/frontend/src/components/Runs/queries.ts +++ b/frontend/src/components/Runs/queries.ts @@ -310,14 +310,24 @@ export const shortCommit = (commit: string) => commit.slice(0, 7) * What makes a sweep readable: fifty runs of one flow share everything but the * two knobs that were swept, and those two are the only columns worth drawing. */ -export function varyingKeys(runs: { params: Record }[]) { +export function varyingKeys( + runs: { params: Record }[], + declared: Map = new Map(), +) { if (runs.length < 2) return [] const keys = new Set() for (const run of runs) for (const key of Object.keys(run.params)) keys.add(key) + // A key a run lacks is one it took from its flow, read as what the flow + // declares now — the value its cell shows. + // ponytail: a run from before 2026-08-29 stored only what was passed, so if + // its flow's `initial` changed since, a real difference reads as none. Exact + // needs the definition at the run's version, which no route serves. + const value = (run: (typeof runs)[number], key: string) => + JSON.stringify(key in run.params ? run.params[key] : declared.get(key)) return [...keys].filter((key) => { - const first = JSON.stringify(runs[0].params[key]) - return runs.some((run) => JSON.stringify(run.params[key]) !== first) + const first = value(runs[0], key) + return runs.some((run) => value(run, key) !== first) }) }