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

4.2 KiB
Raw Blame History

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 frontend→API→geometry path; correction changed pyro→confetti 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 integrationmain; tag v0.1.0.