- Added run ID + unique segment naming (r-{ISOTIME}/seg-{seq}.m4s)
- Added fsnotify watcher for real-time R2 segment upload (~7s)
- Added atomic manifest publication (temp key → CopyObject)
- Fixed manifest Cache-Control: public, max-age=1, s-maxage=2, must-revalidate
- Added hls.js error recovery: bounded retries (5x), exponential backoff, reconnecting UI
- Enriched /health endpoint: run_id, active_item, last_segment_seq, last_r2_pub, consecutive_failures, unhealthy detection
- Updated tests: HealthHandler (new fields + unhealthy), player error recovery test
- Updated TODO.md, BACKLOG.md, DONE.md, MEMORY.md
3.7 KiB
3.7 KiB
BACKLOG
Cloudflare Configuration
- Configure DNS for linearvoid.tv apex and www redirect (manual)
- Configure media.linearvoid.tv for split-domain HLS delivery (manual)
- Create R2 bucket (manual)
- Configure Cache Rules: .ts/.m4s + .m3u8 (manual)
- Configure Cloudflare Pages deploy workflow (
.gitea/workflows/pages-deploy.yml) and setup docs (docs/operations/cloudflare-pages-setup.md,docs/operations/gitea-cloudflare.pages.md) - Create Cloudflare Pages project in dashboard and link custom domain (manual)
- Enable Tiered Cache, WAF, rate limiting (manual)
- Implement Worker for immutable cache headers on segment paths
- Enforce HTTPS/WSS, redirect HTTP → HTTPS (manual)
Monitoring & Observability
- Set up Prometheus with chat/playout/nginx/redis/postgres/node scrape targets
- Add nginx-exporter, redis-exporter, postgres-exporter, node-exporter
- Import Grafana app + operational dashboards
- Define Prometheus alerting rules (8 rules: ChatDown, PlayoutDown, RedisDown, etc.)
- Set up UptimeRobot external monitoring
Security
- Implement admin cookie-session auth (HttpOnly, SameSite=Strict, Secure when TLS)
- Implement server-side session expiration
- Enforce HTTPS/WSS at edge and origin
- Implement rate limiting for chat messages (Redis windowing)
- Implement WebSocket connection rate limiting (5/IP/60s)
- Implement admin login rate limiting (5/IP/5min)
Scaling & Performance
- Create scaling/performance playbook (methods, thresholds, execution order)
- Load-test scaffolding: ws-chat.yml, admin-api.js, run-loadtests.ps1, summarizers
- Cache-hit ratio exporter (scripts/cache-hit-ratio.js + .ps1)
- Saturation alerts: chat p95, Redis memory, cache-hit ratio
- Create Cloudflare Pages project and cut over frontend hosting (manual)
- Optimize segment immutability and manifest TTL for cache efficiency
- Measure playback TTFB from multiple US regions
- Execute WebSocket load tests with real infrastructure
- Execute admin API benchmarks with real infrastructure
- Track cache hit ratio and R2 ops in production
- Plan Phase 2 service separation
- Plan Phase 3 multi-origin resilience
Streaming Pipeline
Gaps from 2026-08-10 audit → 2026-08-10 implementation (STREAMING.md contract vs playlist.go implementation):
- Continuous R2 sync during playout (HIGH):
syncLatestToR2()now uses fsnotify watcher to upload segments in real-time (~7s delay). - Globally unique segment naming (HIGH): Implemented
r-{ISOTIME}/seg-{seq}.m4snaming via run ID + ffmpeg monotonic sequence. - Atomic manifest publication (MEDIUM): Upload manifest to
playlist.m3u8.tmp, thenCopyObjectto final key. - Manifest Cache-Control alignment (LOW): Updated to
public, max-age=1, s-maxage=2, must-revalidate. - CORS headers on HLS responses (MEDIUM): Needs Cloudflare R2 bucket CORS config (infrastructure, not code) — CORS already set in nginx for same-origin; media.linearvoid.tv needs Cloudflare setting.
- Player error recovery (MEDIUM): Added
hls.on(Hls.Events.ERROR)handler with bounded retries (5x), exponential backoff, reconnecting overlay. - Health endpoint detail (LOW): Added active item, run ID, playlist revision, last segment seq, last R2 pub, consecutive failures.
- Source media contract + validation (H.264/AAC, 30fps, keyframe check) — implemented
- fMP4 HLS packaging (6s segments, 24 window) — implemented
- Slate fallback + recovery (
shouldEscalateToSlate) — implemented - R2 cache headers (immutable segments, short-lived manifest) — implemented
- Cloudflare Worker immutable
.m4sheaders — implemented