Skip to main content

Live Hub: shipping what exists

Audience: the product owner, and whoever releases. Status: written on 2026-10-07 as work block W16 of LIVE_HUB_CONCEPT.html. The commit is made. The evening with real devices and the checks on production are not done; this page holds the script for both.

In two days the Live Hub went from an audit to a chain that runs from the first click to the podium. Until 2026-10-07 none of it was committed. This page says what the commit holds, in which order the pieces reach a gym, and what has to be seen with real devices before a customer sees it.

Where things are​

WhatState on 2026-10-07
Tracking app and portalOne commit on feature/announcements, with everything else that was in the working tree. Not pushed, not merged
Server, L0Committed on the backend's branch bugfix/loading_factor_api_technique, on backdev, not merged
Server, L2Committed, on backdev. Three small fixes (83a811f8) reach backdev with its next rebuild
Server, everything elseAsked for in live-hub-backend-handoff-open.md, which is written and not sent
ProductionNothing

What the commit of 2026-10-07 holds​

One commit, with the subject "feat: Live Hub clients L0–L6, with offline, announcement and questionnaire work".

Why one commit and not one per phase. The working tree held four pieces of work that had grown side by side: the Live Hub, the offline and sync work of ADR 0002, announcements, and questionnaire delivery. They meet in the same files: the training screen, the app's layout, the icon set, the translation catalogue, the local database's version. A commit per phase would have needed those files cut by hand, and no commit in between would have built. The tree as a whole passes the checks below, so it is committed as a whole.

GroupFilesWhat it is
Live Hub · portal78The hub, the set-up page, the lobby, the three views, the display, the result. And the Live Hub's tour
Live Hub · shared core50The live queue, the feed and its stream, joining, the lobby, presence, the realtime client, the device session
Live Hub · tracking app7The join sheet, the live button and its card, the Live tab, the two prompts, the gallery of states
Live Hub · chart4The bar-path chart's size for a display and its labels
Live Hub · live tests12Contract tests against backdev, the load run, an app from today, the display soak
Live Hub · documents10The feature doc's companions: handoffs, replies, the release page, the load run's results, the concept
The on-device self-test12Debug › Self-test, with its Live chapter, and its doc
Announcements15Announcements from the backend in both apps
Questionnaire delivery10The host can send a questionnaire's answers
Translations3Written by npm run i18n:extract from all of the above
Handoffs of other features4Notes to the backend that are not about the Live Hub
Offline and sync22ADR 0002, amendments 7 to 13: the queues, their tests and docs
Shared screens and modules82Files that more than one of the pieces changed (the training screen, the layouts, the icon set, the API client, the training models), and the rest of the offline work. Not sorted further
All309

Left out on purpose: apps/tracking/ios/App/App.xcodeproj/project.pbxproj. Its only change empties the build step that runs set-version.sh, which looks like an accident of Xcode and would take the version stamp out of the iOS build. It is still changed in the working tree; revert it or commit it knowingly.

To take the commit back without losing a line: git reset --soft HEAD~1 (or HEAD~2 after dev was merged). The branch has never been pushed.

Every file, by group​

Live Hub · portal (78)

