Skip to content

fix(healers): runtime flow-UUID discovery — commit pgm-heal + de-hardcode thumbs (R2) - #44

Draft
guycochran wants to merge 3 commits into
masterfrom
fix/runtime-uuid-discovery-healers
Draft

guycochran wants to merge 3 commits into
masterfrom
fix/runtime-uuid-discovery-healers

Conversation

@guycochran

Copy link
Copy Markdown
Owner

What

The healer-side of reviewer issue #2 (static facility-specific flow UUIDs). The backend/quickstart side was already fixed via tools/facility_from_discovery.py; this brings the same runtime-discovery discipline to the healers, which had been stuck with hardcoded UUIDs.

Consequences of the old state:

  • mxl-pgm-heal.sh could never be committed — it only lived on the box with baked-in UUIDs.
  • mxl_thumbs.py baked in one lab's SLOTS → the Health panel showed dead slots for sources never present and missed the ones that were.

How

Every flow is self-describing: mxl-info -l groups flows under a stable ROLE name (Pattern, Playout, Guest1..N, Guest5Stable, Keyer, Selector) and flow_def.json carries the same role in its grouphint tag. The healers now name roles and resolve UUIDs at runtime.

  • tools/mxl-flows.sh (new) — sourceable POSIX discovery helper: flow_by_role / flow_present / all_video_roles over a cached mxl-info -l snapshot.
  • tools/mxl-pgm-heal.sh (new; was box-only) — boot/recovery heal: wire selector from discovered present roles, cut to the first advancing slot, point the encoder at the selector output (keyer bypassed by default), verify advancing. Zero hardcoded UUIDs. Correspondent slots prefer GuestNStable (never-interrupt).
  • tools/mxl_thumbs.py — discover SLOTS from the domain; a supervisor re-scans so sources appearing after startup get a worker and a role whose flow is recreated with a new UUID re-attaches (fixes the ~2min slow re-attach wedge, HW Oct 10). Exclude selector/keyer (program outputs); collapse GuestNStable → guestN. Run loop guarded under __main__ so the module is importable for tests.
  • tests/test_thumb_slots.py (new) — pins the discovery contract (7 cases).

Verification

  • python3 -m pytest → 156 pass; node --test tests/js/*.test.js → 68 pass.
  • Discovery dry-run against the live lab domain produced the exact correct 6-slot selector input list (pattern, playout, guest1=Makito, guest3=PTZ, guest5/6 stable) with zero hardcoding — matching what the box's hardcoded script produced.
  • No live-system changes — code + tests only, per the review rules of engagement.

🤖 Generated with Claude Code

guycochran and others added 3 commits October 10, 2026 21:21
…code thumbs (R2)

The healers carried facility-specific flow UUIDs, so pgm-heal could never be
committed (it only lived on the box) and the thumbs probe baked in one lab's
SLOTS — stale UUIDs made the Health panel show dead slots for sources that were
never present and miss the ones that were. This is the healer-side of reviewer
issue #2 (the backend/quickstart side was fixed via facility_from_discovery.py).

Every flow is already self-describing: `mxl-info -l` groups flows under a stable
ROLE name (Pattern, Playout, Guest1..N, Guest5Stable, Keyer, Selector) and
flow_def.json carries the same role in its grouphint tag. So the healers name
ROLES and resolve UUIDs at runtime — portable to any facility.

- tools/mxl-flows.sh: NEW sourceable POSIX discovery helper (flow_by_role /
  flow_present / all_video_roles) over a cached `mxl-info -l` snapshot.
- tools/mxl-pgm-heal.sh: NEW (was box-only). Boot/recovery heal — wire selector
  from DISCOVERED present roles, cut to the first advancing slot, point the
  encoder at the selector output (keyer bypassed by default), verify advancing.
  Zero hardcoded UUIDs; correspondent slots prefer GuestNStable (never-interrupt).
- tools/mxl_thumbs.py: discover SLOTS from the domain instead of a static dict;
  a supervisor re-scans so sources appearing AFTER startup get a worker and a
  role whose flow is recreated with a new UUID re-attaches (fixes the ~2min slow
  re-attach wedge); exclude selector/keyer (program outputs), collapse
  GuestNStable -> guestN. Run loop guarded under __main__ so it's importable.
- tests/test_thumb_slots.py: pin the discovery contract (7 cases).

Suite: 156 pytest + 68 node green. No live-system changes (code+tests only).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017YNw5igfxCp4mUoMMMM9pv
… (SwitchFrame-inspired)

The CBC input-selector parks running:true + 'read source grain N: Out of range - too late'
when its active source delivers a grain outside the readable window (jittery/relayed/
framerate-mismatched — HW Oct: PTZ over the Azure relay wedged it on every cut, all further
cuts 415-reject, PGM frozen). CBC's selector does not self-recover.

Borrowing the strategy from thiagopnts/switchframe's Go MXL reader
(server/mxl/reader.go: 'On too-late errors, re-sync to the current write head instead of
dying'): we can't patch CBC's Rust, so we apply the same idea at our layer — on a too-late
error, re-cut the selector to a VERIFIED-ADVANCING slot, which forces the router to re-grab
from the current write head and clears the wedge. 20s cooldown; role/discovery based (uses
tools/mxl-flows.sh), no hardcoded UUIDs.

Verified: wedge-string detection matches the exact HW error; ignores non-wedge states.
NOT yet HW-tested (box unreachable at commit time — ssh tunnel down); deploy + verify next.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwSKEZZz4yEc2CGq5hcTmT
…ver-switch+browser), borrowable ideas ranked

SwitchFrame is a mature Go/Svelte engine on the same MXL substrate. Documents where it's ahead
(re-sync reader, SIMD v210, atomic graph swap, GPU kernels), the one lesson we already applied
(re-sync-instead-of-die for the selector too-late wedge), and a ranked list of ideas to borrow
next. Strategic read: borrow their algorithms, keep our adoptable/portable/commodity-HW edge.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwSKEZZz4yEc2CGq5hcTmT
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