Skip to content

fix(core): don't reset pareto selection when an unscored data point i… - #391

Merged
langdal merged 2 commits into
mainfrom
fix/pareto-selection-unscored-rows
Jul 4, 2026
Merged

fix(core): don't reset pareto selection when an unscored data point i…#391
langdal merged 2 commits into
mainfrom
fix/pareto-selection-unscored-rows

Conversation

@langdal

@langdal langdal commented Jul 2, 2026

Copy link
Copy Markdown
Member

…s added

Transferring a pareto point or suggestion to the data table appends an unscored (valid: false) row, which is excluded from the optimizer request and cannot move the front — yet the blanket invalidation policy cleared extras.selectedPoint on any dataPoints change, snapping the UI back to the default trade-off and (because the selection is part of the hashed request) triggering a needless re-evaluation.

Move the invalidation post-validation into rootReducer (invalidateStaleParetoSelection) and compare dataPoints by their active (valid + enabled) subset — the same filter calculateData applies. Rows becoming active (score entered), removals, and variable/config changes still clear the selection as before.

@langdal
langdal requested a review from Copilot July 2, 2026 21:48
…s added

Transferring a pareto point or suggestion to the data table appends an
unscored (valid: false) row, which is excluded from the optimizer request
and cannot move the front — yet the blanket invalidation policy cleared
extras.selectedPoint on any dataPoints change, snapping the UI back to
the default trade-off and (because the selection is part of the hashed
request) triggering a needless re-evaluation.

Move the invalidation post-validation into rootReducer
(invalidateStaleParetoSelection) and compare dataPoints by their active
(valid + enabled) subset — the same filter calculateData applies. Rows
becoming active (score entered), removals, and variable/config changes
still clear the selection as before.
@langdal
langdal force-pushed the fix/pareto-selection-unscored-rows branch from 8372957 to 363c0fc Compare July 2, 2026 21:48

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adjusts the pareto-selection invalidation logic in @boostv/process-optimizer-frontend-core so that adding an unscored (invalid) data row (e.g., “Add as data point” from a pareto point or copying a suggestion) no longer clears the current pareto selection or needlessly flags the experiment as changed for re-evaluation. The invalidation is moved to run post-validation and compares data points using the same “active (valid + enabled)” subset that the optimizer request uses.

Changes:

  • Move pareto selection invalidation to rootReducer so it runs after validation (when meta.valid is authoritative).
  • Invalidate selection only when model-relevant structural state changes, comparing dataPoints by the active subset rather than all rows.
  • Replace/expand tests to cover unscored-row append, suggestion transfer, and “row becomes active” transitions; add a Changeset.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
packages/core/src/context/experiment/reducers.ts Runs pareto-selection invalidation post-validation before change detection.
packages/core/src/context/experiment/experiment-reducers.ts Extracts invalidateStaleParetoSelection and compares dataPoints via active subset.
packages/core/src/context/experiment/experiment-reducers.test.ts Adds regression tests ensuring unscored rows don’t clear selection or trigger re-evaluation.
.changeset/pareto-selection-unscored-rows.md Patch changeset documenting the behavioral fix.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/core/src/context/experiment/experiment-reducers.ts
…nce is unchanged

invalidateStaleParetoSelection ran JSON.stringify over the active data-point
subset of both states on every action, adding avoidable O(n) work even to
clearly non-structural actions (e.g. updateExperimentName).

The active subset is a pure function of experiment.dataPoints, and Immer keeps
the same array reference when dataPoints is untouched, so an unchanged reference
guarantees an identical subset. Short-circuit on next.dataPoints ===
previous.dataPoints and only fall back to the deep compare when the reference
actually changes. Behavior-preserving: a row becoming valid (score entered)
mutates dataPoints, yielding a new reference, so validation-driven invalidation
still fires.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@langdal
langdal merged commit 18d9790 into main Jul 4, 2026
1 check passed
@langdal
langdal deleted the fix/pareto-selection-unscored-rows branch July 4, 2026 08:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants