diff --git a/logs/laneC.md b/logs/laneC.md index a53c6ae..2dd5601 100644 --- a/logs/laneC.md +++ b/logs/laneC.md @@ -35,3 +35,32 @@ BLOCKED/REQUESTS: none. NEXT: M2 (when unlocked): scene-validation hardening + asset thumbnails endpoint. M3 render pipeline (ffmpeg encode + web/render.js) is designed in C-server.md §C5, endpoints already stubbed — implement at SYNC-2/M3. + +## 2026-07-18 session 2 +DONE: M2 thumbnails + M3 render pipeline (orchestrator green-lit both). Commit b627a0f. +- `/render/begin` (uuid dir + meta.json, 503 if no ffmpeg), `/frame/{n}` + (PNG->frames/{n:06d}.png, 400 on empty), `/end` (spawns bg ffmpeg thread: + libx264 crf18 yuv420p, 400 if no frames), `/status` (queued|encoding| + done|error+log tail; on-disk out.mp4 fallback after restart), `/out.mp4`. +- Boot-time `reap_renders()` deletes render dirs >48h. +- `/assets/thumb?path=` serves same-stem image sidecar (404 if none). +- `web/render.js`: draftRecord (MediaRecorder webm), finalRender + (timeline.step -> renderActiveCamera -> toBlob -> POST, <=4 in flight, + resize+restore renderer), download() helper. node --check clean. +- `test_server.py`: added render group (ffmpeg lavfi -> 30 PNGs -> begin -> + post -> end -> poll -> ffprobe duration ~1s) + thumbnail asserts. + `OK: 6 test groups passed`. +DECISIONS: +- Render state in-memory (single-process local tool); status() infers from + disk after a restart. ponytail-commented. +- Thumbnails pass-through, no resize — Pillow would be a new dep (stack rule + says log a REQUEST first); not worth it until dock load is measurably slow. +- finalRender total frames = round(duration*fps); relies on timeline.step + being deterministic (orchestrator verified). +BLOCKED/REQUESTS: +- finalRender's per-frame path depends on Lane A `stage.renderActiveCamera` + as a real render target (their M2). Server + ffmpeg path fully tested with + synthetic frames; the browser client path is unexercised until A lands it. +NEXT: M4 is locked. When unlocked: ffmpeg audio mux (scene audio[]), +/mb/submit MODELBEAST proxy, scripts/graft_limb.py. Meanwhile available to +integration-test finalRender once Lane A's renderActiveCamera lands.