new apps/portal/src/app/dashboard/live/athlete-past.test.ts
new apps/portal/src/app/dashboard/live/athlete-past.ts
changed apps/portal/src/app/dashboard/live/attempt-detail-sheet.tsx
new apps/portal/src/app/dashboard/live/board-parts.tsx
changed apps/portal/src/app/dashboard/live/competition-view.tsx
new apps/portal/src/app/dashboard/live/demo-script.test.ts
new apps/portal/src/app/dashboard/live/demo-script.ts
new apps/portal/src/app/dashboard/live/demo-trajectory.test.ts
new apps/portal/src/app/dashboard/live/demo-trajectory.ts
changed apps/portal/src/app/dashboard/live/derive-competition.test.ts
changed apps/portal/src/app/dashboard/live/derive-competition.ts
changed apps/portal/src/app/dashboard/live/derive-stream.ts
new apps/portal/src/app/dashboard/live/device-picker-list.tsx
new apps/portal/src/app/dashboard/live/display-rule.test.ts
new apps/portal/src/app/dashboard/live/display-rule.ts
changed apps/portal/src/app/dashboard/live/exercise-header.tsx
changed apps/portal/src/app/dashboard/live/exercise-pane.tsx
new apps/portal/src/app/dashboard/live/format-previews.tsx
new apps/portal/src/app/dashboard/live/idle-end.test.ts
new apps/portal/src/app/dashboard/live/idle-end.ts
changed apps/portal/src/app/dashboard/live/leaderboard-export.tsx
changed apps/portal/src/app/dashboard/live/leaderboard-view.tsx
new apps/portal/src/app/dashboard/live/lift-insight-line.test.ts
new apps/portal/src/app/dashboard/live/lift-insight-line.tsx
new apps/portal/src/app/dashboard/live/lift-insight.test.ts
new apps/portal/src/app/dashboard/live/lift-insight.ts
changed apps/portal/src/app/dashboard/live/lift-leaderboard-overlay.tsx
new apps/portal/src/app/dashboard/live/live-demo.tsx
new apps/portal/src/app/dashboard/live/live-feed-error.tsx
new apps/portal/src/app/dashboard/live/live-health-line.tsx
new apps/portal/src/app/dashboard/live/live-hub-intro.tsx
changed apps/portal/src/app/dashboard/live/live-hub.tsx
changed apps/portal/src/app/dashboard/live/live-session-drawer.tsx
changed apps/portal/src/app/dashboard/live/live-view.tsx
new apps/portal/src/app/dashboard/live/live-waiting-state.tsx
new apps/portal/src/app/dashboard/live/live-waiting.test.ts
new apps/portal/src/app/dashboard/live/live-waiting.ts
new apps/portal/src/app/dashboard/live/lobby-view.tsx
changed apps/portal/src/app/dashboard/live/page.tsx
new apps/portal/src/app/dashboard/live/path-numbers.test.ts
new apps/portal/src/app/dashboard/live/path-numbers.ts
changed apps/portal/src/app/dashboard/live/peak-markers.ts
changed apps/portal/src/app/dashboard/live/present-mode.tsx
changed apps/portal/src/app/dashboard/live/rank-metrics-sheet.tsx
new apps/portal/src/app/dashboard/live/rank-selection.test.ts
new apps/portal/src/app/dashboard/live/rank-selection.ts
new apps/portal/src/app/dashboard/live/result-parts.tsx
new apps/portal/src/app/dashboard/live/result-store.test.ts
new apps/portal/src/app/dashboard/live/result-store.ts
new apps/portal/src/app/dashboard/live/result-summary.test.ts
new apps/portal/src/app/dashboard/live/result-summary.ts
new apps/portal/src/app/dashboard/live/result-view.tsx
changed apps/portal/src/app/dashboard/live/session-config.test.ts
changed apps/portal/src/app/dashboard/live/session-config.ts
new apps/portal/src/app/dashboard/live/session-result.test.ts
new apps/portal/src/app/dashboard/live/session-result.ts
new apps/portal/src/app/dashboard/live/setup-page.tsx
changed apps/portal/src/app/dashboard/live/stream-detail.tsx
changed apps/portal/src/app/dashboard/live/stream-view.tsx
changed apps/portal/src/app/dashboard/live/trajectory-preview.tsx
changed apps/portal/src/app/dashboard/live/use-athlete-pair.ts
new apps/portal/src/app/dashboard/live/use-athlete-past.ts
changed apps/portal/src/app/dashboard/live/use-decoded-live-reps.ts
changed apps/portal/src/app/dashboard/live/use-rank-metrics.ts
changed apps/portal/src/app/dashboard/live/use-rank-selections.ts
new apps/portal/src/app/dashboard/live/use-session-result.ts
new apps/portal/src/app/dashboard/live/use-weightlifting-lift.ts
changed apps/portal/src/app/dashboard/live/view-config.test.ts
changed apps/portal/src/app/dashboard/live/view-config.ts
new apps/portal/src/app/dashboard/live/wall-board.tsx
new apps/portal/src/app/dashboard/live/wall-lobby.tsx
new apps/portal/src/app/dashboard/live/wall-result.tsx
new apps/portal/src/app/dashboard/live/wall-zoom.test.ts
new apps/portal/src/app/dashboard/live/wall-zoom.ts
new apps/portal/src/app/dashboard/live/weightlifting-platform.tsx
changed apps/portal/src/tours/tour-targets.ts
deleted apps/portal/src/tours/use-live-create-tour.ts
changed apps/portal/src/tours/use-live-tour.ts

