fix(pipeline): finish three changes that had only been half applied
Each of these was recorded as done and was done in one place out of two. AR-011 -- the TransNetV2 dedup window. The derived window (dedup_window_sec, median observed interval halved) reached scenes.json and nothing else. SceneBoundaries, the path that actually feeds is_scene_boundary to the tracker, kept the literal 0.04 s under a comment claiming it "matches the dedup scenes.json applies, so the two views agree". They did not agree. 0.04 is one frame at 25 fps and wider than a frame at 30, so two cuts on consecutive frames merged into one and the loss was invisible: the pipeline simply saw fewer boundaries. The detector now supplies the window it derived. AR-019 -- ownership. The register says ownership "comes from the registry, not a second local tally". Both existed: promotion fired on a local accepted-frame count and fell back to a local per-actor plurality when the registry had not yet claimed the track. That fallback was reachable in the live pipeline, not just in tests -- three accepted frames arrive well before a posterior crosses the ownership threshold -- so in practice the plurality usually decided, and it could not see the AR-025 correlation discounting it was meant to defer to. The tally is gone; promotion now requires the registry's verdict, with the accepted -frame count demoted to an explicit evidence floor. AR-017 -- the route. DeadTrack carried belief but no route, and the sink wrote the literal string "live", so a field the schema publishes could not distinguish anything. AR-017's own verification asks for "deferred and pooled routes distinguishable". Route is now an enum on the claim. Only `live` occurs today; `deferred` exists so AR-020's pass has somewhere to write instead of a serialisation change to make. Also: TrackGallery::forget had no callers, under a comment asserting the matcher called it "on a cut or track disappearance". The cut half was true by another route; the disappearance half was not, so a track that died quietly kept its diversity buffer until the next cut cleared everything. Replaced with prune_dead against the registry's own liveness, the same shape as the tracker's prune_boxes -- a second opinion about which tracks exist is a second thing that can be wrong. Removes dead logistic/logit helpers and fixes five TRACES tags that used a comma where a pipe separates requirement types, which the gate had been reporting as diagnostics. TRACES: AR-011, AR-017, AR-019 | IR-002 | SR-002, SR-005
This commit is contained in:
@@ -210,6 +210,9 @@ TEST_CASE("band thresholds probability, not cosine", "[track_gallery][AR-018][AR
|
||||
TEST_CASE("a two-person track never poisons the annex", "[track_gallery][AR-018]") {
|
||||
TrackGallery tg(expand_cfg());
|
||||
tg.set_calibration(identity_cal);
|
||||
// AR-019: promotion needs the registry's verdict; the local
|
||||
// accepted-frame plurality that used to supply it is gone.
|
||||
tg.set_owner(3, 0);
|
||||
// Two orthogonal identities under one track ID — a track-ID collision.
|
||||
// The band refuses the outsider at the door, so the store never becomes
|
||||
// two-person in the first place.
|
||||
@@ -246,6 +249,9 @@ TEST_CASE("a track that drifts through the band is refused at promotion",
|
||||
TEST_CASE("confirmed track promotes its store", "[track_gallery][AR-019]") {
|
||||
TrackGallery tg(expand_cfg());
|
||||
tg.set_calibration(identity_cal);
|
||||
// AR-019: promotion needs the registry's verdict; the local
|
||||
// accepted-frame plurality that used to supply it is gone.
|
||||
tg.set_owner(7, 0);
|
||||
REQUIRE(tg.enabled());
|
||||
|
||||
// A track owned by actor 0: every frame accepted, every view mutually
|
||||
@@ -281,21 +287,29 @@ TEST_CASE("unconfirmed track (too few accepts) does not promote", "[track_galler
|
||||
CHECK(tg.annex_size() == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("plurality actor wins a mixed-vote track", "[track_gallery][AR-019]") {
|
||||
TEST_CASE("an unowned track never promotes, however many frames it accepts",
|
||||
"[track_gallery][AR-019]") {
|
||||
TrackGallery tg(expand_cfg());
|
||||
tg.set_calibration(identity_cal);
|
||||
// No registry attached (unit-test path): actor 5 accepted twice, actor 6
|
||||
// once → plurality is 5.
|
||||
tg.observe(8, spoke(1, kSpokeCos), 5, 0.30f, true, kNoCrop);
|
||||
tg.observe(8, spoke(2, kSpokeCos), 5, 0.30f, true, kNoCrop);
|
||||
tg.observe(8, spoke(3, kSpokeCos), 6, 0.30f, true, kNoCrop);
|
||||
REQUIRE(tg.annex_size() > 0);
|
||||
for (int actor : tg.annex_actors()) CHECK(actor == 5);
|
||||
// This case used to assert the opposite: it drove a mixed-vote track with
|
||||
// no registry owner and expected the local plurality winner (actor 5) to
|
||||
// take the promotion. That fallback is gone. AR-019 says ownership comes
|
||||
// from the registry and not from a second local tally, and the tally could
|
||||
// not see the AR-025 discounting -- so it weighted thirty near-identical
|
||||
// looks like thirty distinct ones.
|
||||
//
|
||||
// Ten accepted frames, no set_owner, nothing promoted.
|
||||
for (int k = 1; k <= 10; ++k)
|
||||
tg.observe(8, spoke(k, kSpokeCos), 5, 0.30f, true, kNoCrop);
|
||||
CHECK(tg.annex_size() == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("promotion is idempotent across a long track", "[track_gallery][AR-019]") {
|
||||
TrackGallery tg(expand_cfg());
|
||||
tg.set_calibration(identity_cal);
|
||||
// AR-019: promotion needs the registry's verdict; the local
|
||||
// accepted-frame plurality that used to supply it is gone.
|
||||
tg.set_owner(9, 0);
|
||||
for (int k = 1; k <= 3; ++k)
|
||||
tg.observe(9, spoke(k, kSpokeCos), 0, 0.30f, true, kNoCrop);
|
||||
const int after_confirm = tg.annex_size();
|
||||
@@ -328,6 +342,9 @@ TEST_CASE("eviction keeps the gallery-far views", "[track_gallery][AR-018]") {
|
||||
cfg.expand_min_anchor_frames = 4;
|
||||
TrackGallery tg(cfg);
|
||||
tg.set_calibration(identity_cal);
|
||||
// AR-019: promotion needs the registry's verdict; the local
|
||||
// accepted-frame plurality that used to supply it is gone.
|
||||
tg.set_owner(6, 0);
|
||||
|
||||
tg.observe(6, spoke(1, kSpokeCos), 0, 0.80f, true, kNoCrop); // well recognised
|
||||
tg.observe(6, spoke(2, kSpokeCos), 0, 0.40f, true, kNoCrop);
|
||||
@@ -354,6 +371,10 @@ TEST_CASE("promotions drain exactly once, in matrix order",
|
||||
"[track_gallery][AR-026]") {
|
||||
TrackGallery tg(expand_cfg());
|
||||
tg.set_calibration(identity_cal);
|
||||
// AR-019: promotion needs the registry's verdict; the local
|
||||
// accepted-frame plurality that used to supply it is gone.
|
||||
tg.set_owner(7, 0);
|
||||
tg.set_owner(8, 4);
|
||||
|
||||
std::vector<float> emb;
|
||||
std::vector<int> actor;
|
||||
|
||||
Reference in New Issue
Block a user