Skip to content

test(perf): the process-offload heartbeat asserts a 7.5ms absolute ceiling, so runner load and a real regression are indistinguishable #15221

Description

@mrveiss

Found blocking PR #15158. Same defect class as #15055, in a file that PR #15207's sweep did not cover.

What

autobot-backend/code_intelligence/shared/process_offload_test.py::test_a_scan_in_a_process_does_not_delay_the_event_loop asserts an absolute wall-clock budget:

E   AssertionError: a 5ms heartbeat took 50.6ms median while a scan ran in another process
    — something is still contending for this process
E   assert 0.050631568000000016 < (0.005 * 1.5)

A 7.5 ms ceiling on a 5 ms heartbeat — 1.5× headroom — measured on a machine that is also the CI runner and routinely has several suites in flight.

Evidence that it is load, not the diff

Why this one is worse than an ordinary tight budget

The test's own failure message is "something is still contending for this process", and that is precisely what it exists to detect: that the scan really was offloaded rather than blocking the loop. A genuine regression and a busy runner produce the same symptom, so the test cannot distinguish the defect it guards from the environment it runs in. That is the same structural problem #15055 described, expressed as a contention measure rather than a startup measure.

1.5× headroom makes it worse than #15055's, which had ~7% and still flaked. This one flakes at any real load.

The remedy already exists in base

PR #15207 (021219a21, Refs #15055) converted 20 absolute budgets in system_benchmarks_performance_test.py into ratios against a work unit — a fixed slice of pure-Python work timed in the same process at the same moment — so a uniformly slow runner scales both sides. The harness is autobot_shared/perf_work_budget.py. Its regression sensitivity was demonstrated: after calibration a 1.8 ms addition to a constructor still fails.

This site needs the same treatment, with one wrinkle worth thinking about: the quantity here is contention, not duration. The heartbeat's delay relative to a calibrated unit is the natural measure, but confirm that a real offload regression still fails once calibrated — the point is to keep the detector, not to widen it.

Acceptance criteria

  • The assertion no longer compares to an absolute millisecond budget.
  • A genuine regression still fails: force the scan to run in-process rather than offloaded, and show the test goes red. This is the criterion that separates a fix from a disabled test.
  • The test does not fail under runner load. Say how that was established; a reasoned argument from the chosen measure is acceptable if load cannot be reproduced safely — do not generate artificial load on this machine, it runs live CI.
  • Sweep the rest of that file, and the code_intelligence tree, for other absolute wall-clock assertions. Report the count. test(perf): startup benchmarks assert absolute wall-clock budgets and fail on runner load — passed and failed on the same code minutes apart #15055's file held 20 where one was suspected.
  • A vacuity probe: the assertion cannot pass when the measured value is absent or zero.

Refs #15055, PR #15207, PR #15158.