Live Hub · shared core (50)

changed packages/core/src/api/dtos/live-sessions.ts
changed packages/core/src/api/dtos/user-device-sessions.ts
changed packages/core/src/api/live-sessions.ts
changed packages/core/src/api/mappers/live-sessions.test.ts
changed packages/core/src/api/mappers/live-sessions.ts
changed packages/core/src/device-session/hooks.ts
changed packages/core/src/device-session/store.test.ts
changed packages/core/src/device-session/store.ts
new packages/core/src/device-session/stream.test.ts
new packages/core/src/device-session/stream.ts
changed packages/core/src/live-session/dashboard-bridge.ts
new packages/core/src/live-session/demo.ts
renamed packages/core/src/live-session/derive-leaderboard.test.ts
renamed packages/core/src/live-session/derive-leaderboard.ts
new packages/core/src/live-session/earlier-sets.test.ts
new packages/core/src/live-session/earlier-sets.ts
changed packages/core/src/live-session/feed-hooks.ts
changed packages/core/src/live-session/feed-schema.ts
changed packages/core/src/live-session/feed-store.test.ts
changed packages/core/src/live-session/feed-store.ts
new packages/core/src/live-session/feed-stream.test.ts
changed packages/core/src/live-session/feed-stream.ts
new packages/core/src/live-session/feed-types.test.ts
changed packages/core/src/live-session/feed-types.ts
new packages/core/src/live-session/join-code.test.ts
new packages/core/src/live-session/join-code.ts
new packages/core/src/live-session/lobby-hooks.ts
new packages/core/src/live-session/lobby-readiness.test.ts
new packages/core/src/live-session/lobby-readiness.ts
new packages/core/src/live-session/lobby-store.test.ts
new packages/core/src/live-session/lobby-store.ts
new packages/core/src/live-session/lobby-stream.test.ts
new packages/core/src/live-session/lobby-stream.ts
new packages/core/src/live-session/presence.test.ts
new packages/core/src/live-session/presence.ts
changed packages/core/src/live-session/producer.test.ts
changed packages/core/src/live-session/producer.ts
new packages/core/src/live-session/sessions-store.test.ts
changed packages/core/src/live-session/sessions-store.ts
new packages/core/src/live-session/sharing-consent.test.ts
new packages/core/src/live-session/sharing-consent.ts
changed packages/core/src/live-session/use-broadcast.ts
new packages/core/src/live-session/use-earlier-sets.ts
new packages/core/src/live-session/use-live-standings.ts
new packages/core/src/live-session/use-presence.ts
new packages/core/src/live-session/use-sharing-consent.ts
new packages/core/src/offline/live-queue.test.ts
new packages/core/src/offline/live-queue.ts
changed packages/core/src/realtime/client.test.ts
changed packages/core/src/realtime/client.ts

Live Hub · tracking app (7)

