Skip to content

🧪 Flake: REPL lifecycle L2 samples Elicit:enter instead of Elicit:active:question in multi-file selections #935

Open

Description

@taras

packages/cli/tests/repl-lifecycle.test.ts:130, row L2: an element waiting on
a question says so, and stops when it is answered
, intermittently samples the
wrong lifecycle phase. The identical revision passes on a re-run with no fix, so
this is the flake record AGENTS.md asks for rather than a repair.

What it reports

error: Error: expect(received).toEqual(expected) // deep equality

  Array [
-   "Elicit:active:question",
+   "Elicit:enter:",
  ]
    ).toEqual(["Elicit:active:question"]);
    at packages/cli/tests/repl-lifecycle.test.ts:130:7

Evidence of intermittence

When Runtime Command Outcome
2026-10-14, at 10b17a40 Deno, local deno task test packages/cli/tests/repl-execution.test.ts packages/cli/tests/repl-lifecycle.test.ts 5 tests / 38 steps, L2 failed
same Deno, local the file alone 1 test / 8 steps, passed
same Deno, local the identical two-file command, nothing changed 6 tests / 39 steps, passed
2026-10-16, at #883 PR2 integration head Deno, local deno task test packages/cli/tests/repl-route.test.ts packages/cli/tests/repl-layout-admission.test.ts packages/cli/tests/repl-presentation-style.test.ts packages/cli/tests/repl-source-reading.test.ts packages/cli/tests/repl-execution.test.ts packages/cli/tests/repl-lifecycle.test.ts 45 passed (189 steps), L2 failed
same Deno, local the identical six-file command, nothing changed 46 passed (190 steps), passed

Both failures are in a multi-file selection; the file alone has not been seen
to fail. CI has not reported it on #890 or #921.

Where to look

The row samples the lifecycle reading after a fixed number of sleep(0) yields,
so the phase it observes depends on how much work the runner has queued ahead of
it. Elicit:enter: is the phase immediately before Elicit:active:question,
which is consistent with sampling one scheduler turn too early when another
suite's work is interleaved.

That names the readiness assumption to investigate. It is not a proven cause,
and it is not a licence to change the assertion or the yield count: the row's
claim — that an element waiting on a question says so — is the right claim.

Why this is open

A green re-run restored the command's health and does not close this. Closing it
needs a cause and discriminating evidence, per AGENTS.md.

Earlier local record: .reviewer/issue-883/pr2-repl-lifecycle-l2-flake-10b17a40.md.
Sibling flake: #874.

Activity

  1. added
    flakeIntermittent or timing-sensitive failure that can pass without a code change
    on Oct 17, 2026
  2. taras commented on Oct 17, 2026

    @taras
    OwnerAuthor

    Cause found and fixed

    This failed CI on #921 (test-deno (6/15), run 38989066578) and was the single
    remaining failing check, so it was repaired at the cause rather than re-run.

    The boundary. The row sampled session.lifecycle.occurrences after a fixed
    five sleep(0) turns. The phases a consumer is told travel through their own
    queue, and the question is published from inside the element, so how many turns
    that takes depends on what else the runner has queued. With another suite beside
    it the sample lands on Elicit:enter: — the phase immediately before the one
    the row is about — which is exactly the reported diff.

    The fix. It now waits for a signal deliberately narrower than its claim:
    that some element has reported waiting on something. Which element, which
    phase, what it waits on, and that it is the only one are all still asserted
    whole, so a wrong phase or a second waiting element still fails. A wait for the
    expected value would have asserted nothing.

    Discriminating evidence, same revision either way, only that loop differing:

    Variant Six-file selection Two-file selection File alone
    fixed five turns 1 failure in 3 runs — passes
    wait for the signal 2 of 2 passed 3 of 3 passed passes

    The sibling fixed-turn loop below it keeps its count: that one asserts the
    reading stays empty, where more turns only strengthen the claim.

    Intermittency means the passing runs are supporting evidence rather than proof.
    The case rests on the cause above plus the control, which reproduces the failure
    with only that loop changed back.

    Carried in #883's delivery of #921.

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

    flakeIntermittent or timing-sensitive failure that can pass without a code change

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions