Files
linearvoid/.github/MEMORY.md
T

10 KiB

MEMORY

2026-08-07

  • Completed runtime validation section from TODO.
  • Runtime video normalization tests executed in running linearvoid-playout container using ffmpeg/ffprobe.
  • Verified normalized outputs for MOV, MKV, VFR, and 5.1 inputs: h264, yuv420p, 30/1, aac, 48000, 2 channels.
  • Concat continuity check passed with CONCAT_OK; output duration 25.344667 seconds.
  • Responsive viewport test on live viewer (390x844, 412x915) detected 8px horizontal overflow from 100vw usage in viewer container styles.
  • Fixed overflow in source by changing .lv-body and .viewer-shell width from 100vw to 100% in frontend/src/style.css.
  • Redis restart test:
    • Admin session endpoint returned 200 before and after Redis restart.
    • Presence key survived Redis restart in test-lab configuration.
    • Redis health returned to healthy post-restart.
  • Files changed:
    • .github/instructions/TODO.md
    • .github/instructions/DONE.md
    • frontend/src/style.css
    • CHANGELOG.md

2026-08-07 (continued)

  • Completed documentation half of recovery runbook TODO item.
  • Expanded docs/incident-runbook.md with quarterly DR drill: prerequisites, outage simulation, restore validation, pass/fail criteria, and evidence template.
  • Split TODO item into:
    • documented drill ([x])
    • manual rehearsal execution ([ ])
  • Updated CHANGELOG.md with incident runbook drill documentation entry.

2026-08-07 (continued 2)

  • Added manual operations checklist docs/operations/cloudflare-uptimerobot-checklist.md for Cloudflare + UptimeRobot task execution and evidence capture.
  • Linked checklist from SETUP.md Cloudflare section and TODO manual sections.
  • Did not mark manual dashboard items complete; checklist is preparation only.

2026-08-07 (continued 3)

  • Added docs/operations/scaling-performance-playbook.md covering manifest TTL tuning, TTFB baseline method, WebSocket/API benchmarking approach, cache ratio tracking, capacity triggers, and Phase 2/3 plans.
  • Updated TODO and BACKLOG to mark playbook creation done while keeping execution/measurement tasks pending.
  • Linked scaling playbook in README.md resources.

2026-08-09

  • Added WebSocket benchmark summary helper scripts/loadtest/summarize-artillery.ps1.
  • Updated scripts/loadtest/run-loadtests.ps1 to auto-generate ws-chat-summary.txt for ws and all scenarios.
  • Updated scripts/loadtest/summarize-k6.ps1 to produce pipeline-friendly output and integrated automatic admin-api-endpoint-summary.txt generation.
  • Expanded scripts/loadtest/README.md with PowerShell-first artifact capture and helper usage for both ws and admin scenarios.
  • Updated .gitignore to ignore loadtest artifacts (artifacts/ and scripts/loadtest/artifacts/).
  • Added artifact-to-worksheet field mapping section in docs/operations/scaling-performance-playbook.md so ws/admin worksheet entries map directly to generated summary files.
  • Updated docs/DEVELOPMENT.md and .github/instructions/TODO.md to mark ws/admin benchmark scaffolding complete while live benchmark execution remains pending.
  • Added CHANGELOG.md entry 1.0.10 summarizing loadtest helper automation and playbook mapping updates.

2026-08-09 (continued)

  • Completed Phase 1 (test fixtures): documented ffmpeg fixture-generation commands in playlist_test.go header comments (valid_720p30, invalid_h265, invalid_24fps).
  • Completed Phase 4 (R2 integration):
    • Enhanced SyncToR2 in playlist.go to set CacheControl + ContentType based on file extension:
      • .m4s, .ts, .mp4, .m4a -> public, max-age=31536000, immutable + video/MP2T
      • .m3u8 -> public, max-age=2 + application/vnd.apple.mpegurl
      • unknown extension -> no cache headers
    • Added three tests: TestSyncToR2 (segment upload with cache verification), TestSyncToR2_ManifestCacheHeaders (manifest upload), TestSyncToR2_NoCacheHeadersForUnknownExt (unknown extension).
    • All 17 playout tests pass (16 pass, 1 pre-existing skip).
  • Updated TODO.md: Phase 1 marked complete, Phase 4 partially complete (edge cache hit/miss remains manual).
  • Updated DEVELOPMENT.md: Test Fixtures marked complete, R2 Integration Test marked partially complete.

2026-08-09 (continued 2)

  • Completed Phase 2 chat tests in frontend/src/main.test.ts:
    • Presence updates: join/leave system messages add and remove users from presence list, sorted rendering.
    • Private DM flow: togglePrivateDM creates correct dm: room name from sorted usernames.
    • Message rendering: system messages, self messages (message-self), and other-user messages (message-other) all render correctly.
    • Total frontend tests: 27 passing (2 test files).
  • Marked Phase 4 "Document stubs/mocks" done (putObject injection pattern).
  • Updated TODO.md: Phase 2 chat tests checked, Phase 4 stubs checked.
  • Updated DEVELOPMENT.md: User Frontend Tests marked partially complete, R2 stubs checked.
  • Updated CHANGELOG.md with Phase 2 presence/DM/message tests.

