festifun/plan/status/integration.md
m3ultra e5d6b2c47f Integration (M8 + M9): annotation→3D, camera paths, README, v0.1.0
M8: POST /api/annotations resolves a bbox to a 3D point (ray → two-view
triangulation / nearest-point / centroid-depth) via lane B's geometry
primitives; correction panel + bbox-drawing UI; resolved anchors render live
in overlays and the 3D scene. CR-2 (additive): annotations.event_id +
PATCH /api/events/{id} + db.update_event.

M9: keyframed god's-eye camera paths (Catmull-Rom position + slerp
orientation, export/import), gizmos, path-mode camera hooks.

Verified: 101 backend tests pass (two-view corner recovery err 0.00000);
frontend build clean; live in-browser M8 triangulation (gap 0.21) + M9 path
(camera on keyframe at t) + M4 sync ~16ms. Cleanup: worktrees removed, debris
stash dropped, pristine demo DB.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 09:59:51 +10:00

67 lines
4.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Status — integration
## Round 1 — 2026-07-16 — STATUS: ready_to_merge
**Directives acknowledged:** round 1 of plan/DIRECTIVES.md (all lanes merged & verified;
integration begins; CR-1 approved; drop debris stash + remove laneA/B worktrees; real-browser
sync check; test floor 96).
**Scope done: M8 + M9 + README + cross-lane wiring + cleanup.**
### Change requests adjudicated (plan/CHANGE_REQUESTS.md)
- **CR-1 (lane D): APPLIED** — confirmed `POST /api/events/detect` returns `{result, events}`;
renamed test asserts it.
- **CR-2 (integration, filed + APPLIED):** M8 needs an annotation↔event link and event-type
correction, neither of which the frozen contract had. Added — strictly additive:
- `annotations.event_id` (nullable FK) + `AnnotationIn.event_id` — two-view grouping.
- `db.update_event` + `db.get_event` + `PATCH /api/events/{id}` — the correction dropdown.
Every pre-existing route/shape/column and the timebase + pose contracts are unchanged.
- A second foundation stub assertion (`test_annotation_stored`: `anchor_id is None`) was, like
CR-1, only valid pre-M8; renamed to `test_annotation_resolves_to_anchor` for the landed shape.
### M8 — correction + annotation → 3D
- New `backend/festival4d/resolve.py`: ray from bbox center (pose interpolated at t_video via
`geometry.slerp_pose`), then triangulate across two same-event views (reject near-parallel /
gap > 0.5), else nearest point-cloud point (0.3 cyl), else ray at centroid depth. Pure
orchestration over lane B's frozen primitives.
- `POST /api/annotations` now resolves + creates+links an anchor (label = event description).
- Frontend `annotate.js`: click a timeline marker → correction panel (type dropdown → PATCH,
source→user; live marker recolor); **Annotate location** → drag a letterbox-correct box on
any video → POST. Resolved anchors pushed live into overlays **and** the 3D scene (new anchor
spheres + labels in `scene3d.js`).
- **Acceptance (spec M8): PASS.** `tests/test_resolve.py::test_two_view_triangulation_recovers_corner`
— two-view stage-corner annotation lands **0.00000 units** from ground truth (< 0.2). Verified
live in-browser too: two-view annotation triangulated with gap 0.21 through the full
frontendAPIgeometry path; correction changed pyroconfetti with source=user and recolored
the marker.
### M9 — keyframed camera paths
- New `camPath.js`: ** Key**/`K` captures the free-roam pose at the current t_global; gizmos +
Catmull-Rom preview line; ** Path** follows position (Catmull-Rom) + orientation (slerp) by
t_global while the transport plays; ⤓/⤒ export/import JSON. `scene3d` gained
`enterPathMode`/`exitPathMode`/`applyCameraPose`; snap-to-camera and Free-roam/`Esc` cancel a
playing path.
- **Verified live:** 3 keyframes path mode on at t=6.0 s the viewer camera sat exactly on
keyframe #2 `[-10,6,12]` (Catmull-Rom driven).
- Polish present from lanes + this phase: loading state, per-video enable/disable, keyboard
(`Space`,`←/→`,`Shift`,`19`,`Esc/0`,`K`).
### Full-system pass
- **Backend: 101 passed** (`../.venv/bin/python -m pytest`) up from the 96 merge-day floor
(+5: 4 resolve + 1 event-patch; annotation test renamed).
- **Frontend: `npm run build` clean** (18 modules).
- End-to-end on the synthetic fixture: `synthetic → ingest → sync → events → serve` + frontend
loads with 0 console errors; M4 sync error ~16 ms at t=8 s (deterministic pump; half-frame
residual, < 50 ms).
- Cleanup: dropped the shared-worktree debris stash; removed `../festifun-laneA` and
`../festifun-laneB` worktrees; `frontend/dist/` gitignored; pristine demo DB regenerated.
**Blockers / notes for coordinator:**
- **Real-focused-browser M4 check is the one item I could not fully close from here.** The
automated browser pane runs `document.hidden=true`, so rAF is throttled and continuous
playback can't be observed (same limitation lane C hit). I verified sync deterministically
(pump ~16 ms) and every interaction via real handlers, but a human should open the app in a
normal focused window once to eyeball continuous multi-cam sync. Not code-blocking.
**Next:** merge `integration` `main`; tag `v0.1.0`.