Lane B: New... in the scene bar fetches the templates API and applies through
a new single apply path (applyScene = stage.applyState + load + preload, now
shared with Load), confirm-before-clobber via hasContent(), thumbs, toasts on
failure. ? overlay documents 24 real bindings read out of the code across
STAGE/TIMELINE/SCENE BAR, ignores ? while typing. Audio head-trim (left edge
eats into the source, one grouped undo). applyScene strips the template key so
saved scenes stay plain scene JSON.
Orchestrator SYNC-9 fix: help overlay dt column was auto-width + nowrap, so
long terms overflowed and the three columns overlapped visually.
Verified live: picker lists 3 (2 thumbs), no confirm when empty / confirms when
dirty, loads 7 entities + 2 cuts with bar refresh, no template key in toJSON,
overlay opens on ? and Escape closes, no hijack while typing. 5 suites green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
templates/ ships with the repo (two-hander-golden-hour, record-store,
empty-stage), GET /templates + /templates/{name} behind the same slug and
path-traversal guards as /scenes; presentation metadata rides in a template
key that validate_scene ignores and toJSON drops, so loading then saving
yields plain scene JSON.
Test group asserts the three list in order, round-trip, traversal/unknown
rejected, write verbs refused, and every template passes validate_scene with
every referenced asset present on disk - the check that stops a rotten
template shipping. 10 groups green.
Verified live: two-hander loads 7 entities, 8s, both performers animating,
cut fires cam1 to cam2 at 4.5s; other two load clean.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Lane A: bone-alias layer so CC_Base_*/Unreal-HumanIK/Rigify/Rokoko/Biped rigs
fold onto the canonical mixamo names — lady.glb pairs 52/102 bones and
retargets (53 tracks) where she previously threw 'missing hips'; mixamo→mixamo
pairing asserted bit-identical. Backdrops gain frustum auto-fit, floor tint
sampled from the plate, and FogExp2 in the plate's colour via a keyable
param. Also caught: _buildLight ran _refreshDefaults before registration, so
scene lights never dimmed the built-in hemi (every preset was washed out).
Orchestrator SYNC-7 fixes (found only by rendering actual frames):
- editor chrome (gizmo/grid/helpers/cam proxies) was baked into output mp4s
- timeline's per-tick rest transform dragged fitted plates out of frame
- fit used the viewport aspect, output renders at its own → letterboxed plates
- plate offset put its top edge on the lens axis → void above centre-frame;
now params.fitAnchor (default 0.75) picks the row that sits at eye level
Verified: 5 suites green; 1280x720 render shows a CC character dancing a mixamo
clip against an edge-to-edge Flow plate with a horizon and matched ground.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- PLAN §5 M5: shot sizes/angles/focals/light presets/blocking marks as
one-click deterministic presets (grammar.js data + presets.js solver,
Lane A), keyed at the playhead via scenegod:direct events (Lane B),
optional NL box -> POST /director -> tailnet Ollama with server-side op
validation (Lane C; m4pro serves qwen2.5:7b)
- rhubarb 1.14.0 built from John's source zip (JING5), installed arm64 at
~/.local/opt/rhubarb, symlinked /opt/homebrew/bin; happy path verified:
/rhubarb on a real spoken wav (assets/audio/test/vo.wav) returns mouthCues
- lane B unlocked to wire the lip-sync-from-audio button now
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- stage.js detectVisemes: NONMOUTH blocklist + side-stripped matching —
/(^|_)l($|_)/ was swallowing every ARKit left-side morph (eyeblink_l,
browdown_l), so setMorph('L') would blink the eye; self-check hardened to
assert group contents (L === tongue only, smile lands on E)
- CLAUDE.md: lanes stage own files explicitly, never git add -A (laneB's
attribution finding)
- README.md: run + feature summary; lane files: session 4 accepted for all,
v1 declared complete, optional backlog recorded
Verified: node + 9 server test groups green, /rhubarb 503 gate live,
audio lane (tone.wav block, gain) + cut markers + sun keys on screen,
zero console errors.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- stage.js: applyState no longer skips camera/light entities (source
'upload' but no bytes needed) — loaded scenes were silently losing the
directing rig; PLAN schema adds source.type 'none' for the clean fix
- lane files: A session-3 + C M4 accepted; A→absorb hotfix + viseme lane
(M4-A), B→audio rows + Web Audio sync + morphs track (M4-B), C complete
Verified: 6/6 entities restored on scene load, PiP 178x99 capped+visible,
lady 26/26 textured, audio-muxed render h264+aac 8.000s both streams,
graft_limb --selftest green under Blender 5.0.1, node+server suites green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- timeline.js: _mirror — Timeline subscribes stage.onChange, upserts/removes
live stage entities into scene.entities (closes the dock-added-entity gap
both lanes flagged; keyframing now works without a scene load)
- lane files: M2/M3 accepted for all lanes; A→PiP sizing + lady.glb material
polish, B→absorb _mirror + test + setDuration mutator, C→M4 (audio mux,
graft_limb, MB proxy)
SYNC 2: lady+man+street+2cams+sunset built via live dock path, all
frame-exact (probes in transcript). SYNC 3: finalRender → 240 frames
1920x1080 → ffmpeg h264 8.000s, cuts + sunset verified in extracted frames.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>