changed apps/tracking/src/app/debug/connection/ConnectionGallery.tsx
new apps/tracking/src/app/workouts/today/live-earlier-sets-prompt.tsx
new apps/tracking/src/app/workouts/today/live-session-row.tsx
new apps/tracking/src/app/workouts/today/live-sharing-prompt.tsx
new apps/tracking/src/app/workouts/today/live-sheet.tsx
new apps/tracking/src/app/workouts/today/live-status-button.tsx
new apps/tracking/src/app/workouts/today/live-tab.tsx

Live Hub · chart (4)

changed packages/ui/src/charts/technique-trajectory-chart.stories.tsx
changed packages/ui/src/charts/technique-trajectory-chart.tsx
new packages/ui/src/charts/trajectory-marker-labels.test.ts
new packages/ui/src/charts/trajectory-marker-labels.ts

Live Hub · live tests (12)

new tests/live/compat/store-build-v3.0.7.ts
new tests/live/load/live-set-load.ts
new tests/live/offline/12-live-outbox.live.test.ts
new tests/live/offline/14-live-session-config.live.test.ts
new tests/live/offline/15-live-l0-contract.live.test.ts
new tests/live/offline/16-live-set-topic.live.test.ts
new tests/live/offline/17-live-set-load.live.test.ts
new tests/live/offline/18-selftest-live-chapter.live.test.ts
new tests/live/offline/25-live-l2-contract.live.test.ts
new tests/live/offline/40-live-result-contract.live.test.ts
new tests/live/offline/80-store-build-compat.live.test.ts
new tests/live/offline/81-display-soak.live.test.ts

Live Hub · documents (10)

new LIVE_HUB_CONCEPT.html
new docs/live-hub-backend-handoff-l2.md
new docs/live-hub-backend-handoff-l3.md
new docs/live-hub-backend-handoff-open.md
new docs/live-hub-backend-handoff.md
new docs/live-hub-backend-reply-2.md
new docs/live-hub-backend-reply.md
new docs/live-hub-release.md
changed docs/live-performance-hub.md
new docs/testing/live-set-load-run.md

The on-device self-test (12)

new apps/tracking/src/app/debug/selftest/SelfTestScreen.tsx
new apps/tracking/src/app/debug/selftest/checks.ts
new apps/tracking/src/app/debug/selftest/live-checks.ts
new apps/tracking/src/app/debug/selftest/live-compare.test.ts
new apps/tracking/src/app/debug/selftest/live-compare.ts
new apps/tracking/src/app/debug/selftest/page.tsx
new apps/tracking/src/app/debug/selftest/protocol.test.ts
new apps/tracking/src/app/debug/selftest/protocol.ts
new apps/tracking/src/app/debug/selftest/run-selftest.ts
new apps/tracking/src/app/debug/selftest/runner.test.ts
new apps/tracking/src/app/debug/selftest/runner.ts
new docs/testing/offline-self-test.md

Announcements (15)

new docs/announcements.md
new packages/core/src/announcements/api.test.ts
new packages/core/src/announcements/api.ts
new packages/core/src/announcements/condition.test.ts
new packages/core/src/announcements/condition.ts
new packages/core/src/announcements/hooks.ts
new packages/core/src/announcements/rules.test.ts
new packages/core/src/announcements/rules.ts
new packages/core/src/announcements/schema.test.ts
new packages/core/src/announcements/schema.ts
new packages/core/src/announcements/store.ts
new packages/core/src/announcements/types.ts
new packages/ui/src/announcements/announcement-dialog.stories.tsx
new packages/ui/src/announcements/announcement-dialog.tsx
new packages/ui/src/announcements/announcement-host.tsx

Questionnaire delivery (10)

