SCENEGOD/scenegod
type-two 6200f945b0 [laneB] M2 session 3: absorb _mirror + tests, setDuration, snap-step, param capture
- stagestub.js: removeEntity now fires onChange WITH the removed entity (real
  Stage contract) so _mirror's getEntity(id)===null removal path is testable.
- timeline.js: setDuration(x) — clamps the playhead, keeps out-of-range keys
  (lossless), notifies UI via onLoad. (Reviewed orchestrator's _mirror seam.)
- tlui.js: dur field → setDuration; snap-increment select (frame/0.1/0.25/1s);
  keyable-param add via dblclick on a params lane (captures current param
  values, skips 'type'/bool descriptors); params lane only when keys exist or
  kind is camera/light (no empty lane for characters).
- timeline_test.mjs: _mirror lifecycle (add→keyframe→remove) + setDuration.

Verified in browser (throwaway harness, not committed): dock-adds mirror into
rows, param capture, setDuration clamp+bar refresh, snap-step math.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 20:41:39 +10:00
..
web [laneB] M2 session 3: absorb _mirror + tests, setDuration, snap-step, param capture 2026-07-18 20:41:39 +10:00
server.py [laneC] M2/M3: render pipeline (ffmpeg encode + render.js), thumbnails endpoint, reaper 2026-07-18 20:00:14 +10:00