feat: add run comparison type definitions and diff engine#199
Open
Harshil-Malisetty wants to merge 2 commits intoNetflix:masterfrom
Open
feat: add run comparison type definitions and diff engine#199Harshil-Malisetty wants to merge 2 commits intoNetflix:masterfrom
Harshil-Malisetty wants to merge 2 commits intoNetflix:masterfrom
Conversation
Groundwork for the run comparison view (GSoC 2026 deliverable). - RunSnapshot, StepSnapshot, RunComparisonData types composing from existing interfaces - Client-side diff engine: computeParamDiffs, computeStepDiffs, computeArtifactDiffs - 10 Cypress test cases following existing conventions (Chai, testhelper.ts) - All data sourced from existing API endpoints - no new backend routes needed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requirements for a pull request
Description of the Change
This PR adds foundational types and a client-side diff engine for a run comparison view, where users can select any two runs of the same flow and immediately see what changed between them: parameter values, step durations, and artifact presence.
The goal was to add this incrementally rather than in a single large PR, so this is the data layer only. UI components and hooks will follow separately once this is reviewed.
src/types/comparison.tsAll types are built by composing from the existing interfaces in
src/types.ts(Run,Step,Task,TaskStatus,RunParam) so there is no duplication and the comparison view stays in sync with any future changes to those interfaces.RunSnapshotholds a run, itsRunParammap, and an array ofStepSnapshotobjectsStepSnapshotholds aStep, aTaskStatus(sourced fromgetStepStatusintaskdataUtils.ts), itsTask[], and artifact key namesRunComparisonDatais just{ runA, runB }and is the input to every diff functionRunDiffis the output:{ params: ParamDiff[], steps: StepDiff[], artifacts: ArtifactDiff[] }StepDiffincludes adelta_msfield (nullwhen either side has no duration) which maps directly to how the existing timeline already handles incomplete timing dataThe comments at the top of
types/comparison.tsmap each field to the specific existing endpoint it comes from (/runs/{run_number},/parameters,/steps,/tasks,/artifacts).src/utils/comparison.tsFour pure functions, no side effects, no API calls:
computeParamDiffs(paramsA, paramsB): unions all keys from bothRunParamobjects (which are plain string-keyed maps), checks value equality per key, sorts results alphabetically so diffs are stable across renderscomputeStepDiffs(data): matches steps bystep_name, computesdelta_ms = durationB - durationA. Steps missing from one side getnulldurations and'unknown'status, consistent with how the rest of the app handles missing step datacomputeArtifactDiffs(data): compares artifact key presence per step, not artifact values. Artifact values would require additional per-artifact fetches which are expensive; presence diffing is enough to show what the run produced or lostcomputeRunDiff(data): composes all three into a singleRunDiffsrc/utils/__tests__/comparison.test.cypress.ts12 test cases using
createRun,createStep,createTaskfromtesthelper.tsand Chai assertions, matching the conventions in the existing test files. A localmakeSnapshothelper keeps each test focused on the case being tested rather than boilerplate.computeParamDiffs: identical params, changed value, params in only one run, empty paramscomputeStepDiffs: duration delta, step in only one run, null delta when duration missing, alphabetical sort by step_namecomputeArtifactDiffs: both runs have artifact, one run missing artifact, empty artifact listscomputeRunDiff: full integration with params + steps + artifacts in one snapshotNo new API endpoints are needed.
Alternate Designs
Server-side diff endpoint: Considered adding a
/compareendpoint that returns a pre-computed diff. Decided against it because all the necessary data is already fetched by existing hooks (useResource) when viewing a run, the dataset per run is small enough that client-side diffing adds no perceptible cost, and it avoids requiring backend changes for a frontend-driven feature.General-purpose diff library (
deep-diff,microdiff): Rejected to avoid adding a new dependency. The three diff operations are domain-specific enough (step duration delta, artifact presence, param value equality) that a small handwritten implementation is clearer and easier to test precisely.Possible Drawbacks
This PR contains no UI and will produce no visible change on its own. The types may need revision once the comparison view components are designed in detail, but since they compose from existing interfaces rather than duplicating fields, the surface area for breaking changes is small.
Verification Process
yarn cypress run --component --spec "src/utils/__tests__/comparison.test.cypress.ts"