changed apps/portal/src/app/questionnaire/page.tsx
changed apps/portal/src/questionnaire-service/host-auth.ts
changed apps/portal/src/questionnaire-service/host-bridge.ts
new apps/tracking/src/app/workouts/today/questionnaire-delivery.test.ts
new apps/tracking/src/app/workouts/today/questionnaire-delivery.ts
changed docs/questionnaire-service.md
changed packages/core/src/api/dtos/questionnaire.ts
new packages/core/src/offline/questionnaire-queue.test.ts
new packages/core/src/offline/questionnaire-queue.ts
new tests/live/offline/11-questionnaire-queue.live.test.ts

Translations (3)

changed i18n.catalog.json
changed packages/core/src/translations/baseline/en.json
changed packages/core/src/translations/keys.ts

Handoffs of other features (4)

new handoffs/OFFLINE_SYNC_BACKEND_HANDOFF.md
changed handoffs/README.md
new handoffs/VELOCITY_PROFILE_REFIT_BACKEND_HANDOFF.md
new handoffs/WELLNESS_DOCS_HANDOFF.md

Offline and sync (22)

changed docs/decisions/0002-offline-training-persistence.md
changed docs/offline-and-sync.md
new packages/core/src/offline/account-snapshot.test.ts
new packages/core/src/offline/account-snapshot.ts
changed packages/core/src/offline/day-bundle-store.test.ts
changed packages/core/src/offline/day-bundle-store.ts
new packages/core/src/offline/finished-workouts.test.ts
new packages/core/src/offline/finished-workouts.ts
new packages/core/src/offline/library-snapshots.test.ts
changed packages/core/src/offline/orchestrator.test.ts
changed packages/core/src/offline/orchestrator.ts
changed packages/core/src/offline/owner.test.ts
changed packages/core/src/offline/pending-rep-store.test.ts
changed packages/core/src/offline/pending-rep-store.ts
changed packages/core/src/offline/reference-cache.ts
new packages/core/src/offline/retrospective-drafts.test.ts
new packages/core/src/offline/retrospective-drafts.ts
changed packages/core/src/offline/stores.ts
changed packages/core/src/offline/upload-queue.test.ts
changed packages/core/src/offline/upload-queue.ts
new tests/live/offline/10-unbound-session-upload.live.test.ts
new tests/live/offline/13-per-session-outcomes.live.test.ts

Shared screens and modules (82)

