diff --git a/docs/architecture/embedded-inline-playback.md b/docs/architecture/embedded-inline-playback.md index 523360795..3900dd612 100644 --- a/docs/architecture/embedded-inline-playback.md +++ b/docs/architecture/embedded-inline-playback.md @@ -353,7 +353,8 @@ neither retained nor rendered. Technical details show only the sanitized stage, failure, engine type/details, disposition, and HTTP status. The active playback URL remains available to the pre-existing retry, copy, and explicit external-player workflows; it is not copied from the HLS error payload into -the evidence or technical details. +the evidence or technical details. HLS startup development logs are event-only: +they do not include provider-supplied channel names or source URLs. `network-error` is reserved for provider/network loading failures. Engines that expose concrete browser security evidence, such as CORS, mixed content, Content Security Policy, or private-network-access blocks, use `browser-access-error` so the UI can explain that the browser player was blocked before playback reached decoding. diff --git a/docs/superpowers/specs/2026-07-30-structured-hls-diagnostics-design.md b/docs/superpowers/specs/2026-07-30-structured-hls-diagnostics-design.md index bea4b0c9d..d32ce1966 100644 --- a/docs/superpowers/specs/2026-07-30-structured-hls-diagnostics-design.md +++ b/docs/superpowers/specs/2026-07-30-structured-hls-diagnostics-design.md @@ -175,8 +175,10 @@ summary made only from the evidence fields, for example: `stage=manifest · failure=http · type=networkError · details=manifestLoadError · disposition=fatal · HTTP 404` No HLS error message, URL, header, body, response text, or arbitrary provider -payload appears. Existing title/description and HTTP metadata rendering remain -unchanged, so no new translation keys or layout changes are required. +payload appears. HLS startup development logs are event-only and omit +provider-supplied channel names and source URLs. Existing title/description and +HTTP metadata rendering remain unchanged, so no new translation keys or layout +changes are required. ## Testing diff --git a/libs/ui/playback/src/lib/html-video-player/html-video-player.component.shared-controls.sources.spec.ts b/libs/ui/playback/src/lib/html-video-player/html-video-player.component.shared-controls.sources.spec.ts index 1c82ec2b4..929772534 100644 --- a/libs/ui/playback/src/lib/html-video-player/html-video-player.component.shared-controls.sources.spec.ts +++ b/libs/ui/playback/src/lib/html-video-player/html-video-player.component.shared-controls.sources.spec.ts @@ -72,6 +72,27 @@ describe('HtmlVideoPlayerComponent shared controls sources', () => { expect(bindIndex).toBeLessThan(loadIndex); }); + it('does not write HLS provider data to development logs', () => { + const secret = 'hls-dev-log-secret'; + const debug = jest + .spyOn(console, 'debug') + .mockImplementation(() => undefined); + jest.replaceProperty(process.env, 'NODE_ENV', 'development'); + + renderSharedControls(HtmlVideoPlayerComponent, fixtures, { + channel: { + ...TEST_CHANNEL, + name: `Provider channel ${secret}`, + url: `https://user:${secret}@provider.example/live.m3u8?token=${secret}`, + epgParams: `&epg-token=${secret}`, + }, + }); + + const serializedLogs = JSON.stringify(debug.mock.calls); + expect(serializedLogs).not.toContain(secret); + expect(serializedLogs).not.toContain('provider.example'); + }); + it.each([false, true])( 'passes authoritative isLive=%s to raw MPEG-TS playback', (isLive) => { diff --git a/libs/ui/playback/src/lib/html-video-player/html-video-player.component.ts b/libs/ui/playback/src/lib/html-video-player/html-video-player.component.ts index 25f80a8ca..821667c02 100644 --- a/libs/ui/playback/src/lib/html-video-player/html-video-player.component.ts +++ b/libs/ui/playback/src/lib/html-video-player/html-video-player.component.ts @@ -257,7 +257,7 @@ export class HtmlVideoPlayerComponent implements OnInit, OnChanges, OnDestroy { Hls && Hls.isSupported() ) { - debugHtmlPlayer('Switching channel to:', channel.name, url); + debugHtmlPlayer('Starting HLS playback'); const hls = new Hls(); this.hls = hls; hls.on(Hls.Events.MANIFEST_PARSED, (_, data) => {