# HEVC upstream implementation checklist

This is the working checklist for moving Lesavka upstream media from MJPEG-only transport toward HEVC/H.265 video transport while preserving the already-calibrated MJPEG server-to-RCT path.

## Goals

- Keep the existing MJPEG ingress and MJPEG UVC output calibration valid.
- Add first-class HEVC ingress on the server, decoded to the existing MJPEG UVC output path.
- Calibrate server-to-RCT delays per ingress profile and UVC mode.
- Send client-origin synthetic A/V as bundled audio plus HEVC video through the same handoff used by real capture.
- Measure final RCT sync, freshness, and smoothness before adding deeper introspection.

## Safety constraints

- Do not reboot Theia unless SSH/service recovery cannot be achieved any other way.
- If Theia must be rebooted, wait for it to come back online and resume from the last artifact-backed checkpoint.
- Keep server-to-RCT measurement tooling intact except for additive HEVC/profile support.
- Do not overwrite the MJPEG static delay profile with HEVC values.
- Bump package versions before any push that contains code changes.

## Access and automation

- [x] Theia helper supports `deploy`, `restart`, `status`, `hevc-prereqs`, and `reconfigure MODE [hevc|mjpeg]`.
- [x] Passwordless sudo works for `/usr/local/sbin/lesavka-dev-install`.
- [x] `reconfigure 1920x1080@30 hevc` was verified with all services active.
- [x] `reconfigure 1280x720@20 hevc` rebuilt descriptors; Tethys saw `1280x720@20` MJPEG.
- [x] Patch local `lesavka-core.sh` so slow `udevadm control --reload` becomes a warning instead of aborting reconfigure.
- [ ] Deploy the hardened `lesavka-core.sh` to Theia once SSH completes banner exchange again.

## Server-to-RCT HEVC calibration

- [x] `1920x1080@30` HEVC ingress was measured ready in `/tmp/lesavka-server-rc-mode-matrix-20260507-033941`.
- [x] `1920x1080@30` candidate: video `127952us`, audio `0us`, p95 max `5.3ms`, freshness budget max `252.3ms`.
- [x] Initial failures for 720p modes were traced to capture budget, not media failure: coded events started around 45s into a 52s capture.
- [x] Longer HEVC calibration budget proof: `CAPTURE_SECONDS=90`, `PROBE_TIMEOUT_SECONDS=90`.
- [x] `1280x720@20` proof run ready in `/tmp/lesavka-server-rc-mode-matrix-20260507-050819`: video `143741us`, audio `0us`, p95 `9.2ms`, freshness `257.8ms`, smoothness clean.
- [x] `1280x720@30` repeated evidence in `/tmp/lesavka-server-rc-mode-matrix-20260507-051510`: candidates around `129603us`, `135090us`, and `142615us`, all preferred with 15/16 coded pairs.
- [x] `1280x720@20` and `1280x720@30` completed a post-recovery 3-run HEVC static matrix in `/tmp/lesavka-hevc-continuation-20260509-004310/server-rct-hevc-720p-static/lesavka-server-rc-mode-matrix-20260509-005114`.
- [x] `1280x720@20` selected video `173852us`, audio `0us`; p95 max `14.1ms`, median abs max `11.2ms`, freshness budget max `309.0ms`.
- [x] `1280x720@30` selected video `145695us`, audio `0us`; p95 max `27.8ms`, median abs max `18.5ms`, freshness budget max `309.4ms`.
- [ ] Re-run `1920x1080@20` only after a fresh explicit go/no-go decision; this mode is quarantined because the last attempt preceded a Theia outage.
- [ ] Run final all-safe-mode HEVC sanity matrix with `LESAVKA_SERVER_RC_TUNE_DELAYS=0`; avoid `1920x1080@20` until the quarantine is lifted.

### Local artifact consolidation while Theia is offline

These notes are from local artifact review on 2026-05-07. They are useful for choosing the next post-reboot run, but only completed matrix summaries should be treated as final static calibration.

| Artifact | Mode | Result |
| --- | --- | --- |
| `/tmp/lesavka-server-rc-mode-matrix-20260507-033941` | `1920x1080@30` | Completed 3/3 static run, ready at video `127952us`, audio `0us`; p95 max `5.3ms`, median abs max `4.1ms`, freshness budget max `252.3ms`. |
| `/tmp/lesavka-server-rc-mode-matrix-20260507-050819` | `1280x720@20` | Single-run proof, ready only because `min_runs=1`; video `143741us`, audio `0us`; p95 `9.2ms`, median abs `6.4ms`, freshness `257.8ms`. |
| `/tmp/lesavka-server-rc-mode-matrix-20260507-051510` | `1280x720@20` | Interrupted before matrix summary. Per-probe reports show preferred confirmations at `190716us`, `160769us`, and `153680us`; the first confirmation still had median `-31.0ms`, so rerun this mode before locking it. |
| `/tmp/lesavka-server-rc-mode-matrix-20260507-051510` | `1280x720@30` | Interrupted before matrix summary. Per-probe reports show preferred confirmations at `129603us`, `135090us`, and `142615us`, all with 15/16 paired signatures and p95 between `3.0ms` and `11.4ms`; `135090us` remains a sensible candidate pending a completed static summary. |

