Skip to content

feat(doctor): warn when an HTTP deployment silently disables H.264 - #491

Merged
7174Andy merged 1 commit into
mainfrom
andrew/doctor-http-streaming-warning
Sep 1, 2026
Merged

7174Andy merged 1 commit into
mainfrom
andrew/doctor-http-streaming-warning

Conversation

@7174Andy

@7174Andy 7174Andy commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

Summary

lablink doctor now warns when the deployment will serve the viewer over plain HTTP,
because that silently disables H.264 video streaming.

Viewer streaming  WARN  ssl.provider is 'none', so the viewer is served over HTTP and
                        H.264 streaming cannot engage — sessions fall back to JPEG/WebP.
                        Configure an SSL provider, or to test as-is port-forward the
                        allocator (ssh -L 8443:localhost:5000 ...) and open
                        http://localhost:8443, since localhost counts as a secure origin

Chrome exposes the WebCodecs VideoDecoder only on secure origins, so on http:// the
viewer's codec probe reports WebCodecs API not available and negotiation falls back to
JPEG/WebP stills — re-encoding damaged regions from scratch every frame instead of
encoding inter-frame change. The server side is fine: -videoCodec auto makes KasmVNC
advertise H.264 and the encoder works. The browser declines it.

Why a check rather than more docs

It is documented — docs/configuration.md:313 and docs/architecture.md:254, under SSL
and streaming. But nothing in the deploy path says it, so the H.264 work in #477/#478 does
nothing for any domain-less deployment and there was no way to find that out short of
reading the browser console. What reaches an operator is "the desktop feels laggy", which
is a long way from "ssl.provider is none".

Found while diagnosing a real IP-only deployment where exactly this was happening.

Behaviour

ssl.provider Result
none, or unset warn — names the fallback and the port-forward that makes H.264 testable without a domain
letsencrypt, cloudflare, acm pass — viewer served over HTTPS
no valid config warn (skipped), matching the other checks

warn, not fail. HTTP is a supported deployment, just a slower one; failing preflight
over a performance cliff would block a legitimate config. One of the tests asserts that
explicitly, so a later edit can't quietly promote it to a failure.

Testing

packages/cli: 829 passed, 1 deselected
ruff check packages/cli: All checks passed!

Six new cases: HTTP warns and names the workaround, the three HTTPS providers pass, a
missing ssl section is treated as HTTP, and the warn-not-fail contract is pinned.

Related

ssl.provider 'none' serves the viewer over http://, and Chrome exposes the
WebCodecs VideoDecoder only on secure origins — so the codec probe reports
'WebCodecs API not available' and every session falls back to JPEG/WebP stills,
re-encoding damaged regions from scratch each frame instead of encoding
inter-frame change. The server-side encoder is fine; it never gets asked for
video mode.

Nothing surfaced this. The deploy is green, sessions work, and the operator's
experience is 'the desktop feels laggy' — a long way from 'ssl.provider is none'.
It was documented in configuration.md and architecture.md, in the SSL and
streaming sections, which is not where someone choosing 'no domain' is reading.
The H.264 work in #477/#478 therefore does nothing at all for any domain-less
deployment, and there was no way to find that out short of reading the browser
console.

warn rather than fail: HTTP is a supported deployment, just a slower one. The
message also names the port-forward that makes H.264 testable without a domain,
since localhost counts as a secure origin.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@7174Andy
7174Andy merged commit 903ce6c into main Sep 1, 2026
6 checks passed
@7174Andy
7174Andy deleted the andrew/doctor-http-streaming-warning branch September 1, 2026 21:21
7174Andy added a commit that referenced this pull request Sep 8, 2026
Release prep. publish-pip.yml's version guardrail rejects a tag whose
version does not match pyproject.toml, so the bumps land on main before
the release tags are cut.

Allocator and client stay in lockstep at 0.4.0 as they have since 0.1.0;
the CLI is versioned independently and goes to 0.3.0.

The CLI's allocator pin is raised to >=0.4.0 this time: the CLI
re-exports MachineConfig, whose ami_id default became empty (= resolve
the per-region Deep Learning Base AMI, #489) in allocator 0.4.0. An
older allocator would silently reintroduce the stale hardcoded
us-west-2 AMI default that doctor's #490 fallback logic assumes gone.

CHANGELOG (CLI): new 0.3.0 section (#484, #485, #490, #491, #498), and
a backfilled 0.2.0 section — #481 tagged 0.2.0 without adding one
(#467, #472, #474, #479).

Also: README Docker <version> example moved to 0.4.0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
7174Andy added a commit that referenced this pull request Sep 8, 2026
Release prep. publish-pip.yml's version guardrail rejects a tag whose
version does not match pyproject.toml, so the bumps land on main before
the release tags are cut.

Allocator and client stay in lockstep at 0.4.0 as they have since 0.1.0;
the CLI is versioned independently and goes to 0.3.0.

The CLI's allocator pin is raised to >=0.4.0 this time: the CLI
re-exports MachineConfig, whose ami_id default became empty (= resolve
the per-region Deep Learning Base AMI, #489) in allocator 0.4.0. An
older allocator would silently reintroduce the stale hardcoded
us-west-2 AMI default that doctor's #490 fallback logic assumes gone.

CHANGELOG (CLI): new 0.3.0 section (#484, #485, #490, #491, #498), and
a backfilled 0.2.0 section — #481 tagged 0.2.0 without adding one
(#467, #472, #474, #479).

Also: README Docker <version> example moved to 0.4.0.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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