changed apps/portal/src/app/dashboard/data/export/page.tsx
changed apps/portal/src/app/dashboard/data/insights/page.tsx
changed apps/portal/src/app/dashboard/page.tsx
changed apps/portal/src/app/dashboard/workouts/page.tsx
changed apps/portal/src/app/layout.tsx
changed apps/tracking/src/app/ApiConfigInit.tsx
changed apps/tracking/src/app/debug/DebugChrome.tsx
new apps/tracking/src/app/debug/NetworkFaultBadge.tsx
changed apps/tracking/src/app/debug/screenshots/screens.tsx
changed apps/tracking/src/app/debug/sidebar/SidebarGallery.tsx
changed apps/tracking/src/app/layout.tsx
changed apps/tracking/src/app/workouts/today/ExerciseDetailView.tsx
changed apps/tracking/src/app/workouts/today/InsightsSheet.tsx
changed apps/tracking/src/app/workouts/today/TrainingSession.tsx
changed apps/tracking/src/app/workouts/today/WorkoutDetailsDrawer.tsx
changed apps/tracking/src/app/workouts/today/overview-tab.tsx
changed apps/tracking/src/app/workouts/today/page.tsx
changed apps/tracking/src/app/workouts/today/resolve-user-exercises.test.ts
changed apps/tracking/src/app/workouts/today/resolve-user-exercises.ts
changed apps/tracking/src/app/workouts/today/retrospective/RetrospectiveFillView.tsx
changed apps/tracking/src/app/workouts/today/retrospective/RetrospectiveStation.tsx
new apps/tracking/src/app/workouts/today/retrospective/draft.test.ts
new apps/tracking/src/app/workouts/today/retrospective/draft.ts
changed apps/tracking/src/app/workouts/today/retrospective/use-retrospective-upload.ts
changed apps/tracking/src/app/workouts/today/session-rpe/session-rpe-sheet.tsx
changed apps/tracking/src/app/workouts/today/sidebar-actions.tsx
changed apps/tracking/src/app/workouts/today/today-workouts-pane.tsx
changed apps/tracking/src/app/workouts/today/unresolved-summary.test.ts
changed apps/tracking/src/app/workouts/today/unresolved-summary.ts
changed apps/tracking/src/app/workouts/today/use-finish-training.ts
new apps/tracking/src/app/workouts/today/use-finished-workouts.ts
deleted apps/tracking/src/app/workouts/today/use-offline-coverage.ts
new apps/tracking/src/app/workouts/today/use-offline-day.test.ts
changed apps/tracking/src/app/workouts/today/use-offline-day.ts
changed apps/tracking/src/app/workouts/today/use-offline-status.ts
changed apps/tracking/src/app/workouts/today/use-training-sessions.ts
changed apps/tracking/src/app/workouts/today/use-upload-drain.ts
changed apps/tracking/src/app/workouts/today/use-workout-exercises.ts
changed apps/tracking/src/app/workouts/today/wellness/wellness-check-in-sheet.tsx
changed apps/tracking/src/app/workouts/today/workouts-today-list.tsx
changed docs/error-handling.md
changed docs/product-guidance-backend.md
changed docs/state-management.md
changed docs/testing.md
changed docs/tracking-app-features.md
changed packages/core/src/api/capacitor-http.ts
changed packages/core/src/api/client.ts
new packages/core/src/api/fault-injection.test.ts
new packages/core/src/api/fault-injection.ts
new packages/core/src/api/mappers/session-upload-outcomes.test.ts
new packages/core/src/api/mappers/session-upload-outcomes.ts
changed packages/core/src/api/mappers/sessions.ts
new packages/core/src/api/mappers/unbound-sessions.test.ts
new packages/core/src/api/mappers/unbound-sessions.ts
changed packages/core/src/api/sessions.test.ts
changed packages/core/src/api/sessions.ts
new packages/core/src/api/transport.test.ts
changed packages/core/src/api/transport.ts
changed packages/core/src/auth-guard.tsx
new packages/core/src/auth/unauthorized-hold.test.ts
new packages/core/src/auth/unauthorized-hold.ts
changed packages/core/src/auth/use-auth-flow.test.ts
changed packages/core/src/coaching/session-rm1.ts
changed packages/core/src/coaching/set-exertion.ts
new packages/core/src/exercises/store-snapshot.test.ts
changed packages/core/src/exercises/store.ts
changed packages/core/src/store-kit/status.test.ts
changed packages/core/src/store-kit/status.ts
changed packages/core/src/training/models.ts
changed packages/core/src/training/sessions.test.ts
changed packages/core/src/training/sessions.ts
changed packages/core/src/training/set-scheme-templates.test.ts
changed packages/core/src/training/set-scheme.ts
changed packages/core/src/ui-text-content/store.ts
changed packages/core/src/users/store.ts
changed packages/core/src/workouts/store.ts
changed packages/ui/src/auth/auth-steps.tsx
new packages/ui/src/avatar-upload-field.stories.tsx
changed packages/ui/src/icons/index.tsx
changed packages/ui/src/settings/logout-button.tsx
changed packages/ui/src/settings/settings-drawer.tsx
changed tests/live/vitest.config.ts

What passed on the commit​

CheckResult on 2026-10-07
npm run typecheckPasses
npm run lintPasses
npm test403 files, 4224 tests passed, 2 skipped
npm run i18n:extract:checkUp to date, 3097 strings
The docs build (npm run docs:docusaurus)Passes
Live test 80, an app from today (below)Passes on backdev
Live tests 12, 14 to 18, 25, 40Passed on backdev when their blocks were finished, on 2026-10-06 and 2026-10-07. Not run again for this commit

The order of a release​