Post-reboot priority order:

1. Deploy the local `lesavka-core.sh` udev timeout hardening.
2. Treat the completed 2026-05-09 720p static matrix as the source of truth for 720p HEVC values: `1280x720@20=173852`, `1280x720@30=145695`.
3. Keep `1920x1080@30=127952` from the completed 3-run static matrix.
4. Only after an explicit go/no-go, re-run `1920x1080@20` HEVC with explicit mode selection and tighter watchdogs.
5. Run final safe-mode HEVC sanity with tuning disabled for validated modes; avoid `1920x1080@20` until the quarantine is lifted.

## Code work

- [x] Add server HEVC decode path to MJPEG UVC output.
- [x] Add client HEVC capture/encode selection.
- [x] Add synthetic HEVC probe frame encoding.
- [x] Add `mjpeg-cfr` RCT capture mode to avoid MJPEG timestamp compression artifacts.
- [x] Make `LESAVKA_CORE_ONESHOT=1` request a descriptor rebuild in `lesavka-core.sh`.
- [x] Harden `lesavka-core.sh` so slow udev reload/trigger commands do not abort gadget rebuild.
- [x] Add HEVC profile defaults to `run_server_to_rc_mode_matrix.sh`: longer capture/probe timeout and separate delay map.
- [x] Stamp `LESAVKA_CALIBRATION_PROFILE`, `LESAVKA_UPLINK_CAMERA_CODEC`, and profile-specific delay maps during matrix runtime reconfigure.
- [x] Add profile-specific factory calibration maps in server calibration without changing MJPEG defaults.
- [x] Add installer env support for separate MJPEG and HEVC delay maps.
- [x] Add tests for profile selection, install defaults, and matrix HEVC defaults.
- [x] Bump local package versions to `0.21.1` for the initial HEVC profile/defaults work.
- [x] Bump local package versions to `0.21.3` for the 720p HEVC static calibration defaults.
- [x] Bump local package versions to `0.21.4` for HEVC decoded-MJPEG spool pacing.
- [x] Bump local package versions to `0.21.5` for synthetic HEVC probe GOP parity with live camera uplink.
- [x] Bump local package versions to `0.21.6` for encoded probe packets using encoder output PTS.
- [x] Bump local package versions to `0.21.7` for optional UVC spool metadata fetches and stricter local HEVC bundle identity proof.
- [x] Verify local HEVC/profile contracts:
  `cargo test -q -p lesavka_server calibration::tests`,
  `cargo test -q --test client_server_rc_matrix_script_contract --test server_install_script_contract`,
  `cargo test -q -p lesavka_server hevc_probe_frame_encoder_builds_when_x265_is_available`,
  and `cargo test -q --test server_upstream_media_v2_handoff_contract --test client_rct_transport_probe_contract`.
- [x] Verify broad local baseline after the HEVC/profile work:
  `cargo test --workspace --all-targets`.

## Client-to-server-to-RCT transport

- [x] Confirm at code/contract level that client synthetic media uses the same bundled RPC shape as real capture handoff.
- [x] Confirm at code/contract level that the client sends audio and negotiated HEVC video as bundled media units.
- [x] Confirm at code/contract level that the server receives each bundle and queues audio/video into the post-transport UAC/UVC handoff path.
- [x] Add unattended start-delay support to the client-to-RCT transport probe.
- [x] Add local HEVC bundle audit plus freshness-biased jitter stress so outgoing synthetic media proves 16/16 coded events and event codes 1..16 before hardware is involved.
- [x] Add client-to-RCT summary layer attribution for client-local bundle age versus post-send-to-RCT freshness.
- [x] Add optional UVC spool-boundary metadata fetch/summarization so failed blind runs can distinguish server decode/spool loss from final RCT capture loss.
- [ ] Run blind client-to-RCT HEVC transport probe.
- [ ] Evaluate coded-pair completeness, sync p95/median, freshness budget, smoothness, and transport lag.
- [ ] Add deeper ingress/queue/decode instrumentation only if the blind final RCT result fails.

## Deferred downstream/input latency follow-up

Bring this section back up after upstream media is fully optimized and the blind
HEVC client-to-server-to-RCT route is consistently healthy. The goal is to
minimize the loop from local input to visible downstream evidence:

