Skip to content

v0.19.0 — detection diagnostics: silent drops + near-miss capture

Choose a tag to compare

@yha9806 yha9806 released this 27 Apr 14:12
327fff3

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 nothing
  • rank_exceeded_chain_pool — chain found N < K persons; this entity is rank K-1+. Carries entities_in_chain_pool and this_entity_rank so caller knows exactly how many detections exist

Object pathdetect_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_candidates showing 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:

  1. red_car rank-exceeded silently as no_detection_after_chain while sibling yellow_truck succeeded on identical chain — same attempts field, opposite outcome
  2. wildflower_clusters (multi_instance, threshold=0.18) reported dino_not_matched with 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.threshold actually honored at DINO call (4th hidden bug)
  • Tiled/upscaled paths surfacing diagnostics_unavailable_tiled_path flag
  • Joint-pass threshold side-effect documented in CHANGELOG
  • Test boundary tightening (== 5 not <= 5)
  • NEAR_MISS_FLOOR constant migration to src/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)