Each step can be taken alone. The clients are written to run against a server without L2: a session without a state is live from its creation, a join code that is absent is not shown.

StepWhatBefore itAfter it, check
1Server: L0, L2, the cheaper reads, 83a811f8 and 13b7a267 as one release (handoff R1; agreed by the backend on 2026-10-07)The count of sessions past their end date that are still used, and the product owner's decision on them (R2). The slim person on a live set (S2): with L2 an athlete's own phone joins, and must not receive other people's e-mail addressesThe two checks under "After the production deploy"
2Portal from this commitStep 1, or nothing: it falls backA session can be set up, opens in its lobby, shows its code
3Tracking app: a build from this commitStep 1 for joining by codeThe evening with real devices, below, on that build
4Clean-upThe first check after the production deploy has passedpackages/core/src/live-session/dashboard-bridge.ts and its use in feed-stream.ts are deleted

After the production deploy​

With a real account, in a browser with its network panel open.

No.DoMust be seenSeen
1Open a live session in the portalOne request to /realtime/events with the topic workout_live_session:sets: and the session's id, answered 200. No request to /competition_dashboard/join
2Leave that view open for ten minutes without a setThe same request is still open. No second one was started
3Create a session, join one tablet with the code, send a test set, go live, send a set, end itEach step as on backdev
4Edit a session whose end date lies in the pastWhat decision R2 says: it is over, or its date was cleared

When check 1 has passed, step 4 of the release can be taken.

One evening with real devices​

Nothing of the Live Hub has been seen on a real television, a packaged app or a real sensor. Every check so far ran in a headless browser. This is the script for the one evening that changes that. Write what was seen into the last column; an empty cell means "not tried".

Bring: a build of the tracking app from this commit on two tablets and on one phone · a server with L2 (backdev, or production after step 1) · the television of the gym with a browser, or a laptop on HDMI · a sensor per tablet · a coach's account with six athletes, one of whom signs in on the phone with their own login and has lifted the exercise before · a tape measure.

Write down first: the size of the television, and the distance from it to the furthest place where people stand between sets.

Set up and join​

No.DoMust be seenSeen
1Portal: New live session, Leaderboard, through the steps to the lobby. Take the timeThe lobby, with a code of six characters. Under 60 seconds
2Television: open the session, PresentThe code, large, with the three steps to join
3Tablet 1: sidebar, Join live session, the code, "Join as Platform 1". Take the timeWithin a second a tile "Platform 1" in the portal and on the television. Under 15 seconds
4Tablet 2 the same. The phone, signed in as the athlete: joinThe phone asks what may be shared before it joins. After "Agree" it is a tile
5Connect the sensors. One test rep on each deviceOn each tile: joined, sensor, test set. "Ready"
6Touch nothing for three minutesNo tile and no line says that a device was not heard from. (Finding U1 of the concept: today one will)
7Go liveThe television shows the board by itself

Lift​

No.DoMust be seenSeen
8Six athletes, two sets each, on both tabletsEach set on the television within about a second, with one line about it
9Stand at the furthest place. Read a name, a number, the small grey lineNote for each whether it can be read, and the distance
10The athlete with a history lifts more than their bestA yellow tag and the line "Personal best"
11Someone takes the leadA tag and a glow on the row; the board stays readable
12Tablet: tap the live button in the headerThe session's name, as many sets delivered as were lifted, none waiting. Each athlete's place in the athlete switcher
13Change the load of a set on the tablet. Then delete a setThe row on the television changes in place. The deleted set is gone
14Watch the coach's view for five minutes while people liftThe line about devices says that all are connected, the whole time

Ten drills​

