Context
mutation-baselines/decision-kernels.json (the pre-graduation baseline for the mutation gate, see #1415 and mutation-affected.yml/mutation-weekly.yml) records scroll-edge-state at 28.75% mutation score — 92 killed / 228 survived of 320 mutants, the worst of the five designated decision kernels. Root cause: src/utils/scroll-edge-state.ts (326 LOC of real decision logic) has no dedicated test file anywhere in the repo — grep -rl 'scroll-edge-state' --include='*.test.ts' src test returns nothing. Its only coverage is incidental exercise through settle-related suites, which kills barely a quarter of mutants.
This matters now because scripts/mutation/ratchet.ts graduates a kernel to gating purely on score stability across weekly runs (requiredStableRuns: 2), with no minimum-score bar — so this 28.75% floor could become permanently enforced-as-is (see companion issue about the ratchet policy).
Task
Write src/utils/scroll-edge-state.test.ts (or src/utils/__tests__/, match the dominant convention in src/utils/) as a direct behavioral suite for the module's exported API.
Acceptance criteria
Context
mutation-baselines/decision-kernels.json(the pre-graduation baseline for the mutation gate, see #1415 andmutation-affected.yml/mutation-weekly.yml) recordsscroll-edge-stateat 28.75% mutation score — 92 killed / 228 survived of 320 mutants, the worst of the five designated decision kernels. Root cause:src/utils/scroll-edge-state.ts(326 LOC of real decision logic) has no dedicated test file anywhere in the repo —grep -rl 'scroll-edge-state' --include='*.test.ts' src testreturns nothing. Its only coverage is incidental exercise through settle-related suites, which kills barely a quarter of mutants.This matters now because
scripts/mutation/ratchet.tsgraduates a kernel to gating purely on score stability across weekly runs (requiredStableRuns: 2), with no minimum-score bar — so this 28.75% floor could become permanently enforced-as-is (see companion issue about the ratchet policy).Task
Write
src/utils/scroll-edge-state.test.ts(orsrc/utils/__tests__/, match the dominant convention insrc/utils/) as a direct behavioral suite for the module's exported API.Acceptance criteria
scroll-edge-state.ts— read the module and its call sites (settle/scroll paths) first to write assertions about decisions (edge reached? direction? progress?) not implementation details.pnpm mutation:runscoped to this kernel (seescripts/mutation/run.ts --help/ stryker config for per-target invocation) before and after; report both scores in the PR. Target: ≥85% on the module. Use the stryker HTML report's surviving-mutant list to drive test additions — each surviving mutant is either killed or explicitly justified in the PR (e.g. equivalent mutant).mutation-baselines/decision-kernels.jsonby hand — regenerate viapnpm mutation:baselineif the workflow requires it, perdocs/agents/testing.md.pnpm test:unitandpnpm check:toolinggreen.