`local input -> server HID write -> RCT response -> capture-card H.264 -> client display`

Current downstream facts:

- Real downstream eye video is H.264 byte-stream pass-through on the server:
  capture-card `v4l2src` emits `video/x-h264`, the server parses it, and the
  client decodes it.
- The normal downstream path does not decode/re-encode on the server.
- Testsrc-only downstream still uses `x264enc` so the hardware-free contract can
  prove H.264 packet shape, Annex-B framing, IDR recovery, and timing.
- HID/input has deterministic freshness/routing/recovery contracts, but no
  measured end-to-end HID latency probe yet.

Follow-up optimization plan:

1. Add a T0-T5 downstream/input latency probe:
   `T0` local synthetic input generated, `T1` server RPC receive, `T2` server HID
   write, `T3` visible RCT response, `T4` downstream capture-card frame observed
   by the server, `T5` client display handoff.
2. Reuse existing probe patterns instead of inventing new infrastructure:
   client timelines from `lesavka-sync-probe`, server timing sidecars from UVC
   metadata work, final capture analysis from sync/freshness tooling, and local
   performance/input gates for deterministic checks.
3. Tune downstream buffering after measurement: eye queue depth, appsink depth,
   client appsrc queue depth, leaky/drop policy, and first-frame/stall watchdogs.
4. Check capture-card H.264 controls for low-latency settings: GOP/keyframe
   cadence, bitrate, buffering, and whether the card exposes any hardware
   latency knobs through V4L2 controls.
5. Prefer the fastest reliable client H.264 decoder available on the local host;
   keep `sync=false` display sinks and verify queue depths are freshness-biased.
6. Add a focused HID latency measurement, not just reliability tests, so mouse
   and keyboard can be optimized by observed numbers instead of feel.
7. Only consider downstream HEVC or alternate transport after the H.264
   pass-through path is measured; H.264 pass-through is already cheap on Theia,
   so the likely wins are buffering, decoder choice, and measurement-guided
   recovery.

### Optional UVC spool-boundary metadata

The client-to-RCT probe remains non-mutating by default. If a server has already
been configured to append UVC spool metadata, the probe can fetch that JSONL and
write a local summary beside the final RCT capture artifacts:

```bash
env LESAVKA_CLIENT_RCT_UVC_FRAME_META_LOG_REMOTE=/tmp/lesavka-uvc-frame-meta.jsonl \
    ./scripts/manual/run_client_to_rct_transport_probe.sh
```

This does not enable server metadata by itself. It only copies and summarizes a
pre-existing server artifact. The useful comparison is:

- `client-transport-timeline.json`: what the client generated and bundled.
- `uvc-frame-meta-summary.txt`: what reached the server's MJPEG UVC spool.
- `report.txt` and `client-rct-transport-summary.txt`: what the RCT finally
  observed.

If the spool summary has 16/16 synthetic events and the RCT report does not, the
loss is after server decode/spool. If both are incomplete, the next debugging
target is client encoding, bundled transport, or server ingest/decode.

## Remote safety posture

- The 2026-05-08 moonshot run is recorded in
  `/tmp/lesavka-hevc-moonshot-latest/report.log`.
- Local validation is green after the all-mode bundle audit hardening:
  `hygiene_gate.sh`, `quality_gate.sh`, and a release build all passed.
- No reboot or destructive recovery should be attempted by automation.
- The last hardware run survived the 720p HEVC calibration repeats, then failed
  during `1920x1080@20` signal conditioning with zero paired events before the
  host became unreachable.
- Treat `1920x1080@20` HEVC as quarantined until Theia is back and a low-risk
  service-only status pass completes. Do not resume that mode as the first
  remote action.
- Next remote step once Theia recovers: run status-only checks, deploy the
  latest binaries if needed, prove a known-safe mode such as `1280x720@30`, and
  only then decide whether to reattempt `1920x1080@20` with tighter watchdogs.

### 2026-05-08 partial HEVC calibration evidence

These are not final static values, but they are useful breadcrumbs from the
interrupted `/tmp/lesavka-hevc-moonshot-*` matrix:

| Mode | Evidence | Current interpretation |
| --- | --- | --- |
| `1280x720@30` | Three usable tuned confirmations: `150731us`, `140349us`, and `135090us`; p95 stayed in the preferred band with 15 paired coded events per run. | Existing `135090us` remains acceptable; completed evidence centers closer to `136171-140349us`, so do not retune blindly without a final all-mode sanity run. |
| `1280x720@20` | Two strict-eligible tuned confirmations around `184870us` and `180995us`; the third run (`159923us`) had median/p95 too high for static selection. | Needs one more stable completed matrix before baking; likely higher than the older `153680us` seed, but not locked. |
| `1920x1080@20` | Signal conditioning timed out and produced `0` paired events; host became unreachable afterward. | Blocked/risky. Re-enter with status-only checks and a low-risk mode before attempting this again. |