2026-08-09 (continued 3)

  • Completed Phase 3 admin frontend tests in frontend/src/admin.test.ts:
    • Exported savePlaylist and renderPlaylistSortable from admin.ts.
    • Added playlist save test (verifies PUT /api/admin/playlist with JSON body).
    • Added playlist save error handling test (verifies failure status).
    • Added sortable rendering test (verifies index, paths, remove buttons, comment/blank line skip).
    • Total frontend tests: 31 passing (2 test files).
  • Updated TODO.md: Phase 3 playlist/dashboard/API integration all checked.
  • Updated DEVELOPMENT.md: Admin Frontend Tests marked partially complete.

2026-08-10 (continued 2)

  • Implemented STREAMING.md production-readiness gaps from plan .hermes/plans/2026-08-10_164500-production-readiness.md:
    • Task 1-2: Added runID (ISO timestamp format) and monotonic segSequence for globally unique segment naming (r-{ISOTIME}/seg-{seq}.m4s). Replaced strftime pattern with run ID-based path.
    • Task 2: Added watchAndPublishSegments using fsnotify for real-time per-segment R2 upload (~7s delay). Previously syncLatestToR2() only ran after FFmpeg exit.
    • Task 3: Added publishManifest with atomic CopyObject (temp key → final key) to prevent manifest referencing unconfirmed segments.
    • Task 4: Updated manifestCacheControl from "public, max-age=2" to "public, max-age=1, s-maxage=2, must-revalidate" per STREAMING.md.
    • Task 5: Added hls.on(Hls.Events.ERROR) handler in main.ts with bounded retries (5x), exponential backoff (2s→32s), reconnecting overlay (spinner + text). Added showReconnecting/hideReconnecting functions.
    • Task 6: Enriched HealthHandler with run_id, active_item, playlist_revision, last_segment_seq, last_r2_pub, consecutive_failures. Added "unhealthy" status when R2 publish is stale (>12s).
  • Files changed: backend/playout/src/playlist.go, playlist_test.go, go.mod, frontend/src/main.ts, main.test.ts, style.css, index.html.
  • Updated .github/instructions/TODO.md, BACKLOG.md, MEMORY.md, DONE.md.
  • Remaining: CORS on media.linearvoid.tv (Cloudflare R2 config, infrastructure).

2026-08-10 (continued 3)

  • Completed Phase 2 (viewer) + Phase 3 (admin) responsive/accessibility tests:
    • 5 viewer accessibility tests: video controls/attributes, chat panel aria-labels, chat toggle aria-expanded, message input label, reconnecting overlay aria-live/role.
    • 3 viewer responsive tests: chat-collapsed toggle, CSS grid layout detection, now-playing aria-live.
    • 3 admin accessibility tests: nav aria-label, active tab aria-current, nav button focusability.
    • 2 admin responsive tests: tab content visibility, essential tab presence.
    • Total: 45 frontend tests passing (2 test files).
  • Added coverage reporting: vitest.config.ts with v8 provider, thresholds at 20/15/15/20 (statements/branches/functions/lines).
  • Added test:coverage script to package.json.
  • Fixed CI: bumped Node from 20 to 22 in ci.yml and pages-deploy.yml (jsdom@30 requires Node 22+). Added engines to package.json.
  • Updated AGENTS.md: added Required tracking files table with 13 docs and update cadence.
  • All Go vet, Go tests, frontend test:coverage passing.
  • CORS on media.linearvoid.tv remains the only streaming pipeline gap (Cloudflare R2 config, not code).

2026-08-10 (continued 4)

  • Verified all test suites pass after streaming pipeline implementation:
    • Playout: go mod tidy (added fsnotify v1.8.0) → all tests pass
    • Chat: 7 packages pass (go vet + go test)
    • Frontend: 45 tests pass (2 files), test:coverage meets thresholds (22.92% / 18.44% / 19.01% / 25.42%)
  • Edge cache validation script scripts/validate-edge-cache.sh exists.
  • Remaining: CORS on media.linearvoid.tv (Cloudflare R2 bucket CORS config, not a code change). Phases 5-7 are manual/infrastructure only (Cloudflare dashboard, Hetzner provisioning, live benchmarks).

2026-08-11

  • Consolidated all development tasks from DEVELOPMENT.md and .github/instructions/TODO.md into .github/instructions/BACKLOG.md as the single source of truth. DEVELOPMENT.md now obsolete and removed. TODO.md references BACKLOG.md and DONE.md.
  • Fixed R2 endpoint validation in playout service (backend/playout/src/playlist.go):
    • Added isR2Configured() checking all four required env vars (R2_ENDPOINT, R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY, R2_BUCKET_NAME).
    • initR2Client() now returns a clear error if R2 is not configured instead of creating an S3 client with an empty endpoint.
    • Segment watcher (watchAndPublishSegments), syncLatestToR2(), and publishManifest() are now guarded by r2Client != nil — no error spam when R2 is unavailable.
    • Playout gracefully degrades: local HLS via nginx works without R2.
  • Updated .gitea/workflows/cd.yml "Prepare environment" step to include all R2* variables sourced from Gitea secrets (R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY, R2_BUCKET_NAME, R2_ENDPOINT, R2_ADMIN*\*), Cloudflare variables (CLOUDFLARE_API_TOKEN, CLOUDFLARE_ACCOUNT_ID), and frontend public URL variables.
  • Updated docs/DEPLOYMENT.md "Environment File" section: replaced vague "Cloudflare/R2 variables" bullet with explicit variable lists and added a new "Gitea Secrets" table documenting all 15 required secrets.
  • All playout tests pass (20 tests), go vet clean.