8000 fix(ux-tests): console tour pill assertions raced the route hand-off by xerj-org · Pull Request #1011 · xerj-org/xerj · GitHub
[go: up one dir, main page]

Skip to content

fix(ux-tests): console tour pill assertions raced the route hand-off - #1011

Merged
xerj-org merged 1 commit into
mainfrom
fix/ux-pill-tour-race
Sep 21, 2026
Merged

xerj-org merged 1 commit into
mainfrom
fix/ux-pill-tour-race

Conversation

@xerj-org
Copy link
Copy Markdown
Owner

What

The browser security suite's operator-console tour failed on PR #1008's CI:

#/dashboards/ai-overview: a sample-backed view must be labelled
(LIVE · Xerj · UPDATED JUST NOW · 74.3MS)

That pill is the corpus view's — the tour starts at #/corpus. The test read it on the first telemetry route.

Root cause (test-side race)

After each setHash the tour waits for aria-busy === 'false' && .h-scene, h1. app.js only ever sets aria-busy to 'false', at the end of a render — nothing flips it 'true' while the next route's query() is pending — so the condition is already satisfied by the previous route's still-mounted DOM. The fixed 150 ms sleep then reads the old view's pill before the new render swaps nav+view (one innerHTML write).

The product is honest throughout: while the new route's fetch is pending, the pill describes the previous view, which is still the one on screen. No view ever displays another view's pill once rendered.

Fail-before (deterministic)

400 ms latency injected into the fake node's console-API 404s (uncommitted demonstration scaffold) fails the old test in one run, from the mirrored side:

#/data: Xerj: MOCK FALLBACK · UPDATED JUST NOW · 0.8MS

Not reproducible on a 32-core box by CPU starvation alone (6 runs × 24 spinners, 8 × 128: zero failures) — the window scales with runner latency, which is why it bit CI's 2–4 vCPU runner.

Fix

Wait for the pill to reach the route's terminal label instead of sleeping — MOCK FALLBACK|SAMPLE DATA on telemetry routes, ^LIVE on corpus/discover/data — bounded by waitFor's 15 s deadline. The wait is the assertion: a view that never labels itself fails on timeout, showing the text it stalled on.

Verified

  • old + latency → fails (above)
  • fixed + latency → 11/11
  • fixed without latency → browser suite 24/24, xerj-ux/test/*.test.mjs 0 fail

Test-only change; no product code touched. Unblocks PR #1008's UX job (storage PR, xerj-ux untouched there — the flake is main's).

…d-off

PR #1008's CI failed the browser security suite's policy tour:

  #/dashboards/ai-overview: a sample-backed view must be labelled
  (LIVE · Xerj · UPDATED JUST NOW · 74.3MS)

That is the CORPUS view's pill — the tour starts at #/corpus — read on
the first telemetry route.

Root cause, in the test: after each setHash the tour waits for
`aria-busy === 'false' && .h-scene, h1`. But app.js only ever sets
aria-busy to 'false', at the END of a render — nothing flips it 'true'
while the next route's query() is pending — so the condition is
already satisfied by the PREVIOUS route's still-mounted DOM. The fixed
150ms sleep that follows then reads the old view's pill before the new
render swaps nav and view in one piece. On a 2-4 vCPU runner the
pending fetch outlasted the sleep; on a 32-core box it does not (6
runs under 24 spinners + 8 under 128: no reproduction — the window
scales with runner latency, not scheduler pressure).

Fail-before, deterministic: 400ms latency injected into the fake
node's console-API 404s (uncommitted demonstration scaffold) fails the
old test in one run —

  #/data: Xerj: MOCK FALLBACK · UPDATED JUST NOW · 0.8MS

— the same race from the mirrored side: a LIVE-claiming route (data)
read while the previous telemetry view's pill was still up.

Fix: wait for the pill to reach the route's TERMINAL label instead of
sleeping — MOCK FALLBACK|SAMPLE DATA on telemetry routes, ^LIVE on
corpus/discover/data — bounded by the harness waitFor's 15s deadline.
The wait IS the assertion: a view that never labels itself fails on
timeout, showing the text it stalled on. The product is unchanged:
while the new route's query() is pending the pill honestly describes
the previous view — the one still on screen — and nav and view swap in
the same innerHTML write, so no view ever shows another view's pill
once rendered.

Verified: old + latency → fails (above); fixed + latency → 11/11;
fixed without latency → browser suite 24/24, unit suite 0 fail.
@xerj-org
xerj-org merged commit 5837dd4 into main Sep 21, 2026
21 checks passed
neoneye pushed a commit to agent-memory-atlas-archive/xerj-org--xerj that referenced this pull request Sep 22, 2026
The stateless-index and reader-fairness release. Two headline changes,
each with a fail-before reproduction; everything else is a fix:

- storage.backend = "s3" starts for real (xerj-org#965, PR xerj-org#1008): the whole
  segment family packs into ONE immutable ZBM1 bundle object (footer =
  the ZCM1 manifest + absolute offsets; trailer adapted from quickwit's
  split-footer bundle, Apache-2.0, approach only). One object + the
  catalogue PUT is ~18% of R2's free Class-A tier at a 30 s flush
  interval where per-file PUTs would be ~899%. snapshot.json is the
  publication point; merges publish before retiring; a FRESH node on an
  empty data dir boots from the bucket and serves full-text over
  hydrated families (journey test). Fail-before: the round-trip test
  panicked "the flush must publish the snapshot catalogue". Honest
  limits stay in docs/OBJECT_STORAGE.md: single-writer v1, WAL local,
  in-memory packs, simulation-pinned crash consistency. Config 127 -> 128
- readers no longer starve under sustained ingest (xerj-org#1013, PR xerj-org#1014):
  the seqlock token was validated at the END of a search, demanding a
  writer-free interval spanning the whole scan — under flush pressure
  those stop existing and search/delete_by_query 500'd at their
  deadline (reproduced twice in the xerj-org#950 profiling run). Validation now
  happens at the CAPTURE boundary with the evenness check; readers need
  a writer-free instant, not a writer-free search. Fail-before: churn
  test failed at its 2 s deadline with the production error; now passes
  in 0.37 s with exact totals (723/723 lib tests, ES-YAML 1376/0)
- /v1/systemone votes on the payload, never the instruction prose:
  0.9867 empty vs 0.6700 criteria-rich instructions was a 32-point
  swing from wording alone (xerj-org#1000); {"message": ...} voted at the spam
  base rate, 0.1733 vs 0.9667 as a string (xerj-org#1001). All eight
  wording/shape arms now score 0.9767 identically (PR xerj-org#1007)
- the console tour's pill assertions raced the route hand-off (xerj-org#1011) —
  aria-busy never goes 'true', so the wait matched the PREVIOUS route's
  DOM; failed only on slow runners (bit PR xerj-org#1008's CI)
- CI honesty: the reference-coding toolkit's tests never ran (one
  filter per invocation; xc_ matched nothing — green on zero tests),
  and its MCP schema gate looked for a release binary the job never
  builds; the roadmap was re-reviewed against rc.76 (release-drift
  guard)
- follow-up filed: xerj-org#1015 (flush guard spans the whole finalize — a
  latency consideration now, not a starvation hazard)

Version stamps: engine/Cargo.toml + Cargo.lock at 1.0.0-rc.77; landing
footers V1.0.0-RC.77 (51 files). Two historical rc.76 mentions kept on
purpose: the CHANGELOG section and the "since rc.76" feature-landing
reference in landing/answers/rebuild-reference-corpus-index.
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

0