No.DoMust be seenSeen
15Switch a tablet's Wi-Fi off in the middle of a set. Complete two sets. Switch it onThe live button counts two waiting. Both arrive once, in the order they were lifted
16The same, but close and reopen the app before the Wi-Fi is back. Leave "Resume?" unansweredBoth sets arrive within ten seconds of the connection. (Built on 2026-10-07, block W9: 5 s in a headless browser, live test 51)
17Pull the television's network for a minute. Put it backIt says that it lost its connection, catches up, and the line goes. (Today: it does not say so, block W10)
18Have the server restarted during the sessionTablets and television return by themselves. No set is missing or double
19Complete a set and tap its confirmation several times quicklyOne row on the board
20Set a tablet's clock one hour aheadIts tile still says "online", and its lifts stand in the right order
21End the session while someone is in the middle of a setThe tablet says the session is over. The training goes on, and that set is saved and not on the board
22Everyone completes a set at the same momentAll on the television within three seconds
23Type a wrong code eleven times on a tabletThe eleventh try says how long to wait
24Leave the television on the board when the gym closesThe next morning the screen is on and shows the board or the result

End​

No.DoMust be seenSeen
25Portal: End sessionThe podium on the television within a second. The tablets say the session is over
26The result page, then ExportFinal table, facts, a PDF
27Run againA new lobby with a new code. The tablets are not in it
28Finish the trainings on the tablets. Open one in the historyEvery set of the evening with its values

An app from today​

The rule of every handoff is that the server only adds, so that a tablet which was not updated keeps working. Until 2026-10-07 nothing tested that. Now:

  • tests/live/compat/store-build-v3.0.7.ts holds the bodies the tracking app of release tag v3.0.7 (2026-09-25) sends while its device is in a live session, read off that tag: a finished set whose reps carry no id of their own, an edit without created, a delete. Whether v3.0.7 is the build in the stores is for the product owner to confirm; it is the newest release tag in the repository.
  • tests/live/offline/80-store-build-compat.live.test.ts sends them to backdev through raw requests: the coach picks the device, the device reads that from its device session, sends, sends the same again, edits, deletes, and gets "not in a session" after the end.
npx vitest run --config tests/live/vitest.config.ts tests/live/offline/80-store-build-compat

Result on 2026-10-07: passes. POST 201, the repeat leaves one set, PUT 200 with each rep keeping exactly one sensor package although that build sends no rep ids, DELETE removes the set, a POST after the end answers 204.

When the app is released again, add a file for that tag beside the first and run both. What the test cannot see: anything a real device does that the tag does not show.

A display left alone​

tests/live/offline/81-display-soak.live.test.ts opens the Live Hub's demo on a display in a headless Chrome and looks at it once a minute: memory after a forced collection, DOM nodes, event listeners, how often the realtime stream was opened, errors, and whether the board still names the demo's athletes. It runs only when asked for, and needs a running portal and a path to puppeteer-core, which is not a dependency of this repository:

ENODE_DISPLAY_SOAK_MINUTES=480 \
ENODE_PORTAL_URL=http://localhost:3001 \
ENODE_PUPPETEER=/path/to/puppeteer-core/lib/esm/puppeteer/puppeteer-core.js \
npx vitest run --config tests/live/vitest.config.ts tests/live/offline/81-display-soak

First runs on 2026-10-07: two minutes and four minutes, against the development server. After a forced collection the page held 22.7 to 24.8 MB, 730 to 890 DOM nodes and about 860 listeners, with no direction in any of the three. The stream was opened twice at the start and not again. No error on the console or on the page; the board was on screen at every look. A run of half an hour was started and stopped again so that it did not hold the commit. So these numbers say that the tool works, and nothing yet about a working day.

What is open in this block​

  • The evening with real devices. The script above; nobody has run it.
  • The checks after the production deploy. They wait for the deploy.
  • Eight hours. The soak ran for four minutes, in the development server. Run it for a working day against a production build before a display is left in a customer's gym.
  • Three coaches who have not seen it set up their first session, timed. Step 1 of the evening does it once, with someone who knows the feature.
  • dashboard-bridge.ts stays until check 1 on production has passed.