Skip to content

feature: branded highlight outro (orchestration)#315

Open
Flegma wants to merge 7 commits into
mainfrom
feature/branded-outro
Open

feature: branded highlight outro (orchestration)#315
Flegma wants to merge 7 commits into
mainfrom
feature/branded-outro

Conversation

@Flegma

@Flegma Flegma commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Part 2 of 2: api (merge AFTER the game-streamer PR). Renderer: the feature/branded-outro PR in 5stackgg/game-streamer. Full design, both PRs, and merge order: 5stackgg/5stack-panel#514.

What

The orchestration half of the branded highlight outro: the api decides the outro cache hit/miss per render and passes branding env to the game-streamer render pod. The renderer PR consumes that env.

Changes

  • src/matches/game-streamer/outro-branding.ts (new): pure helpers. computeOutroVersion = sha1(brandName|accent|logoEtag).slice(0,12), outroCacheKey = branding/outro_<version>_<dims>_<fps>.mp4, buildOutroEnv. outro-branding.spec.ts has 6 unit tests.

  • game-streamer.service.ts: injects S3Service; resolveOutroBranding(dims, fps):

    • active only when a custom logo (public.logo_url) is set;
    • accent = public.color_dark_tactical_amber, then public.color_tactical_amber, then default 33 94% 58%;
    • seeds the cache version from the logo's S3 ETag (so a same-path logo re-upload invalidates);
    • presigns a cache GET on hit, or a PUT plus branding props on miss;
    • returns {} (which means baked stock outro) when no logo is set or on any error, so it never breaks a render.

    Wired into the batch-highlights pod env (pod-level) and the dispatchClipRenderToPod payload.

  • src/matches/clips/clips.service.ts: passes outro_env in the on-demand dispatch payload.

No DB migration, no web change (reuses the existing branding settings).

Env contract (shared with the renderer PR)

Same six keys: CLIP_OUTRO_URL (hit), or CLIP_OUTRO_RENDER=1 + CLIP_OUTRO_PUT_URL + CLIP_BRAND_LOGO_URL + CLIP_BRAND_NAME + CLIP_BRAND_ACCENT (miss).

Merge order

Merge AFTER the game-streamer PR (which must ship :latest first). Safe either way thanks to the stock fallback, but the renderer must be updated before the api turns the feature on.

Verification

  • jest 6/6 on the pure helpers; changed files tsc --noEmit clean (pre-existing project tsc errors, e.g. sharp, are unrelated).
  • Whole-branch review on the most capable model verified the S3Service signatures, DI wiring, failure isolation, the exact env-name contract, and dims/fps consistency between the batch and on-demand paths. Ready to merge, no Critical/Important findings.

Non-blocking follow-ups

  • Parallelize the independent settings reads (Promise.all) on the cold path.
  • Add a resolver-orchestration unit test (no-logo returns {}, hit/miss env, stat-throws degrades). The pure helpers are tested; the orchestration was verified by review.

@Flegma

Flegma commented Jun 20, 2026

Copy link
Copy Markdown
Contributor Author

Code + security review (multi-agent), addressed

Independent code review (Sonnet) and security review (Opus).

Security review: Ship (no Critical/High)

The trust boundary holds: no path injection (dims is a hardcoded enum, fps validated, the cache version is a sha1 digest, so nothing attacker-controlled reaches the S3 key), no SSRF reflection (the api only ever presigns its own bucket's admin-set logo), no secret leakage in logs, and the presigned PUT is scoped to a single content-addressed key.

Code review, fixed

  • Moved resolveOutroBranding inside the dispatch try in clips.service.ts, so a hypothetical unexpected throw still marks the job error (consistent with the other failure paths).
  • Added S3_PUBLIC_ORIGIN to the demo-session pod env (startDemoPlayback) so the renderer can origin-allowlist the outro URLs against the real S3 presign origin, independent of the demo source. This keeps branded outros working for faceit/external demos (whose DEMO_URL origin differs).

Non-blocking follow-ups

  • Parallelize the independent settings reads (Promise.all) on the cold path.
  • Add a resolver-orchestration unit test (no-logo returns {}, hit/miss env, stat throws degrades). The pure helpers are unit-tested; the orchestration was verified by review.
  • Defense-in-depth: authenticate or NetworkPolicy the render-pod spec-server endpoint (tracked in game-streamer#29 and [FEATURE] Branding for Highlights Outro 5stack-panel#514).

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