### 2026-05-09 post-recovery 720p HEVC static decision

| Mode | Selected video delay | Evidence | Interpretation |
| --- | ---: | --- | --- |
| `1280x720@20` | `173852us` | 3/3 static-ready runs, p95 max `14.1ms`, median abs max `11.2ms`, freshness budget max `309.0ms`; follow-up no-tune sanity still passed sync/freshness/smoothness but had one median sample at `21.8ms`. | Bake this as the 720p20 HEVC default, but keep an eye on median spread in later end-to-end runs. |
| `1280x720@30` | `145695us` | 3/3 static-ready runs, p95 max `27.8ms`, median abs max `18.5ms`, freshness budget max `309.4ms`; follow-up no-tune sanity passed with p95 `13.7ms`. | Bake this as the 720p30 HEVC default. |

## Resume commands

Run these from `/home/brad/Development/lesavka` after `ssh theia 'date -Is'` succeeds:

```bash
./scripts/manual/run_local_hevc_bundle_audit.sh
./scripts/manual/run_local_hevc_encoder_preflight.sh
```

The local audit writes a passwordless preflight manifest proving that the client
synthetic source is producing one HEVC+PCM bundle train with 16/16 coded video
events, event codes 1..16, and nearby audio before any server/RCT hardware is
involved. It also runs a deterministic jitter stress case that drops stale
events as complete A/V bundles while preserving the analyzer's 13-pair evidence
floor.

The encoder preflight is also local-only. It runs the supported
`1280x720@20`, `1280x720@30`, `1920x1080@20`, and `1920x1080@30` modes through
the available GStreamer HEVC encoder and records whether each mode can produce
Annex-B HEVC faster than realtime before remote transport is involved.

Use the re-entry helper for status-only checks first:

```bash
./scripts/manual/run_hevc_remote_reentry_check.sh
```

Or run the post-reboot sequence helper when we are ready for the full unattended
runway. It performs the local HEVC preflights, waits for Theia, syncs/builds/
deploys/reconfigures through passwordless `lesavka-dev-install`, and starts the
pending HEVC static calibration matrix:

```bash
./scripts/manual/run_hevc_post_reboot_sequence.sh
```

Then use the same helper for the full no-password loop after the status check is
green:

```bash
env LESAVKA_HEVC_REENTRY_SYNC=1 \
    LESAVKA_HEVC_REENTRY_BUILD=1 \
    LESAVKA_HEVC_REENTRY_DEPLOY=1 \
    LESAVKA_HEVC_REENTRY_RECONFIGURE=1 \
    LESAVKA_HEVC_REENTRY_WAIT_SECONDS=900 \
    LESAVKA_HEVC_REENTRY_MODE='1280x720@30' \
    ./scripts/manual/run_hevc_remote_reentry_check.sh
```

Equivalent manual commands are:

```bash
rsync -az --exclude target --exclude .git ./ theia:/home/theia/Development/lesavka-codex/
ssh theia 'cd /home/theia/Development/lesavka-codex && cargo build --release --bin lesavka-server --bin lesavka-uvc && sudo -n /usr/local/sbin/lesavka-dev-install deploy'
ssh theia 'sudo -n /usr/local/sbin/lesavka-dev-install reconfigure 1280x720@30 hevc'
```

Then resume the hardware matrix:

```bash
env REMOTE_PULSE_CAPTURE_TOOL=gst \
    REMOTE_PULSE_VIDEO_MODE=mjpeg-cfr \
    LESAVKA_SERVER_RC_PROFILE=hevc \
    LESAVKA_SERVER_RC_MODES='1920x1080@20' \
    LESAVKA_SERVER_RC_REPEAT_COUNT=3 \
    LESAVKA_SERVER_RC_STATIC_MIN_RUNS=3 \
    LESAVKA_SERVER_RC_VERBOSE_PROBES=0 \
    LESAVKA_SERVER_RC_RECONFIGURE=1 \
    LESAVKA_SERVER_RC_RECONFIGURE_COMMAND='ssh theia sudo -n /usr/local/sbin/lesavka-dev-install reconfigure "$LESAVKA_MODE" hevc' \
    CAPTURE_SECONDS=90 \
    PROBE_TIMEOUT_SECONDS=160 \
    PROBE_DURATION_SECONDS=20 \
    PROBE_WARMUP_SECONDS=4 \
    ./scripts/manual/run_server_to_rc_mode_matrix.sh
```