Activity

  1. github-actions commented on Aug 29, 2026

    @github-actions
    Contributor

    PR #15248 (merged to Dev_new_gui) references this issue with a close keyword.

    test(perf): measure the offload heartbeat against its own idle baseline, not a 7.5ms clock (#15221)

    If this issue is fully resolved, close it manually. If work remains, no action is needed.

  2. mrveiss commented on Aug 29, 2026

    @mrveiss
    OwnerAuthor

    Verified in merged Dev_new_gui — closing

    PR #15248 merged as 9f08f7950. Closes does not fire on this branch, so closing by hand against code read from the merged base.

    Criterion Verdict Evidence
    No absolute millisecond ceiling MET process_offload_test.py:130 _TICK_BUDGET_VS_IDLE = 1.5, a ratio against the heartbeat's own idle baseline; the old in_process < 0.005 * 1.5 survives only in the docstring at :27 recording what it replaced
    A genuine regression still fails MET Forcing the scan in-process gives 1.994x its own idle baseline (budget 1.5). Traced independently in review: three separate paths catch it, and :123 _MIN_TICKS_PER_WINDOW = 10 fails loudly rather than skipping if the loop is starved
    Does not fail under runner load MET, bounded Five runs read 0.992–1.012 against 1.5
    Vacuity probe MET Zero, negative, absent measurement and zero baseline all fail; a positive control proves the assertion is not one that always fails
    Sweep the file and the tree MET Exactly one absolute wall-clock assertion existed in code_intelligence/, the one replaced

    Why the #15207 calibration could not be reused, measured rather than assumed

    A CPU work unit fails this quantity twice. Timed during the scan it is starved by the very contention under test, so numerator and denominator inflate together and the detector cancels itself. Timed outside it, six consecutive samples swung 1.43–3.27 ms — a 2.3× spread in the denominator alone, wider than the 2.0× signal it must resolve. The heartbeat's own idle baseline held to ±1.4% over the same samples.

    So the calibration transfers in form — ratio, recorded every run, vacuity-guarded, down-only — but not in yardstick.

    The claim was corrected before merge

    The first version argued a false failure was impossible: under external delay L the ratio is 1 + tax/(5+L), strictly decreasing in L. An independent review found the premise unstated and not guaranteed — the baseline and measurement windows are temporally disjoint over a second or two, on a machine that is also the CI runner, so a burst confined to the measurement window inflates the numerator alone.

    perf_work_budget.py:174-183 now states that premise and names the residual case, closing with the honest bound: "much less likely", not "impossible", and a red here is not on its own proof of a regression. Two caller caveats live in the shared helper where the next contention site will read them — the settling gap, and that a median answers "did the typical sample move", so a minority-delaying regression will not move it.

    One thing it found on the way

    pytest.skip("process pool unavailable here") could never fire: the helper reset _pool_unavailable_reason to None before the caller read it, so on a host forbidding process creation the test reported a regression that was really an environment — the same confusion this issue is about, one layer down. The reason is now captured before the reset, and the fix was verified to skip only for a genuinely unavailable pool, never for a real regression.

  3. mrveiss commented on Aug 29, 2026

    @mrveiss
    OwnerAuthor

    Reopening — I closed this on evidence that did not cover the path it actually fails on

    Second sighting, independently identified while investigating unrelated red checks on PR #15265 (python-suite shard 10/12, job 99064521827):

    AssertionError: the heartbeat produced 1 ticks while the scan ran — fewer than 10,
    so there is no median to compare and the measurement is meaningless
    

    What I got wrong

    I marked the criterion "does not fail under runner load" as MET, citing five runs reading 0.992–1.012 against a 1.5 budget. That evidence was about the ratio, and the ratio is holding — it is not producing false regressions. But the test still goes red under load, through _MIN_TICKS_PER_WINDOW = 10 (process_offload_test.py:123), a precondition I added in the same PR and described in the closure as failing loudly rather than skipping.

    So I measured the half I had changed and reported the criterion met, when the criterion is about the test's behaviour as a whole. A starved event loop on a shared runner still turns this red, which is the same class of confusion this issue was filed about — an environment condition presenting as a code failure. Different mechanism, same outcome for whoever reads the check.

    An earlier failure on PR #15260 was probably also this test; I could not retrieve the log then and correctly declined to attribute it. This one is attributable.

    The design question, which is not obvious

    "Fail loudly rather than skip" was a deliberate choice and I still think skipping is wrong — a skip on a starved runner is how a real regression hides, and pytest.skip was already found to be unreachable here once (fixed in #15248). But failing on starvation is also wrong, because starvation is not evidence of a regression.

    Both branches of the obvious dichotomy are wrong, which suggests the dichotomy is. A measurement that could not be taken is neither a pass nor a failure — it is a retry. Bounded re-measurement (take the window again, a small fixed number of times, fail only if every attempt starves) distinguishes "this runner is momentarily busy" from "this loop is persistently starved", and the latter is worth a red.

    Concrete fix tracked in #15266, which has the failure detail. This issue stays open until the criterion holds in fact, not by argument.

    Not closing again without

    • A run where the loop is deliberately starved and the test still reaches a verdict rather than erroring on the precondition.
    • The distinction stated in the test itself, so the next reader does not have to reconstruct why a retry is neither a skip nor a pass.
  4. github-actions commented on Aug 29, 2026

    @github-actions
    Contributor

    PR #15279 (merged to Dev_new_gui) references this issue with a close keyword.

    fix(test): retry a starved heartbeat window instead of failing or skipping it (#15266)

    If this issue is fully resolved, close it manually. If work remains, no action is needed.

  5. mrveiss commented on Aug 29, 2026

    @mrveiss
    OwnerAuthor

    Closing again — this time the criterion holds in code, not by argument

    PR #15279 merged as b85fc0331. I reopened this because I had reported "does not fail under runner load" as met on evidence that only covered the ratio. Verified per condition this time.

    Condition I set when reopening Verdict Evidence
    A deliberately starved loop reaches a verdict rather than erroring on the precondition MET, with a stated limit test_scan_only_starvation_fails_on_the_first_attempt_without_retrying (process_offload_test.py:446) starves the scan window and the test reaches a verdict — a regression, on attempt 1
    The distinction stated in the test itself MET :240 "raises MeasurementStarved instead: retried, not failed outright", and :252 "this failure is not retried."

    What actually fixed it

    Not a retry alone — a discriminator. The two measurement windows mean opposite things, and the code now uses that:

    if busy_starved and not idle_starved:   # process_offload_test.py:246
    
    • Idle window healthy, scan window starved → the loop was fine until the scan ran, so the scan is what stopped it. Raises a plain AssertionError, which measure_with_starvation_retry (catching only MeasurementStarved) structurally cannot intercept. Scored on attempt 1, like any ratio failure.
    • Both starved → nothing pins it on the scan. Raises MeasurementStarved, retried to _MAX_STARVATION_RETRIES = 3, then fails with wording naming contention.

    That is the distinction this issue was filed to establish: runner load and a real regression are no longer indistinguishable.

    The honest limit

    For genuine both-window starvation the test still ends on the precondition rather than a ratio verdict — it must, because no measurement was taken. What changed is that this outcome is now distinguishable: it takes three attempts and says so, where a regression fails once and says something different. My reopening condition, read literally, asked for a verdict in every starvation case; that is not achievable and would not be desirable, since inventing a ratio from an unmeasurable window is exactly the vacuity this test guards against.

    Found by review, and fixed rather than documented

    The first version had the retry wrap the measurement while the ratio assertions sat outside it — correct for ordinary regressions. But a total-blockage regression (a scan running synchronously on the loop) starves the busy window before any measurement exists, so it tripped the starvation branch, retried three times, and failed with "starved on all 3 attempts" — the message that most reads like contention, produced by the most severe regression. CI still went red, so nothing could merge on it, but a triager would have been sent the wrong way. The discriminator above is what closed that.

    Not weakened to pass

    _MIN_TICKS_PER_WINDOW = 10 (:128), _TICK_BUDGET_VS_IDLE = 1.5 (:142) and the window lengths are byte-identical to base. Only the response to a failed precondition changed. Nothing was quarantined, no window was widened, and no pytest.skip was introduced — a skip is how a real regression hides, and pytest.skip in this very file was already found unreachable once and fixed in #15248.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions