From 51650c728e434c34ee4ff10e5039663554f55a34 Mon Sep 17 00:00:00 2001 From: type-two Date: Fri, 17 Jul 2026 17:31:08 +1000 Subject: [PATCH] foundation2 (phase 5a): contracts, stubs, hooks & UI wiring for lanes E/F/G - DB: paths table (contract #3) + helpers; patch_anchor (label/color) - API: GET /api/beats, POST /api/director (valid-empty degradation), /api/paths CRUD (validated POST -> 422), PATCH /api/anchors/{id}; manifest gains capsule:false (test_api.py key-set lock updated consciously) - CLI: features | direct | capsule subcommands -> lane stubs (exit-2 degradation) - Backend stubs with frozen contracts in docstrings: audio_features, director, capsule - Frontend: six lane stub modules imported from main.js; all phase-5 buttons pre-wired hidden in index.html; write-ui/body.capsule read-only mode; __F4D_API_BASE__ runtime override in state.js - Hooks (contract #6): transport.captureAudioStream/releaseAudioStream, scene3d.focusOn, scene3d.setHelpersVisible (+registerHelper; camPath gizmos) - Suite 121 -> 127 passed; npm build clean; live-browser verified (status file) Co-Authored-By: Claude Fable 5 --- backend/festival4d/api.py | 126 +++++++++++++++++++++++++++ backend/festival4d/audio_features.py | 25 ++++++ backend/festival4d/capsule.py | 28 ++++++ backend/festival4d/cli.py | 43 ++++++++- backend/festival4d/config.py | 2 + backend/festival4d/db.py | 64 ++++++++++++++ backend/festival4d/director.py | 25 ++++++ backend/tests/test_api.py | 3 +- backend/tests/test_phase5_api.py | 107 +++++++++++++++++++++++ frontend/index.html | 25 +++++- frontend/src/anchorPanel.js | 19 ++++ frontend/src/camPath.js | 1 + frontend/src/director.js | 16 ++++ frontend/src/exportVideo.js | 18 ++++ frontend/src/fx.js | 19 ++++ frontend/src/main.js | 27 +++++- frontend/src/pathsStore.js | 18 ++++ frontend/src/photoMode.js | 18 ++++ frontend/src/scene3d.js | 56 +++++++++++- frontend/src/state.js | 7 +- frontend/src/transport.js | 32 +++++++ plan/20-phase5.md | 2 +- plan/status/foundation2.md | 55 ++++++++++++ 23 files changed, 726 insertions(+), 10 deletions(-) create mode 100644 backend/festival4d/audio_features.py create mode 100644 backend/festival4d/capsule.py create mode 100644 backend/festival4d/director.py create mode 100644 backend/tests/test_phase5_api.py create mode 100644 frontend/src/anchorPanel.js create mode 100644 frontend/src/director.js create mode 100644 frontend/src/exportVideo.js create mode 100644 frontend/src/fx.js create mode 100644 frontend/src/pathsStore.js create mode 100644 frontend/src/photoMode.js create mode 100644 plan/status/foundation2.md diff --git a/backend/festival4d/api.py b/backend/festival4d/api.py index 8e90e79..06ed1ee 100644 --- a/backend/festival4d/api.py +++ b/backend/festival4d/api.py @@ -12,6 +12,17 @@ Serves the synthetic project fully so lane C can treat this API as finished: POST /api/events/detect {t_global_s?, window_s?} -> runs M7 detection POST /api/annotations {video_id, t_video_s, bbox:[x0,y0,x1,y1]} -> {anchor_id?, point?} +Phase 5 (foundation2; shapes frozen in plan/20-phase5.md contracts): + + GET /api/beats -> beats.json body (contract #1); 404 when not yet analyzed + POST /api/director {top_n?, lead_s?} -> camPath JSON (contract #2); while lane E + is stubbed, degrades to a VALID empty path + "note" + GET /api/paths -> [{id, name, created_at}] + GET /api/paths/{id} -> {id, name, created_at, json: } + POST /api/paths {name, json: } (validated -> 422) + DELETE /api/paths/{id} + PATCH /api/anchors/{id} {label?, color?} -> updated anchor dict + Source videos in ``data/raw`` are mounted at ``/media`` via Starlette ``StaticFiles``, which supports HTTP Range (required for ``