Skip to Content
Ai LogRed-flag audit: they never fired β€” prune to kept questions + fail loudly

Red-flag audit + fix

Finding: red flags never fired in production

Same skew class as the model metadata. The gateway posts the raw anamnesis (bleeding, color, fever.exists, location1.secondary, …) to /red_flags, but every rule in redFlags.csv indexes derived features β€” is_bleeding_true, temperature, is_color_condition_black, is_secondary_locations_gingiva, … β€” which nothing in the serving path computes. So each rule raised KeyError, and evaluate() caught it with except (KeyError, TypeError): continue β€” silently skipping every rule. Net: zero red flags, ever, on both the ai-service path (/api/v1/diagnosis/red_flags, used by /api/diagnosis) and the gateway path (/api/ai/red_flags, used by the mobile app). Both managers + rule tables are duplicates and were both broken.

Changes

  1. Pruned the rule table to the questions we still collect. Of 22 rules, 18 depended on dropped questions (color, bleeding, fever, swelling, size, pus, elevation/topography, crater). Kept the 4 that use only kept fields: oral lesions (location), infant / elderly (age), pregnant (pregnancy). Applied to both redFlags.csv copies.
  2. Derive the features from the raw anamnesis (_derive_features) so the kept rules actually fire: age, is_pregnancy_true, is_secondary_locations_*. Applied to both managers.
  3. Fail loudly instead of silently. evaluate() no longer swallows KeyError/TypeError; if a rule references a feature the deriver doesn’t produce, it raises RuntimeError naming the rule β€” so a future metadata/rule mismatch surfaces instead of disappearing (this is what hid the original bug).

Verification

  • New red_flag_manager_test.py: the 4 rules fire from raw dotted-key anamnesis (pregnant/infant/elderly/oral), no false positives, missing age is neutral, scalar location.secondary handled, and an undefined-feature rule raises.
  • 6 tests pass; ruff clean on both managers.

Important note for later

This removed the melanoma / erysipelas / high-fever / bleeding red flags along with their inputs. Those were not firing anyway, but if we want them back we must re-collect the underlying signals (color, bleeding, fever) β€” deciding what to ask purely for safety is a separate product call, independent of what the model uses.

Last updated on