Markers/badges -> detection -> cross-view triangulation -> track ribbons + follow-a-friend + LED badge hardware kit. Coordinator-merges policy this phase. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
233 lines
18 KiB
Markdown
233 lines
18 KiB
Markdown
# Coordinator Directives
|
||
|
||
Written **only** by the coordinator (the human's planning session). Agents: read the latest round at session start and after every milestone via `git fetch origin && git show origin/main:plan/DIRECTIVES.md`. The newest round addressed to your lane overrides older rounds and, where in conflict, your lane brief. Never edit this file.
|
||
|
||
---
|
||
|
||
## Round 6 — 2026-07-17 — PHASE 6 planned: Friend Tracks (M18–M24)
|
||
|
||
**Spec:** `plan/30-phase6.md` (canonical). Lane briefs: `plan/lane-H-tracker.md`,
|
||
`plan/lane-J-ribbons.md`, `plan/lane-K-badges.md`. Kickoff prompts are at the bottom of the
|
||
spec — the human launches each Opus session with one.
|
||
|
||
**Directives:**
|
||
1. **Now: `foundation3` only** (one agent, branch `foundation3`, M18). Contracts correctness
|
||
beats speed — three lanes hard-depend on your fixture ground truth, schema, detections
|
||
shape, and blink protocol. The synthetic-fixture edit must keep all 189 existing tests
|
||
green (spec pitfall #6). Maintain `plan/status/foundation3.md`. **Push your branch; do NOT
|
||
merge to main** — this phase the coordinator merges after review (see #4).
|
||
2. **After foundation3 merges — lanes in priority order** (all three concurrently if capacity
|
||
allows): **H** (tracker — longest, validates every contract), **J** (ribbons/follow — the
|
||
visible payoff), **K** (badges — independent, hardware-facing). Per-agent worktrees remain
|
||
MANDATORY.
|
||
3. **Merge policy (changed from Round 4):** agents do NOT merge to main and do NOT tag.
|
||
Push your lane branch + status file, report completion to the human; the human pings the
|
||
coordinator session, which reviews (independent suite re-run, ownership check, CR
|
||
adjudication) and merges in completion order. Everything else from Round 0 protocol
|
||
(status cadence, blocker rule, evidence discipline) unchanged.
|
||
4. **Review loop:** coordinator reads `plan/status/<lane>.md` + the branch diff on each ping;
|
||
findings come back as a new DIRECTIVES round or direct merge. Stub-era assertions
|
||
superseded by a landing milestone: CR entry + minimal edit (CR-1/-4/-5 house pattern).
|
||
5. **integration3** (after all three merge): full synthetic pass, floor raise, tracked field
|
||
test (fold in the still-open phase-5 field test), `v0.3.0` proposal. `v0.2.0` remains held
|
||
per Round 5.
|
||
|
||
**For the human:** (a) launch foundation3 first, alone, with its kickoff prompt; tell the
|
||
coordinator when its status file says ready; (b) then launch H, J, K in parallel; (c) the
|
||
field-test gate is unchanged — real clips in `data/raw/`, now ideally with a marker or badge
|
||
in frame; (d) if you order badge parts, `docs/hardware.md` (lane K) will have the list.
|
||
|
||
## Round 5 — 2026-07-17 — PHASE 5 COMPLETE on synthetic; floor 189; v0.2.0 waits on the field test
|
||
|
||
**Execution report (all same-day):** foundation2 → lanes E/G/F in parallel worktrees (per
|
||
directive 3) → integration2. Every lane merged after independent coordinator verification
|
||
(suite re-run in the lane's worktree, then on the merged tree, live-browser checks per
|
||
feature). Full evidence: plan/status/{foundation2,lane-E,lane-F,lane-G,integration2}.md.
|
||
|
||
**Accepted:** M10–M17 all pass acceptance on the synthetic fixture. Highlights: beats recover
|
||
the 120 BPM ground truth (worst beat 30 ms); director output is beat-snapped and shape-locked
|
||
through frozen geometry helpers; export produced a 13.98 s vp9/opus webm (±5% ✓, audio track
|
||
live) driven headless via the `__f4d` pump; the capsule boots with ZERO off-origin requests,
|
||
seeks over Range, hides all write UI. Lane F self-verified live in isolated servers — model
|
||
evidence discipline, worth repeating.
|
||
|
||
**Ratified:** CR-4 (lane G) and CR-5 (lane E) — stub-era test assertions superseded by
|
||
milestones landing, CR-1 precedent. **The test floor is now 189.** Build stays clean.
|
||
|
||
**Standing decisions:**
|
||
1. **v0.2.0 tag is HELD** until the real-footage field test runs (it is integration2's actual
|
||
milestone; synthetic-only doesn't earn the tag). Failures go to plan/ISSUES.md, not fixes.
|
||
2. Stub-era assertions in foundation tests are now an acknowledged lifecycle: when a milestone
|
||
lands, retiring its stub assertion via a CR entry + pointer to the real coverage is the
|
||
house pattern (CR-1/-4/-5). Foundation agents: prefer writing stub tests that survive the
|
||
landing (assert shape, not stub-ness) so future lanes don't need CRs.
|
||
3. `.gitignore` gained `data/capsule/` and `.claude/worktrees/`.
|
||
|
||
**For the human (the entire remaining critical path):**
|
||
(a) **Drop 2–4 real overlapping clips into `data/raw/`** — the field test and v0.2.0 gate on
|
||
this and only this.
|
||
(b) Focused-window eyeball pass (10 min, headphones): sync panel stays green during playback;
|
||
🎧 spatial audio while flying around; 🎬 auto-path ride; ⏺ export and CHECK THE FRAMES
|
||
(headless verified duration/audio only — rendered frame quality needs human eyes);
|
||
📷 photo PNG; ✨ FX bursts at full rAF rate; anchor panel roundtrip.
|
||
(c) Optional but high-impact: train a splat for the real project
|
||
(`scripts/splat_via_modelbeast.sh`) before capsuling it — photo mode + capsule get
|
||
dramatically better.
|
||
|
||
## Round 4 — 2026-07-17 — Fresh-eyes upgrades landed; PHASE 5 begins (M10–M17)
|
||
|
||
**Coordinator work landed directly on `main` (self-reviewed + live-verified):**
|
||
- `95b7178` — sync solver caches one rFFT per signal across the pairwise GCC-PHAT stage
|
||
(1.8× on 6 cams × 10 min; equivalence locked by a new unequal-lengths test).
|
||
- `c24af80` — **audio is now the master clock** (`GET /api/audio/{id}` AAC + WebAudio;
|
||
`t_global` from `AudioContext.currentTime`; all `<video>` muted picture-only; graceful
|
||
fallback) **+ spatial audio** (🎧 per-camera HRTF panners at live poses, listener = viewer
|
||
camera, gains 1/√N). Verified live: clock drives playback, mid-play source switching is
|
||
continuous, panners sit at the correct camera positions, toggle on/off mid-play is clean.
|
||
- `db42c42` — chore: `python-multipart` locked (declared-but-unlocked drift), launch configs.
|
||
- Suite is **121 passed**; frontend build clean. **The test floor is now 121.**
|
||
|
||
**Contract amendments (coordinator-ratified, additive only):** new route `GET /api/audio/{id}`;
|
||
`transport.js` is now the WebAudio clock owner (its header comment is the reference);
|
||
the `window.__f4d` debug hook is available in production builds via `localStorage f4dDebug=1`.
|
||
`test_api.py`'s manifest key-set lock is unchanged.
|
||
|
||
**Directives — Phase 5 (spec: `plan/20-phase5.md`; lane briefs: `plan/lane-E/F/G-*.md`):**
|
||
1. **Now: `foundation2` only** (one agent, branch `foundation2`, scope in 20-phase5.md).
|
||
Same rule as phase 1: contracts correctness beats speed — three lanes will hard-depend on
|
||
your route shapes, stubs, hooks, and UI wiring points. Maintain `plan/status/foundation2.md`.
|
||
2. **After foundation2 merges — lanes in priority order** (all three concurrently if capacity
|
||
allows): **E** (director — longest, earliest contract validation), **G** (capsule — the
|
||
shareable payoff), **F** (social UX — smallest, pure frontend).
|
||
3. **Worktree rule is MANDATORY this time:** every parallel agent creates its own `git worktree`
|
||
before its first edit (Round 1 standing lesson; the phase-2 shared-tree collision cost us a
|
||
stash cleanup). Single-agent phases (5a, 5c) may use the main working directory.
|
||
4. **Merge policy unchanged:** merge to `main` per-milestone where the lane brief allows it;
|
||
never wait on another lane. Then `integration2` (branch `integration2`), which owns the
|
||
real-footage field test and the `v0.2.0` tag proposal — failures go to `plan/ISSUES.md`,
|
||
not into hasty fixes.
|
||
5. Standing protocol (status files, evidence discipline, blocker rule, DIRECTIVES re-read after
|
||
every milestone) is unchanged from Round 0.
|
||
|
||
**For the human:** (a) the Round 3 focused-browser sync check is still open — now also put on
|
||
headphones, enable 🎧 3D audio, and fly around; (b) real overlapping clips for the field test
|
||
remain the gating item for integration2; (c) optional: a trained splat for a real project makes
|
||
photo mode (M14) and the capsule (M17) dramatically more impressive —
|
||
`scripts/splat_via_modelbeast.sh`.
|
||
|
||
## Round 3 — 2026-07-16 — Integration review: v0.1.0 ACCEPTED; polish + field test next
|
||
|
||
**Coordinator review of the integration work (independently verified):** `main` == `origin/main`
|
||
(d313c8d), tag `v0.1.0` on e5d6b2c. Re-ran the suite: **101 passed**; frontend build clean. The
|
||
M8 acceptance test is faithful (forward-projects ground truth, no self-confirmation); `resolve.py`
|
||
is clean orchestration over lane B's frozen primitives; CR-1/CR-2 correctly adjudicated and
|
||
strictly additive; camPath's Catmull-Rom parameterization maps exactly to three.js segment
|
||
lookup (checked). The live-browser M8/M9 verification methodology was sound given the
|
||
hidden-tab rAF throttle. **v0.1.0 accepted.**
|
||
|
||
**Ratification:** Round 2 was written by the integration agent; DIRECTIVES.md is coordinator-only.
|
||
Content verified accurate — ratified as written. Rule stands for future rounds.
|
||
|
||
**Review findings (all polish; none block the tag):**
|
||
1. **Anchor stacking — the one real wart.** Each annotation creates a NEW anchor, so the
|
||
documented two-view "refine" flow leaves BOTH the view-1 fallback anchor and the view-2
|
||
triangulated anchor, identically labeled (reproduced: 2 anchors for 1 object). On real
|
||
footage the fallback can be far off and there is no way to remove it — no
|
||
`DELETE /api/anchors/{id}`, no UI delete.
|
||
2. `docs/ideas.md` (spec §5 future-extensions note) was never created.
|
||
3. Human focused-browser M4 sync eyeball still open (carried from Round 2).
|
||
|
||
**Directives — Phase 4 (one agent, branch `phase4/polish-field-test`):**
|
||
1. **Polish pass (small, do first):**
|
||
- When an annotation resolves for an event that already has a resolved anchor from a prior
|
||
annotation of the same event, **update that anchor in place** (supersede the fallback with
|
||
the triangulation) instead of creating a sibling. Keep per-annotation `resolved_anchor_id`
|
||
history consistent.
|
||
- Add `DELETE /api/anchors/{id}` + a small delete affordance in the UI (e.g. in the
|
||
annotation panel or anchor list). Additive API only; file a CR entry noting it.
|
||
- Create `docs/ideas.md` (gaussian splatting, MP4 fly-through export, realtime ingest,
|
||
multi-modal audio analysis — from the spec's future-extensions list).
|
||
- Suite must stay ≥ 101; add tests for supersede + delete.
|
||
2. **Field test protocol (the real milestone):** when the user drops 2–4 real overlapping clips
|
||
into `data/raw/`, run `ingest → sync → reconstruct → events → serve`; record in
|
||
`plan/status/phase4.md`: per-pair sync confidence, offsets, COLMAP registration rate,
|
||
which milestones survived contact with real footage. **File failures as entries in a new
|
||
`plan/ISSUES.md` rather than rushing fixes** (per plan/10-integration.md item 4).
|
||
3. Maintain `plan/status/phase4.md`; same evidence discipline.
|
||
|
||
**For the human (unchanged + one new):** (a) open the app in a normal focused browser window
|
||
once and confirm the sync panel stays green during continuous playback; (b) shoot or collect
|
||
2–4 overlapping clips of the same performance for the field test; (c) ~~optionally set
|
||
`GEMINI_API_KEY`~~ done — see addendum.
|
||
|
||
**Round 3 addendum (coordinator, same day) — real API keys wired + first field finding:**
|
||
- A local **`.env`** now exists at the repo root (gitignored, chmod 600, **never commit**) with
|
||
`GEMINI_API_KEY` (default provider) and OpenRouter creds mapped to the `local` provider
|
||
(`FESTIVAL4D_OPENAI_*`, model `google/gemini-2.5-flash`). Load with
|
||
`set -a; . ./.env; set +a` before `python -m festival4d events`. Phase-4 agent: the file is
|
||
machine-local — if it's missing in your worktree, ask the coordinator, don't recreate keys.
|
||
- **Field finding #1 (fixed by coordinator hotfix):** Google retired `gemini-2.5-flash` for new
|
||
API keys (404 "no longer available to new users"). The Gemini model is now env-overridable
|
||
(`FESTIVAL4D_GEMINI_MODEL`) with default `gemini-3.1-flash-lite` — verified live: inline
|
||
video + JSON-schema structured output OK; **3/3 synthetic candidates classified correctly**
|
||
(`light_show`/`bass_drop`, coherent descriptions). Suite still 101 passed. The degradation
|
||
path also behaved exactly as designed during the failure — good lane D work.
|
||
- Phase-4 agent: consider a `plan/ISSUES.md` entry template seeded from this finding's shape
|
||
(symptom → root cause → fix → evidence).
|
||
|
||
## Round 2 — 2026-07-16 — Integration complete; v0.1.0 shipped
|
||
|
||
**Integration merged to `main` (e5d6b2c) and tagged `v0.1.0`.** M8 (annotation→3D correction +
|
||
triangulation) and M9 (keyframed camera paths) are done; README rewritten for v0.1.0. Both
|
||
change requests adjudicated and applied (CR-1, CR-2 — additive only; timebase/schema-columns/
|
||
pose/API shapes otherwise unchanged).
|
||
|
||
**Verification (coordinator-run on merged tree):** 101 backend tests pass (up from the 96
|
||
floor); two-view stage-corner recovery err **0.00000** (< 0.2); frontend build clean; live
|
||
in-browser M8 triangulation (gap 0.21) and M9 path (camera lands exactly on keyframe at t);
|
||
M4 sync ~16 ms via deterministic pump. Worktrees removed, debris stash dropped, `frontend/dist`
|
||
gitignored.
|
||
|
||
**One open item for the human (not code-blocking):** the automated browser pane runs
|
||
`document.hidden=true`, which throttles `requestAnimationFrame`, so continuous multi-cam
|
||
playback sync could only be verified deterministically, not by eye. **Open the app in a normal
|
||
focused browser window once** (`python -m festival4d serve` + `cd frontend && npm run dev`) and
|
||
confirm the top-right sync panel stays green (<50 ms) during continuous playback.
|
||
|
||
**Next:** the pipeline is ready for real footage — drop 2–4 overlapping concert clips into
|
||
`data/raw/` and run `ingest → sync → reconstruct → events → serve` (see README).
|
||
|
||
## Round 1 — 2026-07-16 — All lanes merged & verified; integration begins
|
||
|
||
**Coordinator review result:** foundation + all four lanes are merged to `main` (merge commits `e28dc78` A, `2cad2f7` B, `9d17b47` C; D fast-forwarded earlier at `5c2d7c6`). Independently verified on the merged tree: **96 backend tests pass**, synthetic `ingest → sync` recovers ground-truth offsets exactly (+0 / +1370 / −842 ms, drift 0), `events` finds 3 candidates and degrades gracefully unconfigured, frontend production build clean. Excellent evidence discipline across all lanes — keep it.
|
||
|
||
**Directives:**
|
||
|
||
1. **Integration phase starts now** — one agent, branch `integration` from `main`, per `plan/10-integration.md`. Maintain `plan/status/integration.md`.
|
||
2. **CR-1 (lane D, test_api.py stub assertion): APPROVED by coordinator.** The edit was a direct consequence of M7 landing and touched no frozen contract file. Integration agent: mark the Decision line in `plan/CHANGE_REQUESTS.md` and confirm the new assertion matches the spec M3 `POST /api/events/detect` response shape (`{result, events}`).
|
||
3. **Integration additions to the plan/10-integration.md scope** (small, discovered in review):
|
||
- The shared-worktree collision (see lane A/C status round 0) left a coordinator-stashed debris stash in the main working dir (`git stash list` — "stale lane A/B debris"). After confirming nothing of value remains, drop it, and remove the now-merged worktrees `../festifun-laneA` and `../festifun-laneB` (`git worktree remove`).
|
||
- Lane C's env note: continuous-playback sync was verified deterministically because the automated browser tab was backgrounded. During your full-system pass, verify the M4 sync overlay (<50 ms) once in a real focused browser window.
|
||
- Test count sanity: suite is 96 passed on merge day; it must never drop below that.
|
||
4. **Worktree protocol lesson (standing):** integration runs single-agent, so use the main working directory directly on branch `integration`. If parallel agents are ever launched again, each MUST create its own `git worktree` before its first edit — never share a working directory.
|
||
|
||
## Round 0 — 2026-07-16 — Run order & protocol
|
||
|
||
**Execution order:**
|
||
|
||
1. **Now: `foundation` only.** Nothing else starts until foundation merges to `main`. Foundation agent: contracts correctness beats speed — lanes will hard-depend on your API shapes, schema, pose math, and synthetic fixtures.
|
||
2. **After foundation merges — start lanes in this priority order** (all four concurrently if capacity allows; if running fewer sessions, start in this order):
|
||
1. **Lane C (viewer)** — longest lane and the earliest validation of the API contract; starts first.
|
||
2. **Lane A (media)** — the core real-footage capability; small surface, should finish early.
|
||
3. **Lane D (events)** — small and fully independent.
|
||
4. **Lane B (recon)** — heaviest external dependency (COLMAP) and the most graceful-degradation slack; safe to start last.
|
||
3. **Merge policy:** merge to `main` as soon as your lane's acceptance passes — do not wait for other lanes. Expected finish order: A, D, then C, then B.
|
||
4. **After all four merge: `integration`.**
|
||
|
||
**Standing protocol (all agents):**
|
||
- Maintain `plan/status/<your-lane>.md` per `plan/status/TEMPLATE.md` — session start, every milestone, every blocker, before merge. Push status commits to your branch immediately; the coordinator reviews between rounds by reading these files.
|
||
- If blocked > 30 minutes on an ambiguity, write the blocker to your status file, push, and move to another task in your lane rather than guessing on a frozen contract.
|
||
- Evidence discipline: a checked acceptance box must name the test or the exact command + output that proves it.
|
||
|
||
*(Future rounds will be appended above this line as the coordinator reviews status files.)*
|