feat(campaign): discriminative scenario selection (E2)#321
Merged
Conversation
…ignal, drop saturated ties (E2)
tangletools
approved these changes
Jul 7, 2026
tangletools
left a comment
Contributor
There was a problem hiding this comment.
✅ Auto-approved drewstone PR — f3ee4519
This PR was opened by the trusted drewstone account.
The full PR reviewer audit still runs separately and will publish findings if it detects issues.
tangletools · auto-approval · reason: drewstone_author · 2026-07-07T17:25:23Z
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.
Additive primitive for research claim E2: select holdout scenarios by DISCRIMINATION power instead of a random/balanced split.
Motivation — the OR benchmark is saturating
Run 7 measured ~75% tied holdout cells: most problems are solved optimally by the baseline AND every candidate, so those paired cells carry zero signal. A random/balanced holdout spends its budget on scenarios that cannot separate candidates, and a tie in a paired cell wastes it.
What this adds
src/campaign/scenario-selection.ts:scoreDiscrimination(signals, opts?)— ranks scenarios by how well they separate candidates.discrimination = varianceof the per-candidate composite scores (higher spread = more signal). Flagstiedwhenvariance < 1e-9 && meanScore >= saturationCeiling(default 0.999): every candidate scored the same at the ceiling, i.e. a saturated tie with no signal. Deterministic sort: discrimination desc, then meanScore asc (more headroom first), then scenarioId asc.selectDiscriminative(signals, k, opts?)— returns the top-k scenario ids for a holdout, EXCLUDING saturated ties when enough non-tied scenarios exist. Falls back to the least-saturated ties only when non-tied < k. Throws ifk < 1; returns all ids in discrimination order whensignals.length <= k.Deterministic by construction (no Date/Math.random). Exported from
src/campaign/index.ts.Tests
src/campaign/scenario-selection.test.ts(11 tests, all passing): high-variance ranks above low-variance; all-candidates-score-1.0 flagged tied; an all-equal-but-LOW scenario is NOT tied (headroom remains); custom saturationCeiling honored; ties excluded when enough non-tied exist; fallback to least-saturated ties when non-tied < k; determinism;k<1throws;k>=nreturns all in order.tsc --noEmitclean,biome checkclean.Additive; tested. No changes to existing behavior.