OpenFloodAI V1 Reason Codes and Risk-State Rules¶
1. Purpose¶
This document defines the first V1 reason codes for OpenFloodAI.
Reason codes explain why the system chose a risk state such as NORMAL, HIGH, or UNKNOWN_DEGRADED.
This is planning documentation only. It does not add risk-engine code, ML code, camera ingestion, alert delivery, database storage, dashboard UI, public warning logic, or training code.
The uppercase codes below are a pipeline/frame-level concern (camera, feed, and risk-engine
evidence). They are a distinct, separately implemented concept from the lowercase,
human-reviewed sample failure reasons (riverbank_not_visible, camera_moved, and so on)
defined in Riverbank/Reference Quality Checks on Validation Samples —
do not conflate the two.
2. Plain-Language Summary¶
A reason code is a short label that explains what happened.
Simple example: if the camera is offline, the system can record CAMERA_OFFLINE. That is clearer than a long vague message like “something may be wrong.”
Reason codes help operators, developers, and QA reviewers understand the system later. They should explain evidence, not give emergency instructions.
Reason-Code Naming Format¶
V1 reason codes should use uppercase snake case.
That means:
- Use capital letters.
- Use underscores between words.
- Do not use spaces.
- Keep names short and stable.
Examples:
- Good:
CAMERA_OFFLINE - Good:
HIGH_WATER_COVERAGE - Avoid:
camera offline - Avoid:
HighWaterCoverage
3. Risk States¶
OpenFloodAI V1 uses these risk states:
| Risk State | Simple Meaning |
|---|---|
NORMAL |
No concerning flood evidence is currently detected. |
ELEVATED |
Water evidence is higher than usual or starting to change. |
HIGH |
Strong evidence suggests flood risk may be developing. |
CRITICAL |
Severe evidence suggests urgent human review is needed. |
UNKNOWN_DEGRADED |
The system cannot safely judge risk because input is missing, stale, blocked, or unreliable. |
Simple example: if the camera is frozen, the risk state should be UNKNOWN_DEGRADED, not NORMAL.
4. Input-Quality Reason Codes¶
Input-quality reason codes describe whether evidence is good enough to use.
| Reason Code | Simple Meaning |
|---|---|
INPUT_USABLE |
The input looks good enough for analysis. |
INPUT_DEGRADED |
The input exists, but quality is reduced. |
INPUT_UNKNOWN |
The system cannot tell if the input is usable. |
BAD_TIMESTAMP |
The frame time is missing, wrong, or not trusted. |
MISSING_FRAME |
An expected frame was not received. |
LOW_CONFIDENCE |
The system has weak confidence in the evidence. |
Simple example: if a video frame arrives without a usable timestamp, record BAD_TIMESTAMP.
5. Camera / Feed Reason Codes¶
Camera/feed reason codes describe camera and video-stream problems.
| Reason Code | Simple Meaning |
|---|---|
CAMERA_OFFLINE |
The camera is not reachable. |
STREAM_DISCONNECTED |
The video stream disconnected. |
STALE_FRAMES |
The same old frame appears to repeat. |
LOW_VISIBILITY |
The river view is hard to see. |
CAMERA_OBSTRUCTED |
Something blocks the camera view. |
NIGHT_OR_LOW_LIGHT |
The scene is too dark or has too little light. |
HEAVY_RAIN_ON_LENS |
Rain on the lens makes the image hard to use. |
CAMERA_MOVED |
The camera view changed from the expected scene. |
Simple example: if the camera points away from the river after strong wind, record CAMERA_MOVED.
6. Vision / ML Reason Codes¶
Vision/ML reason codes describe what the vision module thinks it sees.
These codes are evidence only. They are not ground truth and are not public warning instructions.
| Reason Code | Simple Meaning |
|---|---|
WATER_REGION_VISIBLE |
The river or water area is visible. |
WATER_COVERAGE_INCREASED |
Water appears to cover more of the watched area. |
WATER_NEAR_REFERENCE_LINE |
Water appears close to a configured reference line. |
WATER_ABOVE_REFERENCE_LINE |
Water appears above a configured reference line. |
SCENE_CHANGED |
The scene changed enough that past comparison may be less reliable. |
MODEL_UNCERTAIN |
The model or visual method is unsure. |
Simple example: if water appears above a painted marker on a bridge support, record WATER_ABOVE_REFERENCE_LINE.
7. Temporal-Change Reason Codes¶
Temporal-change reason codes describe what happened over time.
| Reason Code | Simple Meaning |
|---|---|
PERSISTENT_WATER_INCREASE |
Water increase lasted across the evidence window. |
RAPID_WATER_RISE |
Water appears to be rising quickly. |
SHORT_SPIKE_ONLY |
A brief change happened but did not last. |
INSUFFICIENT_HISTORY |
There is not enough past evidence to judge change. |
MISSING_TIME_WINDOW |
The expected time window is incomplete. |
Simple example: one splash may be SHORT_SPIKE_ONLY. Water rising for several minutes may be PERSISTENT_WATER_INCREASE.
8. Risk-Engine Reason Codes¶
Risk-engine reason codes explain how the risk state was selected.
| Reason Code | Simple Meaning |
|---|---|
NORMAL_CONDITIONS |
Current evidence supports normal conditions. |
ELEVATED_WATER_EVIDENCE |
Evidence suggests early concern. |
HIGH_WATER_COVERAGE |
Water coverage is high enough to support a high-risk state. |
CRITICAL_WATER_EVIDENCE |
Evidence is severe enough to support urgent review. |
DEGRADED_EVIDENCE_USED |
Some evidence was poor quality and affected the decision. |
RISK_STATE_CHANGED |
The risk state changed from the previous state. |
RISK_STATE_UNCHANGED |
The risk state stayed the same. |
Simple example: a HIGH output might include HIGH_WATER_COVERAGE, PERSISTENT_WATER_INCREASE, and RISK_STATE_CHANGED.
9. Alert-Candidate Reason Codes¶
Alert-candidate reason codes explain what happened to an alert candidate.
| Reason Code | Simple Meaning |
|---|---|
HUMAN_REVIEW_NEEDED |
A person or approved local process should review the situation. |
ALERT_CANDIDATE_CREATED |
An alert candidate was created. |
ALERT_CANDIDATE_SUPPRESSED |
A candidate was not created because rules did not allow it. |
DUPLICATE_CANDIDATE_SUPPRESSED |
A repeated candidate was suppressed. |
OFFICIAL_WARNING_NOT_CREATED |
No official public warning was created by OpenFloodAI. |
Simple example: if a HIGH state already created a candidate two minutes ago, a duplicate may be suppressed with DUPLICATE_CANDIDATE_SUPPRESSED.
10. Offline / Local-Storage Reason Codes¶
Offline/local-storage reason codes describe network and edge storage behavior.
| Reason Code | Simple Meaning |
|---|---|
NETWORK_OFFLINE |
Cloud or internet access is unavailable. |
LOCAL_RECORD_QUEUED |
A record was stored locally for later upload. |
LOCAL_UPLOAD_PENDING |
Upload has not happened yet. |
LOCAL_STORAGE_LOW |
Local disk space is low. |
LOCAL_STORAGE_FAILED |
Local storage failed. |
Simple example: if the edge node cannot reach the cloud, it may record NETWORK_OFFLINE and LOCAL_RECORD_QUEUED.
11. Privacy / Safety Reason Codes¶
Privacy/safety reason codes explain sensitive-data handling and safety boundaries.
| Reason Code | Simple Meaning |
|---|---|
EXACT_LOCATION_RESTRICTED |
Exact GPS or placement details are restricted. |
PUBLIC_LOCATION_ONLY |
Only broad location information should be shown publicly. |
RAW_VIDEO_NOT_STORED |
Raw video was not stored. |
EVENT_CLIP_STORED |
A short event clip was stored under site policy. |
SENSITIVE_VIEW_DETECTED |
The view may include people, homes, roads, vehicles, or license plates. |
Simple example: if a road appears in the camera view, record SENSITIVE_VIEW_DETECTED and consider masking or cropping before public deployment.
12. How Multiple Reason Codes Should Be Combined¶
A record may include more than one reason code.
Use multiple codes when they explain different parts of the decision:
- Use input-quality codes to explain whether the video can be trusted.
- Use camera/feed codes to explain camera problems.
- Use vision/ML codes to explain visual evidence.
- Use temporal-change codes to explain what happened over time.
- Use risk-engine codes to explain the selected risk state.
- Use alert-candidate codes to explain alert-candidate behavior.
- Use privacy/safety codes to explain sensitive-data handling.
Rules:
- Include at least one reason code in every risk-engine output.
- Put the most important reason first when order is meaningful.
- Do not use reason codes as full public warning text.
- Do not hide degraded evidence behind a normal-looking result.
- Keep reason codes stable once event records depend on them.
Simple example: a record may include HIGH_WATER_COVERAGE, PERSISTENT_WATER_INCREASE, and HUMAN_REVIEW_NEEDED.
13. How Reason Codes Should Appear in Event / Audit Records¶
Reason codes should appear in event and audit records as an array of strings.
Example:
{
"record_type": "event_audit_record",
"site_id": "site-bridge-01",
"camera_id": "camera-bridge-01-main",
"timestamp": "2026-08-27T14:05:00+05:45",
"risk_state": "HIGH",
"reason_codes": [
"HIGH_WATER_COVERAGE",
"PERSISTENT_WATER_INCREASE",
"RISK_STATE_CHANGED",
"ALERT_CANDIDATE_CREATED"
]
}
Audit records should also include the evidence window, software version, config version, and model version if a model was used.
Simple example: months later, a reviewer should be able to see that an alert candidate happened because water coverage was high and stayed high, not because of a random single frame.
14. Validation and Testability Expectations¶
Future tests should check reason-code behavior.
Test expectations:
CAMERA_OFFLINEshould lead toUNKNOWN_DEGRADED.STALE_FRAMESshould not produceNORMAL.HIGH_WATER_COVERAGEplusPERSISTENT_WATER_INCREASEcan supportHIGH.CRITICAL_WATER_EVIDENCEcan supportCRITICAL.LOW_CONFIDENCEshould be visible in audit records.- Every risk-engine output should include at least one reason code.
- Public-facing records should not include private location or camera-secret details.
- Alert candidates should include review-oriented codes, not evacuation instructions.
Simple example: a unit test can give the future risk engine fake input with CAMERA_OFFLINE and check that the output state is UNKNOWN_DEGRADED.
Risk-State Rule Guidance¶
These are simple guidance rules for future implementation. They are not final algorithms.
- If the camera is offline or frames are stale, use
UNKNOWN_DEGRADED, notNORMAL. - If video quality is poor enough that the river cannot be judged, use
UNKNOWN_DEGRADED. - If water evidence is mildly higher but not persistent, the system may use
ELEVATED. - If water evidence is high and persistent, the system may use
HIGH. - If water evidence is severe or rapidly rising, the system may use
CRITICAL. - If evidence is unclear, say so with reason codes such as
LOW_CONFIDENCE,MODEL_UNCERTAIN, orINSUFFICIENT_HISTORY. - If an alert candidate is created, include
ALERT_CANDIDATE_CREATEDandHUMAN_REVIEW_NEEDED. - If OpenFloodAI does not create an official warning, use
OFFICIAL_WARNING_NOT_CREATEDwhen that boundary needs to be visible.
Simple example: high water in one frame may be noise. High water plus several minutes of persistent rise is stronger evidence.
15. Known Unknowns¶
The following are not settled yet:
- Final numeric thresholds for
ELEVATED,HIGH, andCRITICAL. - Final site-specific reference lines or baseline definitions.
- Full reason-code list for every future component.
- Whether some reason codes should have severity levels.
- Whether reason-code ordering should be required.
- How reason codes should be translated for operator dashboards.
- Which reason codes should be public versus restricted.
- How long deprecated reason codes should remain supported.
These unknowns should become future issues, schemas, tests, or ADRs.
Safety Boundaries¶
Reason codes explain evidence.
Reason codes are not official emergency instructions.
OpenFloodAI V1 should create alert candidates for review, not public evacuation orders.
Missing or bad camera data must never be treated as normal by default.
ML/vision output must remain evidence, not ground truth.
Simple example: CRITICAL_WATER_EVIDENCE means urgent human review is needed. It does not mean OpenFloodAI has officially ordered an evacuation.
Architect Review Notes¶
Architecture decisions supported by these reason codes:
- Observation, risk assessment, alert candidates, and public warnings remain separate.
- Risk-engine outputs can explain state changes with auditable reason codes.
- Degraded evidence is explicit instead of silently becoming
NORMAL. - ML/vision reason codes are evidence only.
- Offline and privacy behavior can be recorded in the same audit trail.
Main architecture caution:
- Future code should not treat one reason code, one model output, one frame, or one camera as enough to issue an official public warning.
QA Challenge Notes¶
QA concerns to test in future stories:
- Missing reason codes should fail validation for risk-engine outputs.
- Camera/feed failure codes should produce visible degraded states.
- Risk-state rule tests should cover normal, elevated, high, critical, and unknown/degraded paths.
- Audit records should preserve reason codes, versions, timestamps, and evidence windows.
- Public-facing records should be checked so private location and camera-secret details do not leak.
- False alert candidates and missed dangerous events should both become measurable test concerns.
QA recommendation:
- This reason-code list is a useful V1 baseline, but it is not a production-safety claim. Future work needs schemas, validation tests, replay tests, and field evidence.