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
| What | State on 2026-10-07 |
|---|---|
| Tracking app and portal | One commit on feature/announcements, with everything else that was in the working tree. Not pushed, not merged |
| Server, L0 | Committed on the backend's branch bugfix/loading_factor_api_technique, on backdev, not merged |
| Server, L2 | Committed, on backdev. Three small fixes (83a811f8) reach backdev with its next rebuild |
| Server, everything else | Asked for in live-hub-backend-handoff-open.md, which is written and not sent |
| Production | Nothing |
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.
| Group | Files | What it is |
|---|---|---|
| Live Hub · portal | 78 | The hub, the set-up page, the lobby, the three views, the display, the result. And the Live Hub's tour |
| Live Hub · shared core | 50 | The live queue, the feed and its stream, joining, the lobby, presence, the realtime client, the device session |
| Live Hub · tracking app | 7 | The join sheet, the live button and its card, the Live tab, the two prompts, the gallery of states |
| Live Hub · chart | 4 | The bar-path chart's size for a display and its labels |
| Live Hub · live tests | 12 | Contract tests against backdev, the load run, an app from today, the display soak |
| Live Hub · documents | 10 | The feature doc's companions: handoffs, replies, the release page, the load run's results, the concept |
| The on-device self-test | 12 | Debug › Self-test, with its Live chapter, and its doc |
| Announcements | 15 | Announcements from the backend in both apps |
| Questionnaire delivery | 10 | The host can send a questionnaire's answers |
| Translations | 3 | Written by npm run i18n:extract from all of the above |
| Handoffs of other features | 4 | Notes to the backend that are not about the Live Hub |
| Offline and sync | 22 | ADR 0002, amendments 7 to 13: the queues, their tests and docs |
| Shared screens and modules | 82 | Files 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 |
| All | 309 |
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
| Check | Result on 2026-10-07 |
|---|---|
npm run typecheck | Passes |
npm run lint | Passes |
npm test | 403 files, 4224 tests passed, 2 skipped |
npm run i18n:extract:check | Up 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, 40 | Passed 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.
| Step | What | Before it | After it, check |
|---|---|---|---|
| 1 | Server: 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 addresses | The two checks under "After the production deploy" |
| 2 | Portal from this commit | Step 1, or nothing: it falls back | A session can be set up, opens in its lobby, shows its code |
| 3 | Tracking app: a build from this commit | Step 1 for joining by code | The evening with real devices, below, on that build |
| 4 | Clean-up | The first check after the production deploy has passed | packages/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. | Do | Must be seen | Seen |
|---|---|---|---|
| 1 | Open a live session in the portal | One request to /realtime/events with the topic workout_live_session:sets: and the session's id, answered 200. No request to /competition_dashboard/join | |
| 2 | Leave that view open for ten minutes without a set | The same request is still open. No second one was started | |
| 3 | Create a session, join one tablet with the code, send a test set, go live, send a set, end it | Each step as on backdev | |
| 4 | Edit a session whose end date lies in the past | What 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. | Do | Must be seen | Seen |
|---|---|---|---|
| 1 | Portal: New live session, Leaderboard, through the steps to the lobby. Take the time | The lobby, with a code of six characters. Under 60 seconds | |
| 2 | Television: open the session, Present | The code, large, with the three steps to join | |
| 3 | Tablet 1: sidebar, Join live session, the code, "Join as Platform 1". Take the time | Within a second a tile "Platform 1" in the portal and on the television. Under 15 seconds | |
| 4 | Tablet 2 the same. The phone, signed in as the athlete: join | The phone asks what may be shared before it joins. After "Agree" it is a tile | |
| 5 | Connect the sensors. One test rep on each device | On each tile: joined, sensor, test set. "Ready" | |
| 6 | Touch nothing for three minutes | No tile and no line says that a device was not heard from. (Finding U1 of the concept: today one will) | |
| 7 | Go live | The television shows the board by itself |
Lift
| No. | Do | Must be seen | Seen |
|---|---|---|---|
| 8 | Six athletes, two sets each, on both tablets | Each set on the television within about a second, with one line about it | |
| 9 | Stand at the furthest place. Read a name, a number, the small grey line | Note for each whether it can be read, and the distance | |
| 10 | The athlete with a history lifts more than their best | A yellow tag and the line "Personal best" | |
| 11 | Someone takes the lead | A tag and a glow on the row; the board stays readable | |
| 12 | Tablet: tap the live button in the header | The session's name, as many sets delivered as were lifted, none waiting. Each athlete's place in the athlete switcher | |
| 13 | Change the load of a set on the tablet. Then delete a set | The row on the television changes in place. The deleted set is gone | |
| 14 | Watch the coach's view for five minutes while people lift | The line about devices says that all are connected, the whole time |
Ten drills
| No. | Do | Must be seen | Seen |
|---|---|---|---|
| 15 | Switch a tablet's Wi-Fi off in the middle of a set. Complete two sets. Switch it on | The live button counts two waiting. Both arrive once, in the order they were lifted | |
| 16 | The same, but close and reopen the app before the Wi-Fi is back. Leave "Resume?" unanswered | Both sets arrive within ten seconds of the connection. (Built on 2026-10-07, block W9: 5 s in a headless browser, live test 51) | |
| 17 | Pull the television's network for a minute. Put it back | It says that it lost its connection, catches up, and the line goes. (Today: it does not say so, block W10) | |
| 18 | Have the server restarted during the session | Tablets and television return by themselves. No set is missing or double | |
| 19 | Complete a set and tap its confirmation several times quickly | One row on the board | |
| 20 | Set a tablet's clock one hour ahead | Its tile still says "online", and its lifts stand in the right order | |
| 21 | End the session while someone is in the middle of a set | The tablet says the session is over. The training goes on, and that set is saved and not on the board | |
| 22 | Everyone completes a set at the same moment | All on the television within three seconds | |
| 23 | Type a wrong code eleven times on a tablet | The eleventh try says how long to wait | |
| 24 | Leave the television on the board when the gym closes | The next morning the screen is on and shows the board or the result |
End
| No. | Do | Must be seen | Seen |
|---|---|---|---|
| 25 | Portal: End session | The podium on the television within a second. The tablets say the session is over | |
| 26 | The result page, then Export | Final table, facts, a PDF | |
| 27 | Run again | A new lobby with a new code. The tablets are not in it | |
| 28 | Finish the trainings on the tablets. Open one in the history | Every 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.tsholds the bodies the tracking app of release tagv3.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 withoutcreated, a delete. Whetherv3.0.7is 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.tssends 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.tsstays until check 1 on production has passed.