- 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 <noreply@anthropic.com>
56 lines
3.7 KiB
Markdown
56 lines
3.7 KiB
Markdown
# Status — foundation2
|
|
|
|
## Round 1 — 2026-07-17 — STATUS: ready_to_merge
|
|
|
|
**Directives acknowledged:** Round 4 of plan/DIRECTIVES.md. Single-agent phase 5a — main
|
|
working directory on branch `foundation2` (per directive 3).
|
|
|
|
**Acceptance checklist** (plan/20-phase5.md "foundation2 scope"):
|
|
- [x] DB: `paths` table (contract #3) + helpers `add/get/get_one/delete_path`, plus
|
|
`patch_anchor` (label/color only) — `db.py`
|
|
- [x] API: `GET /api/beats` (serves `config.BEATS_JSON`, 404 when absent),
|
|
`POST /api/director` (degrades to a VALID empty camPath + `note` while lane E is
|
|
stubbed), `GET/POST/DELETE /api/paths*` (implemented — CRUD over the helpers was
|
|
cheaper than stubbing; POST validates the camPath shape → 422),
|
|
`PATCH /api/anchors/{id}` (contract #4) — `api.py`
|
|
- [x] Manifest gained `"capsule": false` — `test_api.py` exact-set lock updated in the same
|
|
commit (pitfall #3)
|
|
- [x] CLI: `features`, `direct`, `capsule` subcommands dispatch into stubs; house
|
|
degradation (exit 2, no traceback) — `cli.py`
|
|
- [x] Backend stubs raise NotImplementedError with the frozen contract in the docstring:
|
|
`audio_features.py`, `director.py`, `capsule.py`
|
|
- [x] Frontend stub modules created + imported from `main.js`, each wiring its own hidden
|
|
button in init(): `director.js`, `exportVideo.js`, `anchorPanel.js`, `photoMode.js`
|
|
(+ per-frame `fx.update()` call in the master loop), `fx.js`, `pathsStore.js`
|
|
- [x] index.html: ALL phase-5 buttons pre-wired hidden — #btn-director, #btn-path-save,
|
|
#path-load-select, #btn-path-del, #btn-export, #btn-photo, #btn-fx, #btn-anchors,
|
|
#anchor-panel container; `.write-ui` class + `body.capsule .write-ui{display:none}`
|
|
- [x] Hooks (contract #6): `transport.captureAudioStream()/releaseAudioStream()` (post-gain
|
|
tap, spatial included, tracks re-join across seeks), `scene3d.focusOn(x,y,z)`,
|
|
`scene3d.setHelpersVisible(bool)` (+ `registerHelper`; camPath gizmos registered)
|
|
- [x] `state.js`: `window.__F4D_API_BASE__` ?? `VITE_API_BASE` ?? localhost (contract #5);
|
|
`state.capsule` from the manifest toggles `body.capsule`
|
|
- [x] Suite ≥ 121 + new tests: **127 passed** (121 floor + 6 in `test_phase5_api.py`)
|
|
- [x] Ownership table updated (paths-route bodies → foundation2; noted in 20-phase5.md)
|
|
|
|
**Done this round — evidence:**
|
|
- `uv run pytest backend/tests` → **127 passed** (was 121).
|
|
- `npm run build` → clean (pre-existing chunk-size warning only).
|
|
- Live browser (Vite :5173 + uvicorn :8000, synthetic fixture): app boots (3 videos, sync
|
|
+0 ms); all 9 new controls present and `display:none`; `setHelpersVisible(false)` hides
|
|
grid (and restores); `focusOn(1,0.5,0)` retargets OrbitControls to exactly [1,0.5,0];
|
|
`captureAudioStream()` returns a MediaStream with 1 audio track, release clean;
|
|
`POST /api/director` → `{version:1, keyframes:[], note:…}` and round-trips
|
|
`camPath.fromJSON` (0 keyframes, no throw); paths save→load→fromJSON reproduces 2
|
|
keyframes, DELETE → 200 then 404; `PATCH /api/anchors/1 {color}` → updated dict;
|
|
`GET /api/beats` → 404; `body.capsule` hides #annot-panel/#btn-path-save/#btn-path-del.
|
|
|
|
**Blockers / questions for coordinator:** none. One conscious deviation, self-adjudicated
|
|
(coordinator == foundation2 agent this round): paths route bodies implemented here instead
|
|
of stub-marked for lane G — they were one-line calls into the db helpers I had to write
|
|
anyway; stubbing them would have been more code than implementing. Lane G scope shrinks to
|
|
capsule + pathsStore.js + deepening test_paths.py.
|
|
|
|
**Next:** merge to `main`, then lanes E, G, F in parallel (each in its own worktree —
|
|
directive 3 is mandatory for 5b).
|