flower
/
All briefs
idea draft review_synthesis vodmanager
epic · VOD Manager — post-review roadmap (ambassador launch...

Clip discovery / auto-clip — 3 P0 production issues + conductor integration plan (ships without conductor)

Dispatch

canonical · plan

Spec

markdown

hand-off · dispatch

Dispatch

Auto-dispatch

when it reaches planned

Design-loop

design pass before build

Direct dispatch — no refine required. The packet tells the agent to ask questions only if the request is blocked by ambiguity.

kind

No dispatch requests yet — dispatch above to generate a copy-paste packet.

provenance · append-only

Trace

live
or paste a screenshot uploading…
  1. refinement 10h ago

    PROGRESS (commit 7894c23, held main): the P0/P1/P2 production-hardening is DONE + independently re-verified (full suite 1963 pass / 1 pre-existing skip, Pint clean). Extracted HighlightClipCutter service + CutsHighlightClips job trait so the single-clip + new batch job share the hardened path. - P0-1: refinement extracts audio once per VOD via shared AudioCache (cache hit → never pulls the 40GB source); DiskSpaceProbe preflight on refinement pull + clip job; new GenerateStreamHighlightClipsJob pulls source ONCE, loops all un-clipped highlights ("Cut all clips" action + CLI). - P0-2: clip writes reserve through the same free-tier-count + QuotaService::tryToFit path as a normal archive; skip gracefully if they can't fit. tryToFit + evictIfAtCap gained a backward-compatible protected_vod_ids param; the cutter pins the source VOD so a clip can never evict the VOD it was cut from. (Reviewed by hand — correct + source path unaffected.) - P0-3: DetectStreamHighlightsJob caps refinements/run (vodmanager.highlights.max_refinements_per_run, default 5); is_clipable=false refuses a refined cut (cutter + all 3 createClip actions + UI "Not a clip"/"Create clip anyway"). - P1: deterministic twitch_vod_id=highlight-{id} + trashed-row reuse on retry; clamp to source duration + min-duration floor before ffmpeg + min-size floor after (empty cut never becomes a row). - P2: SendStreamArchivedNotificationListener early-returns for type=highlight; per-stream detection lock; vodmanager:generate-highlight-clip CLI. REMAINING (follow-ups, NOT done): the deferred "ideas" (9:16 social clips + burned captions, precise-cut re-encode mode, trim-handle editing UX, type=highlight provenance subtype); the conductor integration (blocked on external Phase 4); and the STRATEGIC local VOD source cache (VodSourceCache generalizing AudioCache: pull source once, reuse across transcribe/encode/refine/clip; warm-at-archive; free-space-driven sweep — design in discussion, pending operator decisions, will get its own brief). Also noted (pre-existing, now gated off by the referrals kill-switch): QualifyReferralOnVodArchived fires on a clip's VodArchivedEvent — already tracked as ambassador #150 item 2.9.

    agent · claude-code
  2. parent set 11h ago

    Grouped under epic #272.

    agent · claude-code
  3. note added 2d ago

    Deep review of the clip-discovery/highlights/auto-clip feature + the pending conductor dependency (map + conductor-repo exploration + Opus production review). == WHERE THINGS STAND == The auto-clip pipeline is FEATURE-COMPLETE and end-to-end automatic, entirely in-app, ZERO conductor dependency: stream ends → chat+events terminal → StreamAnalyticsTrigger dispatches DetectStreamHighlightsJob → HighlightScorer merges 3 signals (chat z-score ≥2.5, event weights raid=10/giftsubs=8/cheer=5/hypetrain=6/sub=2/redemption=1, transcript keyword density) into ranked top-N → optional LLM refinement (mock/gemini-flash, up to 3 iterations, history preserved) → GenerateHighlightClipJob (ffmpeg -ss -c copy stream-copy → type=highlight VOD row → VodArchivedEvent). Surfaces: /streams/{stream}/highlights, stream-show section, replay 4th tab + minimap. Real test coverage (20+ files). CONDUCTOR NOT WIRED (grep = zero references) and NOT NEEDED to ship. == P0 PRODUCTION ISSUES (fix before prod) == 1. Redundant full-VOD pulls → disk/bandwidth exhaustion. Refinement re-downloads the entire source PER highlight (DetectStreamHighlightsJob fans out 1 RefineHighlightWithLlmJob per highlight, up to 10) → a 40 GB VOD = up to 10×40 GB (~400 GB) before a clip is cut; each clip cut re-downloads again; AudioCache (already solves this for transcription, keyed {vod_id}-{file_size}) is NOT reused; no DiskSpaceProbe preflight; 6 concurrent on generalist-supervisor alongside uploads. FIX (biggest quick win): one "cut all clips for a stream" job that pulls source ONCE and loops highlights; reuse AudioCache for refinement audio; add DiskSpaceProbe. 2. Clip write bypasses quota/free-tier entirely. GenerateHighlightClipJob force-fills status=ARCHIVED with no QuotaService/FreeTierLimits (tryToFit only called from VodDownloader) → clip can push an account over byte quota silently; on free tier bypasses caps (clips bucket into VOD count → a burst evicts real VODs on next daily sweep). FIX: route through quota, reserve for clip size — BUT protect the source VOD from oldest-first purge during the reserve (don't purge the source you're cutting from). 3. Uncapped LLM cost fan-out; is_clipable computed but never enforced. Up to 10 highlights × 3 iterations ≈ 30 Gemini calls/run (inline base64 audio), auto-firing whenever highlight_refinement_backend is set, no per-run/per-account cap; re-run button makes runaway bills cheap. LLM returns is_clipable but resolveBounds uses refined bounds REGARDLESS. Failures swallowed into failed rows with no ops visibility. FIX: cap fan-out; enforce/surface is_clipable; confirm GOOGLE_API_KEY + billing before enabling gemini-flash; add ops alerting. == P1 == - Non-idempotent clip window: idempotency rests only on generated_clip_vod_id set at the END; twitch_vod_id randomized per attempt (no DB unique guard) → crash after upload but before back-ref save → tries=2 retry cuts a SECOND clip + orphans the first (slow S3 pull trips the 30-min job timeout). Fix: deterministic twitch_vod_id=highlight-{id} + DB unique constraint (or pre-work claim) + cleanup partial upload on retry. - No bound clamping to vod.duration_seconds → start past EOF → ffmpeg produces a ~0-byte "clip" that still becomes an archived VOD row. Add start<duration, end≤duration, min-duration/min-size guard before creating the row. == P2 == stream-copy can't honor sub-keyframe precision (undercuts LLM tighter bounds); re-running detection races in-flight jobs (add per-stream lock); spurious "stream archived" email on clip's VodArchivedEvent (early-return listener on TYPE_HIGHLIGHT); 3 near-identical createClip actions with no action-layer feature:highlights re-check (consolidate); type=highlight conflates auto-clips + native-Twitch highlights (add provenance subtype); weak transcript keyword signal; no CLI to cut a clip (detection has one). == CONDUCTOR == legitphp/conductor + conductor-client = a GENERIC central GPU/embedding work service built first for lounge (~90M-row Reddit), NOT a clip tool. Additive to vodmanager in 2 tiers: near-term = text embeddings over chat_messages.body (cleanest fit) and/or transcript segments → a NEW semantic discovery signal for highlight detection; larger/parked = self-hosted refinement LLM, GPU transcription/diarization, video-frame (EVA02) — need conductor to generalize beyond embeddings (open questions: cost allocation, media transport, GPU class, cold-start). HARD EXTERNAL BLOCKER (Phase 4, ~2–4 days, in the non-Laravel legit-embedding repo): the worker ignores reply_to and writes to a GLOBAL text_embedding_results stream; conductor-client ResultConsumer XACK+XDELs every entry before filtering by source → **vodmanager and lounge would mutually destroy each other's results.** No safe interim. Phase 4 = worker reply_to honoring + per-app stream config + per-app watch/janitor + per-app Redis ACL. STANCE: keep the in-app pipeline fully independent of conductor. App\Contracts\HighlightRefinementBackend already exists → a future ConductorRefinementBackend slots in as one resolveBackend() case, zero structural change. vodmanager steps once Phase 4 unblocks: composer require conductor-client + publish config/migrations; CONDUCTOR_* env (SEPARATE Redis from vodmanager's db 7/8 — conductor has its own); vector storage decision (conductor's polymorphic embeddings tables VS the homelab Redis 8.6.2 VectorSet at .206 db6 already earmarked for speaker clusters — reuse for a single hot-query path); add HasEmbeddings to ChatMessage + paced backfill (XLEN backpressure); conductor:consume-results as a Forge DAEMON (not a Horizon supervisor); add semanticCandidates() as a 4th HighlightScorer signal (purely additive). Bonus to surface to conductor roadmap: its open "how do large media payloads travel?" question is answerable from vodmanager's presigned-URL infra (replay proxy) — hand it a presigned URL instead of inline bytes. SEQUENCING (non-blocking): (1) now: fix the P0/P1s, ship in-app heuristic+Gemini; (2) external: land conductor Phase 4; (3) then onboard vodmanager as the Phase 4 POC for text embeddings (chat first); (4) add semanticCandidates(); (5) later/parked: ConductorRefinementBackend + GPU tasks. == IDEAS == Batch cutting (biggest quick win, doubles as the P0 disk fix); precise-cut re-encode mode for short clips (<60s cheap on VodEncoder) honoring frame-accurate LLM bounds, keep stream-copy as fast default (or smart-cut hybrid); VERTICAL 9:16 social clips w/ burned-in captions from ChatVttBuilder VTT (new VodEncoder "social-vertical" profile) + one-click social export; better signals (audio RMS/laughter via ffmpeg, chat-sentiment already light-computed, semantic clustering via conductor); trim-handle editing UX + multi-select bulk cut + surface is_clipable/confidence; vodmanager:generate-highlight-clip CLI. DO NOT REGRESS: test coverage, finally-based scratch cleanup, refinement history preservation, detector's clipped-highlight preservation.

    agent · claude-code
  4. participant joined 2d ago
    system · claude-code

epic · dependencies

Relationships

depends on

No dependencies — dispatchable once planned.

agents · waves

Participants

  • claude-code participant · active

trace · graph

Links

No links yet — they accrue as agents work the brief.

scope

Projects

  • vodmanager · primary

dogfood · read-only

Agent’s-eye view

The literal recall_brief payload an agent gets — same service path as the MCP tool.