Files
amethyst/nestsClient/plans/2026-05-07-tighten-cross-stack-assertions.md
T
Claude 32065901c8 docs(nests): T16 closure roadmap + 4 follow-up plans
Plans the path from 'infra shipped' to 'full coverage with
correct behaviours'. Five new plan docs in nestsClient/plans/:

1. 2026-05-07-t16-closure-roadmap.md — index + priority order.
   Three sequential steps + one independent track.

2. 2026-05-07-moq-relay-routing-investigation.md (Priority 1)
   — root-cause the moq-relay 0.10.x per-broadcast subscribe-
   routing race. Step-by-step: capture relay-side trace, write
   minimum reproducer, file upstream OR bump moq-relay version.
   Smoking gun + hypotheses already in place from the
   late-join-flake investigation; this plan turns that into
   actionable next steps.

3. 2026-05-07-tighten-cross-stack-assertions.md (Priority 2)
   — once the routing race is closed, replace the five soft-
   pass scenarios in BrowserInteropTest with hard floors.
   Lists each scenario, its current soft-pass behavior, and
   the proposed hard threshold.

4. 2026-05-07-cross-stack-interop-ci-gating.md (Priority 3)
   — re-add the hang-interop + browser-interop GitHub Actions
   jobs that were dropped in 6829ab727 / b94737de7. Includes
   the exact YAML to restore and a 10/10 sweep stability bar
   before merge.

5. 2026-05-07-framespergroup-production-rerun.md (independent
   track) — re-run the HCgOY two-phone field tests against
   current nostrnests production at multiple framesPerGroup
   values to settle whether the test pin (5) and production
   default (50) can converge.

Estimated total: 2.5-3.5 days of focused work to fully close
T16. After these four: I7 post-reconnect cliff and I12 GOAWAY
remain open as genuinely upstream-territory items, tracked in
their existing investigation docs.
2026-05-07 14:36:21 +00:00

115 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Plan: tighten cross-stack interop assertions to hard-pass
**Status:** specced — pickup ready.
**Depends on:** `2026-05-07-moq-relay-routing-investigation.md`
must be closed first (the soft-passes exist *because* of that flake;
removing them while the flake is unresolved produces fail-flakes,
not regression catches).
## Why soft passes exist today
Five scenarios currently soft-pass (vacuous-pass on listener-side
0-frame outcomes) to keep the test suite from fail-flaking on the
upstream relay-routing race documented in
`2026-05-07-late-join-catalog-flake-investigation.md`:
| Scenario | File | Soft-pass behavior |
|---|---|---|
| `chromium_listener_late_join_still_decodes_tail` | `BrowserInteropTest.kt` | `if (pcm.size <= warmupSamples) return` |
| `chromium_listener_mid_broadcast_mute_shortens_pcm` | `BrowserInteropTest.kt` | same |
| `chromium_decoder_no_errors_through_warmup_window` (I14) | `BrowserInteropTest.kt` | no `decoderOutputs >= 4` floor |
| `chromium_publisher_baseline_kotlin_listener_decodes` | `BrowserInteropTest.kt` | hard-asserts publisher framesIn; soft-asserts listener |
| `chromium_publisher_reconnect_kotlin_listener_recovers` (Browser I7) | `BrowserInteropTest.kt` | same as baseline |
All five have hard assertions on the `framesIn` / publisher-side
behavior; the listener-side is what's soft. None of these are
reaching their full design intent.
## Soft-pass justification audit (per scenario)
Re-read each scenario's kdoc. The soft-pass is honest right now
(captured 0 frames means harness flake, not regression). Once the
relay-routing race is fixed, the listener side becomes deterministic
and the soft-pass is no longer load-bearing — at that point, the
soft-pass HIDES regressions (a real T8/T11/T13 break could land in
a 0-frame outcome and pass vacuously).
## Tighten plan
### Step 1 — confirm sweep stability
After the routing investigation lands, run:
```
for i in 1 2 3 4 5; do
echo "=== run $i ==="
./gradlew :nestsClient:jvmTest \
--tests HangInteropTest \
--tests BrowserInteropTest \
-DnestsHangInterop=true \
-DnestsBrowserInterop=true \
--rerun-tasks 2>&1 | grep -E "FAILED]|BUILD"
done
```
5/5 BUILD SUCCESSFUL with 0 `FAILED` lines = stability achieved.
### Step 2 — replace each soft-pass with a hard floor
For each scenario in the table above, remove the
`if (pcm.size <= warmupSamples) return` short-circuit and replace
with a meaningful sample-count floor. Tighten thresholds based on
observed steady-state numbers (see each scenario's kdoc for what
"steady-state" looks like — most run ≥ 1 s of audio in green-state).
Concretely:
- **Late-join**: `assertTrue(pcm.size >= ...)` floor.
Steady-state captures ~3 s on a 5 s broadcast with 2 s late-join,
minus warmup. Threshold: `≥ 1.5 s` — comfortably under the
steady-state but well over zero.
- **Mute-window**: tighten the upper bound (current 5.5 s) to
~5.0 s. Add a lower bound asserting `≥ 2.5 s` — proves audio
arrived AND the muted segment shortened the total.
- **I14**: re-add `decoderOutputs >= 4` (3 warmup + ≥ 1 audio).
Current absence-only assertion is partial coverage.
- **Browser publisher baseline + reconnect**: remove the
vacuous-pass branches, add a `≥ 0.5 s of audio after warmup`
floor for baseline and `≥ 2.5 s` for reconnect (matches the
hang-tier I7 threshold).
### Step 3 — reverify
Re-run the 5× sweep. All scenarios must hard-pass 5/5. If a
scenario flakes after tightening, the relay-routing investigation
isn't fully done and we revert the tightening on that scenario
until it is.
### Step 4 — update the gap matrix
`nestsClient/plans/2026-05-06-cross-stack-interop-test-gap-matrix.md`
currently lists I14 with "browser ⏳" pending; flip to "✅" once
its hard floor is in. Same for any I-scenarios that now have
hard floors on both tiers.
## Acceptance criteria
- All BrowserInteropTest scenarios run with hard sample-count
AND FFT-peak assertions (no `return@runBlocking` short-circuits
on pcm.size).
- All HangInteropTest scenarios already hard-pass — no change
needed there.
- Gap matrix updated to reflect hard-pass coverage on each T#.
- Results plan updated to remove the "soft-pass on flake"
language.
## Risk: post-tightening flake
If any scenario fail-flakes after tightening, the routing
investigation isn't really done. Don't paper over with a wider
threshold; that's the same trap as the soft-passes. Either:
(a) revert the tightening on that scenario and keep
investigating, OR
(b) widen the threshold ONLY if the new value still excludes
the regression mode the test was designed to catch.