Skip to content

Merge-queue triage guidance: the AssertionError vs timeout heuristic has a counterexample class — the discriminator is what the assertion MEASURES, not what kind of failure it is #13830

Description

@os-warren

Split out of #13691 by the triage seat. That card is one timing guard in driver-sql; this is the reusable correction its author flagged as "worth more than this single test" — and which, filed nowhere, would have closed along with it. Prose in a comment is invisible to candidate queries, sweeps and ageing alarms; this card is the record.

The standing guidance

The merge-queue triage comment instructs readers, verbatim:

超时多半是负载/时序……断言(AssertionError: …)才指向真实的行为改变」

That heuristic is sound in general and is doing real work — the domain:devx seat used it the same day to refuse a flake reading on #13683 (an AssertionError on run-dev-unbuilt-workspace.e2e.test.ts), correctly, and that refusal is why that card exists.

The counterexample

#13691 is an AssertionError:

Temporal Conformance (live PG + MySQL)
AssertionError: this run took over a second, so second-precision stamps could have
differed too: expected 1006 to be less than 1000

By the heuristic this reads as "real behaviour change". It is not. The assertion is a validity precondition — the test requires its own run to fit inside one second so that a truncated second-precision stamp could not have distinguished the updates, which is what gives the following distinctness assertion its meaning. The real invariant (monotonicity, asserted on the line above) held.

⇒ The experiment was invalidated. The product was not falsified. And it was confirmed load-dependent by evidence: same head, same test, re-queued once with no change → success.

The correction

The discriminator is not AssertionError vs timeout. It is what the assertion measures.

assertion measures belongs with example
product behaviour (a value, a shape, a refusal) real behaviour change — investigate, ⛔ do not re-run away #13683
elapsed time, ordering under load, or any other precondition of the experiment's own validity timeouts — load-sensitive, and a re-run is a legitimate discriminator #13691

A validity-precondition assertion is a timing measurement wearing an AssertionError's clothes.

Why it is worth encoding rather than remembering

⚠️ Both readings are expensive in opposite directions, and the heuristic as written only protects one of them:

  • Treating a behaviour assertion as a flake → a real defect gets re-run until it passes. The heuristic exists to prevent this, and it does.
  • Treating a validity-precondition assertion as a behaviour change → an author is sent to debug a product that is not broken, on a red they cannot reproduce. Under the current wording this is the instructed outcome.

⭐ The tell is cheap and mechanical: the assertion's message or its compared values name a duration, a timestamp, a count of elapsed units, or an ordering that only holds under a time budget. expected 1006 to be less than 1000, with a message beginning "this run took over a second", is unambiguous on its face.

Scope

One paragraph in the merge-queue triage guidance (and, if the same wording is carried in the dispatch playbook, there too — grep for the 超时/断言 pair before editing, so the two copies do not diverge).

Refs

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions