Add local task recording and server clock offset

Merged
JS
5d ago
+872-48

Task mode gets an optional local WebM recording of the CodeTrial tab, and its countdown stops depending on the browser's clock. The recording stays in the tab and is never uploaded; camera, fullscreen and visibility monitoring keep running during and after it, and the download survives an attempt ending or the connection dropping. Preparing again after a device replacement or a Start the server never saw offers recording again, the capture picker no longer overlaps fullscreen entry, and an empty recording hands keyboard focus back. A take that was never downloaded is saved before another replaces it, and leaving with unsaved media asks first.

task_state snapshots now carry serverNow (whole-second RFC 3339, payload stays version 1). The page measures the server clock against its monotonic and wall clocks, so a browser clock off by ten minutes either way still shows the right time and keeps counting; a late snapshot cannot lengthen the time left and a sleep can only shorten it. docs/task-mode.md describes both.

Verified with the three browser suites (task-workspace, task-controller, local-recorder: 189 tests passing at the last full run), ESLint and Prettier on the touched files, and cargo fmt. The Rust side (snapshot_now, the moved wire-fixture test and the new session_clock.rs tests) was not compiled on my machine, which has no clang for the webrtc-sys build, so CI is its first run. Recording was exercised against fake capture and MediaRecorder objects, not a real Chrome tab picker.


Summary by cubic

Adds an optional local WebM recording of the CodeTrial tab to task mode, and makes the deadline countdown use the server clock so a browser clock off by minutes in either direction still shows the right time.

  • The recording lives only in the current tab, is never uploaded, and stays downloadable after an attempt ends or the connection drops.
  • A take never downloaded is saved before a later one replaces it, and leaving with unsaved media asks for confirmation first.
  • Recording can restart after a device replacement or a Start the server never confirmed; camera, fullscreen, and visibility monitoring keep running over it.
  • The capture picker no longer overlaps fullscreen entry, and an empty recording returns keyboard focus to the workspace.
  • task_state snapshots now carry serverNow; snapshots without it are refused, and payload version stays 1.