pyronear / pyronear/pyro-annotator
FP lane gaining missed-smoke stays annotated with no boxes, and exports
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 0
- Forks
- 1
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 2
Description
An FP lane sitting at annotated can gain missed-smoke — and therefore start needing localization — without changing stage, so neither the localization guard nor the FP→smoke demotion fires. The lane ends up at annotated, needing localization, with zero boxes: on /localize/done and in /export/alerts.
This is the state #346 set out to prevent. PR #352 closed every path into annotated; this one never crosses that boundary.
Reproduced
SEEDED: [('annotated', {'annotation': []})] # FP lane's empty placeholder
PATCH {"has_missed_smoke": true}
PATCH status: 200
RESULT stage: annotated
RESULT has_missed_smoke: True
IN /localize/done: True
IN /export/alerts: True
Why both guards miss it
- The localization guard (
sequence_annotations.py,assert_localization_complete) requires the stage to be changing intoannotated. Heretarget_processing_stage == existing.processing_stage == ANNOTATED, so it is skipped. Widening it would not help either: the FP exit already wrote empty annotated-stage detection annotations viaauto_create_detection_annotations, soassert_localization_completewould pass on those rows. - The FP→smoke promotion (
is_fp_promotion) requirestarget_processing_stage == SEQ_ANNOTATION_DONE. A flags-only PATCH leaves the stage alone, so the demotion — which would delete those empty rows and re-arm auto-annotate — never runs.
Reachable from the UI, not just the API
frontend/src/pages/LocalizeAlertPage.tsx sends exactly this PATCH from the missed-smoke row:
apiClient.updateSequenceAnnotation(annotationId, { has_missed_smoke: value })
and missedSmokeAnnotationId falls back to "the first lane that has an annotation at all", which can be the FP lane. The row renders in done mode.
Suggested fix
Key is_fp_promotion on the flag transition rather than the target stage: a lane at annotated that did not previously need localization but does after this edit should demote to seq_annotation_done, whatever stage the payload names. That is the intent issue #275 already established — the current predicate just happens to detect it only when the client also sends the new stage.
Worth confirming as part of that work: a flags-only PATCH would then change processing_stage without the client asking, which callers should expect.
Found by review of #352; not a regression (the same gap existed before it, via the existing == SEQ_ANNOTATION_DONE form of the guard).
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with is_fp_promotion and the localization guard in sequence_annotations.py, then trace the missed-smoke PATCH from frontend/src/pages/LocalizeAlertPage.tsx. Reproduce the flags-only update described in the issue and verify that a lane newly needing localization is demoted from annotated to seq_annotation_done, avoiding the zero-box localization and export states.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, typescript
- Domain
- api, backend, frontend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100