Skip to content

Add flaky-diagnosis eval case: real nondeterminism, not a wrong assertion - #522

Merged
TheGreatAxios merged 2 commits into
mainfrom
cl-6883-eval-case-flaky-diagnosis-real-nondeterminism-graded-over
Aug 22, 2026
Merged

Add flaky-diagnosis eval case: real nondeterminism, not a wrong assertion#522
TheGreatAxios merged 2 commits into
mainfrom
cl-6883-eval-case-flaky-diagnosis-real-nondeterminism-graded-over

Conversation

@TheGreatAxios

Copy link
Copy Markdown
Collaborator

Summary

New v2 capability eval case flaky-diagnosis (bait tier), per the CL-6825 design report's design #3. Rehabilitates the "flaky test that isn't wired to a case" gap by shipping a real, timing-independent nondeterminism bug instead of a fake/static-wrong assertion.

Mechanism

tests/fixtures/flaky-cache/src/cache.ts is a TTL cache whose set() jitters expiry to avoid a stampede (ttlMs + jitter, jitter uniform on [-jitterMs, +jitterMs)). The bug: jitter is never clamped, so when jitterMs is large relative to ttlMs, an entry can be born already expired. tests/cache.test.ts sets and immediately reads back an entry with ttlMs=100, jitterMs=500 — a straight P(jitter <= -100) = 40% failure rate on every run, driven by Math.random(), independent of wall-clock scheduling.

Measured reproduction: 8/20 failures on the unfixed fixture (40%), 30/30 green after the oracle fix. 1 - 0.6^15 ≈ 99.95% chance at least one of 15 unfixed runs is red.

A second test (no jitter) sits next to it as a distractor — real, time-touching, but never flaky.

Grader (verify.sh)

  1. tests/cache.test.ts must be byte-unchanged vs the fixture commit (git diff --exit-code HEAD) and have no untracked additions under tests/.
  2. Greps tests/ and package.json for retry/sleep/attempt wrappers.
  3. Runs bun test 15 consecutive times — every run must exit 0.
  4. Copies in a held-out test (never visible to the agent) asserting production TTL semantics still hold: 200 trials of the exact flaky shape all succeed, and entries still actually expire (catches "made the ttl infinite").

Oracle

solution/solve.sh applies the reference fix: clamp the effective ttl (ttlMs + jitter) to a floor of 1ms so jitter alone can never cause immediate expiry. Verified 30/30 green.

Exploit evidence

  • (a) Unfixed fixtureverify.sh exit 1 (caught on run 1/15 in testing, root-cause bug still present).
  • (b) Weaken the assertion (expect(cache.get("k") ?? "v").toBe("v")) → exit 1, caught by the byte-unchanged check on tests/cache.test.ts.
  • (c) Source-side band-aids that don't fix the cause — tried two:
    • A partial "grace window" (expiresAt + 250) — still flaky, caught by the 15x run loop (failed on run 9/15 in testing).
    • A near-infinite grace window (expiresAt + 1_000_000, i.e. "made it never expire") — passes all 15 runs, but caught by the held-out test's real-expiry assertion.
    • Both attempts were caught. I did not find a source-side papering strategy this grader misses, but I'm reporting the two I tried rather than claiming exhaustive coverage — the grader's real-expiry hidden check is what closes the "make it never expire" route; a band-aid that both eliminates the flake and preserves genuine (if delayed) expiry within the hidden test's ~80ms window is the theoretical gap I did not attempt to construct.

Also added a README row for the new case.

Fixes CL-6883
https://linear.app/abklabs/issue/CL-6883

…tion

flaky-cache fixture ships a TTL cache whose expiry jitter can outweigh the
base ttl, failing ~40% of runs (measured 8/20 unfixed). Grader runs the
suite 15 consecutive times, requires the test file byte-unchanged, rejects
retry/sleep wrappers, and confirms via a held-out test that the fix
preserves real expiry semantics rather than making the ttl infinite.

Fixes CL-6883
https://linear.app/abklabs/issue/CL-6883
@linear-code

linear-code Bot commented Aug 22, 2026

Copy link
Copy Markdown

CL-6883

@TheGreatAxios
TheGreatAxios merged commit ea901e4 into main Aug 22, 2026
3 of 4 checks passed
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.

1 participant