67 lines
3.6 KiB
Markdown
67 lines
3.6 KiB
Markdown
# Lane C log — append-only, newest at bottom
|
|
|
|
Format per session:
|
|
|
|
## <date> session N
|
|
DONE: …
|
|
DECISIONS: …
|
|
BLOCKED/REQUESTS: …
|
|
NEXT: …
|
|
|
|
## 2026-07-18 session 1
|
|
DONE: M1 code-complete. Commit bb85eef.
|
|
- `requirements.txt` (fastapi, uvicorn only); `.gitignore` += `.venv/`.
|
|
- `scenegod/server.py` single file: statics (`/` no-store placeholder,
|
|
`/web/{path}` short-cache, path-guarded), `/assets/tree` (5s cache,
|
|
per-category grouping), `/assets/file` (traversal-guarded), `/scenes`
|
|
CRUD with atomic write + slugify + `validate_scene`, render endpoints
|
|
(begin/frame accept + save; end/status/out 501 until M3).
|
|
- `scripts/test_server.py`: 5 groups green (tree grouping, file stream,
|
|
4 traversal attempts rejected, scene round-trip w/ slugify, 5 validation
|
|
failures + 1 fade-overlap-allowed). `OK: 5 test groups passed`.
|
|
DECISIONS:
|
|
- System python3 is 3.14 (fastapi present but pydantic missing); made a
|
|
`.venv` on python3.11 per CLAUDE.md stack rule. Tests + server use
|
|
`.venv/bin/python`. `.venv/` gitignored.
|
|
- `web/` is under `scenegod/web/` per PLAN §2 (not repo root) — `WEB`
|
|
points there; Lane A/B statics resolve via `/web/{path}`.
|
|
- Asset grouping: per-category primary ext set (models for chars/anims/
|
|
props, images for backdrops, audio for audio). Non-primary image sharing
|
|
a stem → `thumb`, not a `format`. `path` prefers glb else first model.
|
|
Entries with no primary format dropped (thumb-only stems aren't assets).
|
|
- Clip-overlap check: violation if `next.start < a.end - a.fade`, where
|
|
`a.end = start + (out-in)*loop`. Fade-region overlap allowed.
|
|
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.
|