4.3 KiB
Status — foundation3 (Phase 6a / M18)
Round 6 — 2026-07-17 — STATUS: ready_to_merge
Directives acknowledged: round 6 of plan/DIRECTIVES.md. Directive #1: foundation3 only,
branch foundation3, push — do NOT merge. Contracts correctness beats speed; keep 189 green.
Acceptance checklist (M18, plan/30-phase6.md §M18):
- 1. Synthetic fixture: two moving markers (A magenta
hue:150, B blinkcode:5) composited through each camera's real pose projection;data/work/track_truth.jsonbuilt from the SAME 3D paths (synthetic.build_track_truth, Three.js scene space).synthetic.project_pointis the exact inverse ofgeometry.ray_from_pixel. Basetestsrc2is saturation/brightness-muted (BASE_SATURATION/BASE_BRIGHTNESS) so its own magenta/cyan colour bars don't swamp lane H's colour detector — the discs are the only high-sat magenta/cyan + only bright small blobs (verified by a real-render test). - 2. DB:
Track/TrackPointtables (contract #2) +add_track/get_tracks/get_track/get_track_points/set_track_points/patch_track/delete_track/has_tracks. - 3. API: GET /api/tracks, PATCH/DELETE /api/tracks/{id}, POST /api/tracks/solve (degrades
to valid empty + note while lane H stubbed), manifest
has_tracks. Key-set lock edit → CR-6. - 4. CLI:
python -m festival4d track [--detect-only|--solve-only]→ lane-H stubs. - 5. Backend stubs:
tracker_detect.py/tracker_solve.py—NotImplementedError+ full contracts #1–#5 in docstrings; foundation-owned frozen constants (blink OOK, hue keys) live intracker_detectas the single source of truth (syntheticimports them). - 6. Frontend:
friendTracks.jsstub (never-throws, fx.js pattern) wired intomain.jsloop; hidden#btn-friends+#friends-panel;state.tracksloaded whenhas_tracks.npm run buildclean (27 modules, 851 ms). - 7. Capsule:
capsule.pybakesapi/tracks(additive). Bundle-structure test edit → CR-6. - 8. Tests:
test_tracks_foundation.py(20) — DB helpers, routes, solve degradation, manifest, frozen protocol/encoders, track_truth shape, the projection round-trip, and a real-ffmpeg render test proving marker A is the dominant magenta blob after base-muting.
Done this round: all 8 steps land. Evidence:
- Full suite 209 passed, exit 0 (
uv run pytest -q) — the 14 pre-existing files sum to exactly 189 (floor held), + 20 new intest_tracks_foundation.py(all passed, none skipped). test_projection_round_trip_recovers_ground_truth: projects both markers' 3D truth through every camera pose, back-projects via frozenray_from_pixel, triangulates viatriangulate_rays— worst recovery error < 1e-3 across ≥8 samples in 2+ views. Lane H's M20 target (median 3D error < 0.3) is reachable by construction (~300× margin).encode_word(5) == [1,1,1,0,0,0,0,0,1,0,1,1]; all 64 IDs preamble+parity+MSB-recover checked.- Frontend production build clean; manifest
has_tracksreflects the DB live. - CR-6 filed (plan/CHANGE_REQUESTS.md): the two sanctioned M18 test-lock edits (manifest key-set, capsule bundle paths) — additive, flagged for integration3 ratification.
Recovery note (2026-07-17): a prior foundation3 attempt left M18 half-done and uncommitted
in a stale locked worktree — steps 2/3/4/5/7 (DB/API/CLI/stubs/capsule) + the synthetic.py
marker code present, but step 1's ground-truth never validated, steps 6/8 (frontend/tests) not
started, suite never run. This session salvaged it: committed the WIP as checkpoint 6a703c3,
then completed steps 1/6/8 and verified every inherited contract choice against the spec. The
one real bug found: the base testsrc2 visual carried solid magenta+cyan bars (the marker hues)
that would have swamped lane H's colour detector — fixed by muting base saturation/brightness
and locked with a real-render regression test (marker A dominant-blob within 2.5 px, 24/24
frames). No work was redone. Do NOT merge — coordinator reviews + merges (DIRECTIVES R6 #3).
Blockers / questions for coordinator: none. Ready for review + merge.
Next: coordinator reviews git diff main..foundation3 + this file, merges to main.
After merge, lanes H / J / K launch in parallel worktrees (DIRECTIVES R6 #2).