Skip to content

Flaky: newt-core prompt_window_is_sealed (trybuild) drifts red on a rustc older than CI's @stable #1496

Description

@hartsock

TL;DR

cargo test -p newt-core fails the trybuild target prompt_window_is_sealed
(test fn a_prompt_window_cannot_be_constructed_outside_newt_core_tty) with
3 of 3 tests failed. This is pure rustc diagnostic-wording drift, not a
code defect:

  • The three sealed-PromptWindow fixtures still fail to compile (which is
    what the test actually asserts) — only the committed .stderr snapshots no
    longer match this box's compiler text.
  • It is local-toolchain-only. CI is green on this test today: gh pr checks 1492
    shows all three jobs that execute it (Rust tests, Windows build + test,
    Workspace coverage) passing.
  • It is not a regression from any current branch — the fixtures, harness, and
    PromptWindow definition are byte-identical to origin/main.

Do not TRYBUILD=overwrite to "fix" it (see Remediation — on a stale local
rustc that would overwrite the correct snapshots and turn CI red).

Symptom

test a_prompt_window_cannot_be_constructed_outside_newt_core_tty ... FAILED
thread '...' panicked at trybuild-1.0.118/src/run.rs:102: 3 of 3 tests failed
5 | let _w = newt_core::tty::PromptWindow::test_stub();
  |                                        ^^^^^^^^^ function or associated item not found in `PromptWindow`
note: If the actual output is the correct output you can bless it by rerunning
      your test with the environment variable TRYBUILD=overwrite

Root cause — E0599 wording drift

newt-core/tests/prompt_window_is_sealed.rs runs trybuild's compile_fail
over tests/ui/prompt_window_*.rs (3 fixtures). trybuild does a byte-for-byte
match of each fixture's compiler stderr against a committed .stderr, so any
cosmetic rustc rewording flips the case red even though the compile-fail
behavior is unchanged.

The E0599 item-kind noun phrase differs between the toolchain that blessed the
snapshots and this box's rustc, in both the header and the caret label:

test_stub / new (E0599)
Blessed .stderr (matches CI @stable) ... no **associated function or constant** named ... / **associated function or constant** not found in \PromptWindow``
Local rustc 1.93.1 (this box) ... no **function or associated item** named ... / **function or associated item** not found in \PromptWindow``

The struct_literal fixture (error: cannot construct \PromptWindow` with struct
literal syntax due to private fields) also drifted — likely a newer rustc appending a private fields ... not provided` note — but its exact new text was
not captured (no local cargo re-run in this diagnosis).

Direction matters: NUC01's rustc is 1.93.1 (01f6ddf75, 2026-02-11), which
is older than CI's late-July-2026 @stable. The committed snapshots carry the
newer stable wording (which CI still matches); the stale local box emits
the older wording. Local is the outlier, not CI.

Why it's pre-existing, local-only, and not a branch regression

Confirmed by an adversarial verification pass (tried to refute each claim, failed):

  • Snapshots blessed once, 1adf768 (2026-07-20, PR fix(tui): terminal-line arbiter — make a hidden permission prompt impossible to write #1314 "terminal-line
    arbiter"), never re-blessed. That commit is an ancestor of origin/main, and
    the harness + all three .stderr are byte-identical between origin/main and
    every open branch → checking out main under rustc 1.93.1 drifts identically.
  • No branch feeds this test. PromptWindow (newt-core/src/tty/arbiter.rs:573,
    unforgeable via a private _seal: Seal ZST + private fields; test_stub gated
    #[cfg(any(test, feature = "test-util"))], off by default) and the fixtures are
    unchanged; E0599 text is a function of PromptWindow's own impls + the rustc
    version only.
  • CI is green on this test. It executes in exactly three jobs (ci.yml: Rust
    tests, Windows build + test, Workspace coverage), all on unpinned
    dtolnay/rust-toolchain@stable; all three pass on PR Nemotron qualification framework (bench/psyche-ab-matrix) — DRAFT until live plan runs #1492.

Please don't just delete the test

prompt_window_is_sealed.rs is the compiler-checked proof (doc: "the primary
guarantee") that a downstream crate cannot forge a PromptWindow — the seal that
keeps a hidden-permission-prompt hang (the #1312/#1314 bug class) from silently
walking back in. The cases must fail to compile.

Remediation (in order of preference)

  1. Local fix for the red-on-NUC01 symptom: rustup update stable && rustup default stable
    so the local rustc matches CI's @stable. The test then passes with zero code
    changes — this is a local toolchain-staleness problem.
  2. Durable (recommended): add a rust-toolchain.toml pinning a stable channel.
    There is no toolchain pin anywhere in the repo today (only the check-only
    MSRV job pins @1.88), so unpinned @stable + committed trybuild .stderr is
    inherently reproducibility-fragile across machines and over time. A pin also
    future-proofs the planned second trybuild case
    question_cannot_be_asked_without_window.rs (docs/decisions/tty_widget_suite.md §6 I4),
    which will share this glob and the same drift risk.
  3. If a genuine re-bless is ever needed (CI's stable itself rewords E0599),
    run TRYBUILD=overwrite only on the exact toolchain CI uses, never on a
    stale local rustc, and let CI re-verify. ⚠️ Blessing on 1.93.1 now would
    overwrite the correct newer-stable snapshots with older wording and turn the
    currently-green CI jobs red
    .

Residual risk

Unpinned @stable means a future stable that rewords E0599 before a CI run
could turn CI red for exactly this reason (currently unrealized — live CI green).
Fix #2 closes this.

Environment

Not a duplicate

Searched open + closed issues (trybuild, prompt_window, sealed, stderr,
E0599, TRYBUILD overwrite) — no existing tracker. Distinct from #1494
(mcp_cli fixture leak).

Diagnosis gathered + adversarially verified by Claude Opus 4.8.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions