v0.19.0 — detection diagnostics: silent drops + near-miss capture
Two diagnostic improvements to the orchestrated detection pipeline surfaced by a 7-entity dogfood run on IMG_6847.jpg. Detection behavior unchanged — only the reporting of misses is improved so callers can take targeted recovery actions instead of guessing.
Highlights
Person path — distinguish two failure modes that v0.18 lumped into no_detection_after_chain:
chain_returned_zero— chain found nothingrank_exceeded_chain_pool— chain found N < K persons; this entity is rank K-1+. Carriesentities_in_chain_poolandthis_entity_rankso caller knows exactly how many detections exist
Object path — detect_all_bboxes now returns {assigned, near_miss, nms_drops} (BREAKING for direct callers; migration recipe in CHANGELOG). Missed-branch reason refined:
dino_below_threshold(+near_miss_candidatesshowing actual conf range; user can lower threshold)dropped_by_within_label_nms(+nms_drop_candidates)dino_not_matched(true zero — preserved)
Motivation
Real dogfood on roadside photo IMG_6847.jpg surfaced 2 silent drops in 30 minutes:
red_carrank-exceeded silently asno_detection_after_chainwhile siblingyellow_trucksucceeded on identical chain — sameattemptsfield, opposite outcomewildflower_clusters(multi_instance, threshold=0.18) reporteddino_not_matchedwith no way to tell if DINO had below-threshold candidates
Both fixes give users actionable diagnostic signal so they can refine plan.json without reading the source.
Tests
10 new regression tests + existing 22/22 pass + real-DINO+SAM lanterns fixture pass.
Cross-validated by fresh codex GPT-5.4 + superpowers Claude parallel review — both flagged same P1 (id() set comparison fragility against future _nms_bboxes refactor → fixed value-based) and same nit (CHANGELOG test count → fixed).
Out of scope (v0.20 backlog)
- Per-entity
entity.thresholdactually honored at DINO call (4th hidden bug) - Tiled/upscaled paths surfacing
diagnostics_unavailable_tiled_pathflag - Joint-pass threshold side-effect documented in CHANGELOG
- Test boundary tightening (
== 5not<= 5) NEAR_MISS_FLOORconstant migration tosrc/vulca/_segment.py
Migration
grep -rn 'detect_all_bboxes(' --include='*.py' .
# replace `result[label]` → `result["assigned"][label]`
# new diagnostic keys are optional: result["near_miss"], result["nms_drops"]detect_bbox (legacy single-label wrapper) preserves return shape (bbox, score) — no migration needed.
🤖 Authored by Claude Opus 4.7 + Codex GPT-5.4 + Superpowers Claude (parallel review)