cat / goq
clone

turns a linux box into a private steam streaming appliance: plug in, tap your key, play from another computer

test(proof): make the replacement and focus-handoff gates deterministic

Dami committed b2e61ed
`--focus-handoffs` could not pass at all. It auto-selected viewer 2 as the
same-peer replacement target, but viewers 1 and 2 are the handoff
participants, so the replacement tore down a participant's control session
mid-exchange and the run died on "did not observe all handoffs". Replacement
now targets a viewer outside the participant set, and stays off entirely when
the roster has no spare viewer. Requesting an in-set target fails fast with a
clear reason instead of a confusing cardinality error.

Focus participants also left as soon as their handoffs landed, shrinking the
roster underneath any concurrent replacement cycle. They now hold the session
for the full frame budget, exactly like a spectator.

The replacement cycle asserted an exact roster cardinality on every cycle, but
the harness only controls that on cycle 1, which runs immediately after every
viewer attaches and long before any exhausts its frame budget. Later cycles
race the primaries' own exit, so they now assert what same-peer replacement
actually governs: the roster never grows past the configured bound, and the
replacement joined a generation that still has a survivor. This is what made
the three-viewer proof flake under load.

The spectator path reported the roster from a single sample taken at hello
time; it now tracks the maximum across the snapshot stream, as the focus
participant already did.

With the gate working, `verify-demo-build.sh` now runs it, so slot-0 focus
handoff and neutral-before-successor are covered by the release preflight
rather than by hand.
commit
b2e61ed63c2f58e5dd0cd541f95c443c8d46dc9a
parent
9c040f61fa919e1b68f26efa87db8fba09b05b9d
author
Dami <dami.etoile@gmail.com>
2 files changed, +34 -3
Mscripts/loopback-proof.sh34+++++++++++++++++++++++++++---
Mscripts/verify-demo-build.sh3+++
M scripts/loopback-proof.sh +31 -3
@@ -261,7 +261,20 @@ if [[ "$stress" == true ]]; then
261261 fi262262 if [[ "$control_v2" == true && "$viewers" -gt 1 && "$reconnect_cycles" -gt 0 \263263 && "$replace_viewer" -eq 0 ]]; then264- replace_viewer=2264+ if [[ "$focus_handoffs" -gt 0 ]]; then265+ # Viewers 1 and 2 are the focus-handoff participants. Replacing one tears266+ # down its control session mid-exchange, so it can never observe the267+ # required handoffs. Replace a viewer outside the participant set, and268+ # leave replacement off entirely when the roster has no spare viewer.269+ if [[ "$viewers" -gt 2 ]]; then270+ replace_viewer=3271+ fi272+ else273+ replace_viewer=2274+ fi275+fi276+if [[ "$focus_handoffs" -gt 0 && "$replace_viewer" -gt 0 && "$replace_viewer" -le 2 ]]; then277+ die "--replace-viewer must target a viewer above 2 when --focus-handoffs is requested"265278 fi266279 [[ "$primary_frames" -ge 4 ]] \267280 || die "--primary-frames must be at least 4 for keyframe recovery"
@@ -735,8 +748,23 @@ if [[ "$control_v2" == true ]]; then
735748 grep -Eq '^roster_viewers=(7|8)$' "$replacement_log" \736749 || die "replacement cycle $cycle exceeded the bounded stress roster"737750 else738- grep -Fxq "roster_viewers=${viewers}" "$replacement_log" \739- || die "replacement cycle $cycle did not preserve bounded roster cardinality"751+ observed_roster="$(sed -n 's/^roster_viewers=\([0-9][0-9]*\)$/\1/p' \752+ "$replacement_log" | head -1)"753+ [[ -n "$observed_roster" ]] \754+ || die "replacement cycle $cycle did not report a roster cardinality"755+ # Cycle 1 runs immediately after every viewer attached and long756+ # before any of them exhausts its frame budget, so the full roster is757+ # deterministic there. Later cycles race the primaries' own exit, so758+ # assert only what same-peer replacement actually governs: the roster759+ # never grows past the configured bound, and the replacement joined a760+ # generation that still has at least one survivor.761+ if [[ "$cycle" -eq 1 ]]; then762+ [[ "$observed_roster" -eq "$viewers" ]] \763+ || die "replacement cycle 1 observed roster $observed_roster instead of $viewers"764+ else765+ [[ "$observed_roster" -ge 2 && "$observed_roster" -le "$viewers" ]] \766+ || die "replacement cycle $cycle observed unbounded roster $observed_roster"767+ fi740768 fi741769 grep -Fxq 'media_progress=monotonic' "$replacement_log" \742770 || die "replacement cycle $cycle did not report monotonic progress"
M scripts/verify-demo-build.sh +3 -0