adeem6 commited on
Commit
b2512e2
·
verified ·
1 Parent(s): f492127

Upload 2 files

Browse files
Files changed (2) hide show
  1. README_NEW.md +449 -0
  2. ethics_and_safety_report.txt +287 -0
README_NEW.md ADDED
@@ -0,0 +1,449 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # HaramGuard — Agentic AI Safety System for Hajj Crowd Management
2
+
3
+ HaramGuard is a real-time, multi-agent decision-support system that integrates computer vision, risk modeling, reflective bias correction, and LLM-based coordination to assist human operators in preventing crowd crush during Hajj and Umrah.
4
+
5
+ Designed for deployment at the Grand Mosque (Masjid al-Haram), the system analyzes video feeds, estimates crowd risk levels, and generates structured operational recommendations — while maintaining strict human-in-the-loop governance, safety guardrails, and full auditability.
6
+
7
+ **Capstone Project · Tuwaiq Academy**
8
+ **Developed by: Adeem Alotaibi, Reem Alamoudi, Munirah Alsubaie, Nourah Alhumaid
9
+ Supervised by: Eng. Omer Nacar**
10
+
11
+ ---
12
+
13
+ ## Table of Contents
14
+
15
+ 1. [Overview](#1-overview)
16
+ 2. [Problem Definition](#2-problem-definition)
17
+ 3. [Solution / System Architecture](#3-solution--system-architecture)
18
+ 4. [Agentic System Design (Agents Description)](#4-agentic-system-design-agents-description)
19
+ 5. [Human-in-the-Loop Design](#5-human-in-the-loop-design)
20
+ 6. [Guardrails](#6-guardrails)
21
+ 7. [System Architecture Diagram](#7-system-architecture-diagram)
22
+ 8. [Installation & Running](#8-installation--running)
23
+ 9. [Repository Structure](#9-repository-structure)
24
+ 10. [Iterative Improvements](#10-iterative-improvements)
25
+ 11. [Ethics & Safety](#11-ethics--safety)
26
+ 12. [Limitations & Future Work](#12-limitations--future-work)
27
+
28
+ ---
29
+
30
+ ## 1. Overview
31
+
32
+ HaramGuard is implemented as a **single-pipeline, multi-agent** system. One orchestration layer (`RealTimePipeline` in `backend/pipeline.py`) runs a fixed sequence of five agents per video frame and maintains a single shared state. The pipeline does not replace the operator; it produces a stream of recommendations and alerts that the operator may approve, reject, or ignore via a React dashboard.
33
+
34
+ - **Backend:** Python (FastAPI), Ultralytics YOLO, OpenCV, NumPy, SciPy; SQLite persistence via `HajjFlowDB` (`backend/core/database.py`). Optional Streamlit dashboard entry point in `dashboard.py`.
35
+ - **Frontend:** React 18, Vite, Tailwind CSS, Lucide icons; polls the backend REST API for real-time state and displays KPIs, risk gauge, proposed actions, and decisions log with approve/reject/delete controls.
36
+ - **Data flow:** Video frames → PerceptionAgent → RiskAgent → ReflectionAgent → OperationsAgent → CoordinatorAgent (when a decision exists). State is updated each frame and persisted (risk events every 30 frames; reflection every frame; decisions and coordinator plans when emitted). The FastAPI server exposes `/api/realtime/state`, `/api/frames/buffer`, `/api/actions/{id}/approve`, `/api/actions/{id}/reject`, `/api/reset`, and `/health`.
37
+
38
+ ---
39
+
40
+ ## 2. Problem Definition
41
+
42
+ ### 2.1 Real-World Problem
43
+
44
+ Mass gatherings during Hajj and Umrah create extreme crowd densities in and around the Grand Mosque. Crowd crush and stampede events have occurred in the past, with serious consequences. Effective crowd management depends on timely detection of rising density and flow bottlenecks, and on recommending proportionate interventions (e.g. opening gates, directing flow, broadcasting guidance) before conditions become critical.
45
+
46
+ Manual monitoring of many camera feeds is error-prone and does not scale. Operators need a system that (1) continuously estimates crowd density and risk from video, (2) explains why a risk level was assigned, and (3) suggests concrete actions while leaving all execution decisions to humans.
47
+
48
+ ### 2.2 Significance
49
+
50
+ - **Safety:** Reducing the likelihood of crowd crush by earlier, evidence-based recommendations.
51
+ - **Scale:** Supporting operators who cannot watch every feed; the system aggregates perception and risk into a single, interpretable state.
52
+ - **Accountability:** Every recommendation is logged with reasoning (risk events, reflection log, decisions, coordinator plans), supporting post-incident review and governance.
53
+ - **Context:** The system is designed to respect the religious and social context of Hajj (no individual identification, human authority over actions, alignment with consultation-based decision-making).
54
+
55
+ ---
56
+
57
+ ## 3. Solution / System Architecture
58
+
59
+ ### 3.1 High-Level Design
60
+
61
+ HaramGuard uses a **deterministic, unidirectional pipeline**:
62
+
63
+ 1. **PerceptionAgent** turns each video frame into a structured `FrameResult` (person count, density, spacing, 3×3 spatial grid for hotspots, annotated frame). It uses a YOLO model (path and size in `backend/config.py`); an optional VisionCountAgent (Claude Vision) is available in code but disabled in the default pipeline.
64
+ 2. **RiskAgent** maintains a sliding window of `FrameResult`s and computes a risk score and level (LOW/MEDIUM/HIGH) using four paths: Fruin-style EMA of count, instant high-count floor, pre-emptive rate-of-change, and spatial clustering from the 3×3 grid. Output is `RiskResult`.
65
+ 3. **ReflectionAgent** observes `RiskResult` and `FrameResult`, detects four bias patterns (chronic LOW, rising trend ignored, count–risk mismatch, over-estimation), and corrects risk level/score when needed. All reflections are logged to the database.
66
+ 4. **OperationsAgent** emits a `Decision` only when the risk level *changes* (event-driven). Priority (P0/P1/P2) is derived from config thresholds aligned with RiskAgent. P0 decisions are rate-limited per zone. Decisions are stored in the database; actions and selected gates are left empty until the Coordinator fills them.
67
+ 5. **CoordinatorAgent** is invoked by the pipeline for **every** decision (P0, P1, P2). It calls an LLM (Groq API) to generate a structured plan (threat level, executive summary, selected gates, immediate actions, Arabic alert, confidence). A ReAct loop (reason → act → observe, max 3 iterations) validates output with six guardrails (GR-C1–C6); the pipeline then fills the decision's actions, justification, and selected_gates from the plan and stores the plan in the database.
68
+
69
+ **Single state:** One `state` dictionary is updated each frame and exposed to the FastAPI server; the React dashboard polls it. All numeric thresholds and caps live in `backend/config.py`.
70
+
71
+ ### 3.2 Data Flow
72
+
73
+ - **Input:** Video frames from a file or camera (path set by `VIDEO_PATH` in config).
74
+ - **Output:** Per-frame state (frame_id, person_count, density_score, risk_score, risk_level, trend, latest_decision, coordinator_plan, arabic_alert, reflection_summary, risk_history, decisions_log, etc.) plus persisted records in SQLite: `risk_events`, `op_decisions`, `coordinator_plans`, `reflection_log`.
75
+ - **Interfaces:** Backend: FastAPI on port 8000 (configurable via `API_PORT`). Frontend: Vite dev server (e.g. port 5173), configurable via `VITE_API_BASE_URL` for the API base URL.
76
+
77
+ ---
78
+
79
+ ## 4. Agentic System Design (Agents Description)
80
+
81
+ The pipeline runs five agents in order each frame. Each agent is implemented in a single module under `backend/agents/`. Data flows unidirectionally; agents do not call each other directly.
82
+
83
+ ### 4.1 PerceptionAgent (`perception_agent.py`)
84
+
85
+ - **Role:** Convert a raw video frame into a `FrameResult`: person count, density score, average spacing, bounding boxes, annotated frame, track IDs, occupation percentage, and a 3×3 spatial grid (grid_counts, grid_max, hotspot_zone) for downstream hotspot detection. Based on Umm Al-Qura University (UQU) Haram crowd research: local clustering in one cell can indicate risk even when global count is moderate.
86
+ - **Design pattern:** Tool use — YOLO for detection and tracking; optional VisionCountAgent (Claude Vision) for an alternative count when an Anthropic key is provided. In the current default pipeline, PerceptionAgent is instantiated without an Anthropic key (YOLO-only).
87
+ - **Guardrails:** GR1 — person count capped at `MAX_PERSONS` (1000 in agent class). GR2 — density score capped at `MAX_DENSITY` (50.0).
88
+ - **Input:** Raw frame (numpy array). **Output:** `FrameResult` (see `backend/core/models.py`).
89
+
90
+ ### 4.2 RiskAgent (`risk_agent.py`)
91
+
92
+ - **Role:** Maintain a sliding window (30 frames) of recent `FrameResult`s and compute a scalar risk score in [0, 1] and a discrete risk level (LOW / MEDIUM / HIGH), plus trend (rising / stable / falling). Final score is the maximum of four paths: (1) Fruin smooth — EMA of current person count normalized to `RISK_HIGH_COUNT` (50), with spacing and trend weights; (2) instant floor — if current count ≥ HIGH_COUNT, score floor 0.70; (3) pre-emptive ROC — 5-frame growth and EMA thresholds; (4) spatial clustering — if any 3×3 grid cell has ≥ `GRID_CELL_HIGH` persons (from FrameResult), floor 0.70. Score is clamped to [0, 1] (GR3).
93
+ - **Design pattern:** Sliding window + multi-path weighted scoring. Window size, thresholds, and weights are in `config.py`.
94
+ - **Input:** `FrameResult`. **Output:** `RiskResult` (frame_id, risk_score, risk_level, trend, level_changed, window_avg, window_max, density_ema, density_pct).
95
+
96
+ ### 4.3 ReflectionAgent (`reflection_agent.py`)
97
+
98
+ - **Role:** Critique the current risk assessment and correct it when one of four bias patterns is detected: (1) chronic LOW — N consecutive LOW frames with average person count above threshold → upgrade to MEDIUM; (2) rising trend ignored — trend=rising, risk=LOW, count above threshold → upgrade to MEDIUM; (3) count–risk mismatch — high person count but LOW risk → upgrade to MEDIUM or HIGH; (4) over-estimation — HIGH risk but person count below threshold (e.g. < 15) → downgrade to MEDIUM. All reflections are persisted to `reflection_log` by the pipeline.
99
+ - **Design pattern:** Reflection (observe → critique → correct → log). History window and thresholds in config (`REFLECTION_BIAS_WINDOW`, `REFLECTION_CROWD_LOW_THRESH`, `REFLECTION_HIGH_CROWD_THRESH`, `REFLECTION_OVER_EST_THRESH`).
100
+ - **Input:** `RiskResult`, `FrameResult`. **Output:** Reflection dict; pipeline applies corrections to `RiskResult` before passing to OperationsAgent.
101
+
102
+ ### 4.4 OperationsAgent (`operations_agent.py`)
103
+
104
+ - **Role:** Map the (possibly reflection-corrected) risk level to an operational priority (P0 / P1 / P2) and emit a `Decision` only when the risk level *changes*. Priority is derived from config (`OPS_P0_SCORE`, `OPS_P1_SCORE`) aligned with RiskAgent thresholds. P0 emission is rate-limited per zone (cooldown 300 s in agent class). The decision's actions and selected_gates are left empty; the pipeline fills them via CoordinatorAgent and then stores the decision in `op_decisions`.
105
+ - **Design pattern:** Event-driven; no decision when level unchanged.
106
+ - **Input:** `RiskResult`, context string (e.g. `Mecca_Main_Area`). **Output:** `Decision` or None.
107
+
108
+ ### 4.5 CoordinatorAgent (`coordinator_agent.py`)
109
+
110
+ - **Role:** For every decision (P0, P1, or P2), produce a structured action plan using the Groq LLM (model in agent, e.g. `openai/gpt-oss-120b`). Plan includes threat_level, executive_summary, selected_gates, immediate_actions, actions_justification, arabic_alert, confidence_score. Implements a ReAct loop (max 3 iterations): reason (build prompt from RiskResult, Decision, frame buffer; optional feedback from failed validation) → act (LLM call, parse JSON) → observe (run guardrails GR-C1–C6); repeat until valid or max iterations. Pipeline fills the decision's actions, justification, and selected_gates from the plan and stores the plan in `coordinator_plans`.
111
+ - **Design pattern:** ReAct (reason → act → observe) + output guardrails.
112
+ - **Input:** `RiskResult`, `Decision`, list of recent `FrameResult`s. **Output:** Plan dict.
113
+
114
+ ### 4.6 VisionCountAgent (`vision_count_agent.py`) — Optional
115
+
116
+ - **Role:** Provide an alternative person count by sending a subset of frames to a vision API (e.g. Claude Vision). Designed to be called from PerceptionAgent in hybrid mode to improve count in dense or occluded scenes. Not used in the default pipeline (PerceptionAgent is instantiated with `anthropic_key=None`).
117
+ - **Design pattern:** Tool use; sampling and rate limiting internal to avoid API overload.
118
+
119
+ ---
120
+
121
+ ## 5. Human-in-the-Loop Design
122
+
123
+ HaramGuard is a **decision-support** system, not an autonomous enforcement system. Every action that affects the physical world (opening gates, dispatching security, broadcasting alerts) is a **recommendation** to a human operator. No such action is executed by the system alone.
124
+
125
+ - **OperationsAgent** emits prioritized decisions (P0/P1/P2) and stores them; **CoordinatorAgent** produces Arabic alert text and action plans (gates, immediate actions) for each decision. These are shown on the React dashboard as "proposed actions."
126
+ - **Human operator** approves or rejects each proposed action via the dashboard. The API records approve/reject via `/api/actions/{id}/approve` and `/api/actions/{id}/reject`; the system does not execute any action itself.
127
+ - **Operator responsibilities:** Treat system silence (e.g. API down or pipeline stopped) as a trigger to switch to manual monitoring; review P0 recommendations and Arabic alerts before any broadcast or deployment; use the dashboard as one input among others (e.g. direct camera views, on-ground reports).
128
+
129
+ This design aligns with the principle of consultation (Shura) and with due diligence in decisions that affect lives: the machine informs, the human decides.
130
+
131
+ ---
132
+
133
+ ## 6. Guardrails
134
+
135
+ Guardrails are hard constraints and validations applied in code to keep outputs within safe and interpretable bounds. The following are implemented in the current repository.
136
+
137
+ | ID | Agent | Guardrail | Justification |
138
+ | --- | --- | --- | --- |
139
+ | **GR1** | PerceptionAgent | Person count capped at MAX_PERSONS (1000 in agent) | Prevents implausibly high counts from YOLO artifacts from propagating to risk and alerts. |
140
+ | **GR2** | PerceptionAgent | Density score capped at MAX_DENSITY (50.0) | Keeps density in a bounded range for downstream risk formulas. |
141
+ | **GR3** | RiskAgent | Risk score clamped to [0.0, 1.0] | Ensures threshold comparisons (e.g. 0.35, 0.65) remain valid. |
142
+ | **GR4** | OperationsAgent | P0 rate-limited per zone (cooldown 300 s in agent) | Reduces alert fatigue; risk is still logged; only decision emission is rate-limited. |
143
+ | **GR-C1** | CoordinatorAgent | Required JSON fields enforced; missing set to safe defaults | Prevents dashboard or downstream logic from breaking when the LLM omits fields. |
144
+ | **GR-C2** | CoordinatorAgent | threat_level whitelist (CRITICAL, HIGH, MEDIUM, LOW) | Avoids invalid or adversarial values that would break UI or logic. |
145
+ | **GR-C3** | CoordinatorAgent | confidence_score in [0, 1]; otherwise 0.5 | Normalizes LLM output so confidence is comparable. |
146
+ | **GR-C4** | CoordinatorAgent | Full range enforcement: threat_level overridden to match actual risk_score thresholds (LOW/MEDIUM/HIGH) | Prevents LLM from returning HIGH threat during MEDIUM risk or CRITICAL during LOW risk. |
147
+ | **GR-C5** | CoordinatorAgent | Arabic alert fallback if empty | Ensures safety-critical Arabic alert is never empty on the dashboard. |
148
+ | **GR-C6** | CoordinatorAgent | selected_gates must be non-empty list; otherwise fallback | Ensures operators receive concrete gate recommendations. |
149
+ | **RF1** | ReflectionAgent | Chronic LOW bias: N consecutive LOW with avg count above threshold → MEDIUM | Addresses sliding-window lag during rapid escalation. |
150
+ | **RF2** | ReflectionAgent | Rising trend ignored: trend=rising, LOW, count above threshold → MEDIUM | Corrects inconsistent state (rising crowd with LOW risk). |
151
+ | **RF3** | ReflectionAgent | Count–risk mismatch: high count but LOW risk → upgrade to MEDIUM/HIGH | Corrects mathematically inconsistent states. |
152
+ | **RF4** | ReflectionAgent | Over-estimation: HIGH risk but count < threshold (e.g. 15) → MEDIUM | Reduces false HIGH from empty or near-empty frames. |
153
+
154
+ Each guardrail is implemented in the corresponding agent file; further justification is documented in `ethics_and_safety_report.txt`.
155
+
156
+ ---
157
+
158
+ ## 7. System Architecture Diagram
159
+
160
+ ```text
161
+ ┌───────────────┐
162
+ │ Video Frame │
163
+ └───────┬───────┘
164
+
165
+
166
+ ┌───────────────┐
167
+ │PerceptionAgent│
168
+ └───────┬───────┘
169
+
170
+
171
+ ┌───────────────┐
172
+ │ RiskAgent │
173
+ └───────┬───────┘
174
+
175
+
176
+ ┌───────────────┐
177
+ │ReflectionAgent│
178
+ └───────┬───────┘
179
+
180
+
181
+ ┌───────────────┐
182
+ │OperationsAgent│
183
+ └───────┬───────┘
184
+
185
+
186
+ ┌───────────────┐
187
+ │CoordinatorAgent│
188
+ └───────┬───────┘
189
+
190
+
191
+ ┌───────────────┐
192
+ │ HajjFlowDB │
193
+ │ (SQLite) │
194
+ └───────┬───────┘
195
+
196
+
197
+ ┌───────────────┐
198
+ │ FastAPI │
199
+ │ REST API │
200
+ └───────┬───────┘
201
+
202
+
203
+ ┌───────────────┐
204
+ │ React │
205
+ │ Dashboard │
206
+ │(Human-in-the- │
207
+ │ Loop) │
208
+ └───────────────┘
209
+ ```
210
+
211
+ ---
212
+
213
+ ## 8. Installation & Running
214
+
215
+ ### 8.1 Prerequisites
216
+
217
+ - Python 3.9+ (backend)
218
+ - Node.js 18+ (frontend)
219
+ - Groq API key (required for CoordinatorAgent). Anthropic API key optional (only if enabling VisionCountAgent in the pipeline).
220
+
221
+ ### 8.2 Backend
222
+
223
+ ```bash
224
+ cd backend
225
+ python -m venv venv
226
+ source venv/bin/activate # Windows: venv\Scripts\activate
227
+ pip install -r requirements.txt
228
+ ```
229
+
230
+ Set `GROQ_API_KEY` in the environment or in `backend/config.py`. Set `VIDEO_PATH` to a valid video file path (default: `hajj_real_video.mp4` in the backend directory). Set `MODEL_PATH` if using a different YOLO weight file (default: `yolo11l.pt`).
231
+
232
+ ```bash
233
+ python api.py
234
+ ```
235
+
236
+ API listens on `http://0.0.0.0:8000` by default (port configurable via `API_PORT` in config).
237
+
238
+ ### 8.3 Frontend
239
+
240
+ ```bash
241
+ cd frontend
242
+ npm install
243
+ npm run dev
244
+ ```
245
+
246
+ Dashboard at `http://localhost:5173` (or the port Vite reports). If the API is not at `http://localhost:8000`, set `VITE_API_BASE_URL` in `frontend/.env` or the environment.
247
+
248
+ ### 8.4 Evaluation
249
+
250
+ From the backend directory:
251
+
252
+ ```bash
253
+ python evaluation.py
254
+ ```
255
+
256
+ Outputs are written to `backend/outputs/eval/` (and optionally `backend/outputs/plots/`). See `RUN.md` for more detail and troubleshooting.
257
+
258
+ ---
259
+
260
+ ## 9. Repository Structure
261
+
262
+ ```text
263
+ Haramguard 2/
264
+ ├── README.md
265
+ ├── README_OLD.md
266
+ ├── README_NEW.md
267
+ ├── RUN.md
268
+ ├── ITERATIVE_IMPROVEMENT2.md
269
+ ├── changes.md
270
+ ├── ethics_and_safety_report.txt
271
+ ├── backend/
272
+ │ ├── README.md
273
+ │ ├── config.py
274
+ │ ├── requirements.txt
275
+ │ ├── api.py
276
+ │ ├── pipeline.py
277
+ │ ├── evaluation.py
278
+ │ ├── dashboard.py
279
+ │ ├── core/
280
+ │ │ ├── __init__.py
281
+ │ │ ├── models.py
282
+ │ │ └── database.py
283
+ │ ├── agents/
284
+ │ │ ├── __init__.py
285
+ │ │ ├── perception_agent.py
286
+ │ │ ├── risk_agent.py
287
+ │ │ ├── reflection_agent.py
288
+ │ │ ├── operations_agent.py
289
+ │ │ ├── coordinator_agent.py
290
+ │ │ └── vision_count_agent.py
291
+ │ └── outputs/
292
+ │ └── eval/
293
+ │ ├── summary.json
294
+ │ ├── full_results.json
295
+ │ └── evalResults.md
296
+ └── frontend/
297
+ ├── package.json
298
+ ├── package-lock.json
299
+ ├── index.html
300
+ ├── vite.config.js
301
+ ├── tailwind.config.js
302
+ ├── postcss.config.js
303
+ ├── .env
304
+ ├── STATE_REFERENCE.md
305
+ ├── src/
306
+ │ ├── main.jsx
307
+ │ ├── App.jsx
308
+ │ ├── index.css
309
+ │ ├── pages/
310
+ │ │ └── Dashboard.jsx
311
+ │ ├── Fin.svg
312
+ │ └── kaaba.svg
313
+ └── dist/
314
+ ├── index.html
315
+ └── assets/
316
+ ```
317
+
318
+ ---
319
+
320
+ ## 10. Iterative Improvements
321
+
322
+ HaramGuard was developed through **14 documented iterations**, each addressing a measured problem with a verifiable before/after result. The first 10 iterations are documented in `ITERATIVE_IMPROVEMENT2.md`; the following 4 are documented in `changes.md`.
323
+
324
+ ### Summary Table
325
+
326
+ | # | Title | Problem | Before | After |
327
+ |---|-------|---------|--------|-------|
328
+ | 1 | YOLO Model Upgrade | nano model detected 3–4 persons on 30+ person frames | ~10% recall | ~85% recall (~8× improvement) |
329
+ | 2 | Count-Based Risk Scoring | Density-based formula: HIGH risk mathematically unreachable on aerial cameras | Scene C accuracy: 0% | Scene C accuracy: 100% |
330
+ | 3 | ReflectionAgent Added | 30-frame sliding window caused 20+ frame blind spot during rapid escalation | Uncorrected bias | 5/5 bias detectors passing |
331
+ | 4 | Risk–Priority Threshold Alignment | HIGH risk (score 0.66) incorrectly received P1 instead of P0 | Risk→Priority alignment: ~75% | 100% alignment |
332
+ | 5 | Hybrid PerceptionAgent (YOLO + Claude Vision) | Dense crowd under-count due to white ihram occlusion | 3–4 persons detected | Matches ground truth |
333
+ | 6 | Modular Architecture | Entire system in one notebook — untestable, unconfigurable | 0 isolated tests | 6 independent agent modules |
334
+ | 7 | SQLite Audit Trail | Reflection corrections lost after session — no auditability | Console logs only | Full SQLite history |
335
+ | 8 | Evaluation Framework | No systematic metrics — manual testing only | Manual testing | 8 quantified metrics, 4 scenarios |
336
+ | 9 | Condition-Based Risk Factors | High compression + clustering still reported LOW risk | Compression undetected | Compression/clustering detected |
337
+ | 10 | Weight Recalibration | Condition factors weakened the primary count signal | System accuracy: 50% (2/4) | System accuracy: 75% (3/4) |
338
+ | 11 | Risk Index Direction Fix | 17 persons + shrinking crowd → 82% risk (peak window bug) | window_peak = max(counts) | current_count EMA — risk falls with crowd |
339
+ | 12 | Trend Score Bidirectionality | t_score always ≥ 0.4 even during rapid crowd decrease | Decreasing crowd added constant risk | t_score = 0.0 when crowd shrinking fast |
340
+ | 13 | Arabic UI & Decision Log | English-only labels; decisions replaced on each poll | English labels, lost history | Arabic labels (منخفض/متوسط/عالي), cumulative log |
341
+ | 14 | Clean Dashboard State | FALLBACK_STATE showed fake HIGH emergency on load | Fake P0 alert on startup | ZERO_STATE — clean until real data arrives |
342
+
343
+ ### Key Iterations in Detail
344
+
345
+ **Iteration 2 — Count-Based Scoring (most critical architectural fix)**
346
+
347
+ The original formula computed pixel density: `persons / (frame_pixels / 10,000)`. For a 1920×1080 aerial frame (~2M pixels), even 100 persons yields density = 0.5, far below the HIGH threshold of 20. The system was architecturally incapable of ever reporting HIGH risk. Replacing the primary signal with absolute person count normalized to a Hajj-calibrated threshold of 50 persons brought Scene C accuracy from 0% to 100%.
348
+
349
+ **Iteration 4 — Threshold Alignment (critical safety fix)**
350
+
351
+ RiskAgent labeled scores ≥ 0.65 as HIGH, but OperationsAgent only issued P0 for scores ≥ 0.70. A score of 0.66 — a genuine HIGH emergency — would receive P1 (routine monitoring) instead of P0 (immediate response). Aligning both thresholds to 0.65/0.35 in `config.py` fixed this safety gap and brought Risk→Priority alignment to 100%.
352
+
353
+ **Iteration 11 — Risk Index Direction Fix**
354
+
355
+ The EMA was computed using `max(counts)` over the last window, causing the risk to remain inflated long after the crowd had dispersed. Example: 70 persons 15 frames ago but only 17 now → 82% risk. Switching to `current_count` as the EMA input allows risk to decrease in proportion to the actual crowd, while the EMA still smooths out frame-to-frame noise.
356
+
357
+ **Iteration 14 — Clean Dashboard State**
358
+
359
+ `FALLBACK_STATE` was a hardcoded demo object showing a fake P0 HIGH emergency, designed for UI screenshots. It was left in production code and flashed on screen before the backend connected — showing operators a false emergency every time the dashboard loaded. Replacing it with `ZERO_STATE` (all zeros, LOW level, empty arrays) ensures the dashboard starts clean.
360
+
361
+ ---
362
+
363
+ ## 11. Ethics & Safety
364
+
365
+ ### 11.1 Human-in-the-Loop Design
366
+
367
+ HaramGuard is a decision-support system, not an autonomous enforcement system. Every output is a recommendation to a human operator — no gate opens, no security is dispatched, no PA broadcast is made without a human approving the action. This design aligns with the Islamic principle of consultation (Shura) and with due diligence in decisions that affect the lives of millions of pilgrims.
368
+
369
+ ### 11.2 Privacy & Surveillance
370
+
371
+ HaramGuard processes crowd count data only — not individual identities.
372
+
373
+ - No facial recognition is performed
374
+ - No biometric data is stored
375
+ - YOLO detects person bounding boxes (anonymous blobs only)
376
+ - Claude Vision counts persons without identification
377
+ - SQLite stores: risk scores, counts, timestamps — **no personal data**
378
+
379
+ None of the database tables (`risk_events`, `op_decisions`, `coordinator_plans`, `reflection_log`) contain personally identifiable information (PII). Bounding box data is discarded after spacing calculation and tracking IDs are not persisted.
380
+
381
+ ### 11.3 Fairness & Bias
382
+
383
+ YOLO models trained on general datasets may under-detect pilgrims in white ihram clothing (domain shift). Two mitigations are implemented:
384
+
385
+ - **VisionCountAgent** (Claude Vision) provides a context-aware second counting layer that understands "pilgrims in white garments"
386
+ - **ReflectionAgent** detects chronic under-counting (CHRONIC_LOW_BIAS) and corrects upward, preventing model bias from causing under-response
387
+
388
+ Residual risk: under-count in extreme occlusion remains possible and is documented in `evaluation.py` Section 6 as a known limitation.
389
+
390
+ ### 11.4 Transparency & Explainability
391
+
392
+ Every decision in HaramGuard is logged with human-readable reasoning:
393
+
394
+ - **RiskAgent:** logs risk_score, trend, window_avg
395
+ - **ReflectionAgent:** logs critique text explaining why bias was detected (e.g. `"RISING_TREND_IGNORED: trend=rising, persons=25, but risk=LOW. Upgraded to MEDIUM."`)
396
+ - **OperationsAgent:** logs which playbook actions were triggered and why
397
+ - **CoordinatorAgent:** logs GPT confidence score and any guardrail corrections applied
398
+
399
+ Operators can audit every decision post-incident by querying the SQLite database.
400
+
401
+ ### 11.5 Conservative Bias by Design
402
+
403
+ The system is deliberately tuned to err toward higher risk:
404
+
405
+ - `HIGH_COUNT = 50` (not 100) — triggers HIGH alert at moderate crowd sizes
406
+ - ReflectionAgent corrections always go **upward** — never downgrade an assessment
407
+ - Missing confidence score defaults to 0.5 (not 0)
408
+
409
+ Rationale: in crowd safety, a false alarm is far less costly than a missed stampede.
410
+
411
+ ### 11.6 Potential Misuse Scenarios
412
+
413
+ | Scenario | Risk | Mitigation |
414
+ |----------|------|------------|
415
+ | Surveillance creep | System extended to track individuals | Bounding boxes discarded after use; no tracking IDs in DB; Vision prompt states "count only — do not identify" |
416
+ | False positive causing panic | Incorrect HIGH alert triggers overreaction | HITL design; ReflectionAgent monitors for oscillation; 30-frame window smooths spikes; P0 rate limiting |
417
+ | System failure during peak crowd | Pipeline crash → operators lose visibility | Fail-safe per-agent isolation; operators trained to treat silence as trigger for manual monitoring |
418
+ | Adversarial prompt injection | Malicious input manipulates LLM output | Structured JSON-only output; GR-C1–C5 guardrails validate every field; threat_level constrained to whitelist |
419
+ | Disproportionate security response | P0 triggers aggressive enforcement harming pilgrims | Playbook actions are crowd-management only (open gates, PA broadcast, crowd guides) — not enforcement; human operator has final authority |
420
+
421
+ ### 11.7 Fail-Safe Behavior
422
+
423
+ If any agent fails, the pipeline continues with safe defaults:
424
+
425
+ - **PerceptionAgent fails** → returns empty FrameResult (count=0)
426
+ - **RiskAgent fails** → previous risk level is retained
427
+ - **VisionCountAgent fails** → falls back to YOLO count (logged in flags)
428
+ - **CoordinatorAgent fails** → P0 decision still issued without GPT plan
429
+ - **DB write fails** → logged to console, pipeline continues
430
+
431
+ No single point of failure can silence an alert.
432
+
433
+ ---
434
+
435
+ ## 12. Limitations & Future Work
436
+
437
+ - **Single-camera, single-zone:** The pipeline processes one video stream per instance. Real deployment at the Grand Mosque would require multiple cameras and zones. Future work: multi-zone state and one pipeline per camera with aggregation at the API or dashboard layer.
438
+
439
+ - **Synthetic-only evaluation:** Quantitative metrics in `evaluation.py` are computed on synthetically generated scenarios with known ground-truth counts. Real aerial footage has occlusion, blur, and lighting conditions not fully captured. Future work: annotate real frames and measure real-world accuracy and recall.
440
+
441
+ - **No Hajj-specific fine-tuning:** The YOLO model is pre-trained on general datasets. Pilgrims in white ihram can be under-detected (domain shift). VisionCountAgent and ReflectionAgent mitigate this in part when enabled. Future work: fine-tune a detector on Hajj-annotated data to improve recall (estimated +15%).
442
+
443
+ - **Coordinator output quality not automatically measured:** Evaluation covers risk levels, priorities, and guardrail compliance — not the appropriateness or clarity of generated Arabic plans and alerts. Future work: human-expert rubric and sample-based evaluation of plan quality.
444
+
445
+ - **Production scaling:** The architecture supports running multiple pipeline instances; the dashboard and API would need to be extended for per-zone or per-camera state and approve/reject controls per zone.
446
+
447
+ ---
448
+
449
+ **HaramGuard — Capstone Project · Tuwaiq Academy**
ethics_and_safety_report.txt ADDED
@@ -0,0 +1,287 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ ╔══════════════════════════════════════════════════════════════════╗
3
+ ║ HaramGuard — Ethics, Safety & Guardrails Report ║
4
+ ╚══════════════════════════════════════════════════════════════════╝
5
+
6
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
7
+ SECTION 1 — ETHICAL CONSIDERATIONS
8
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
9
+
10
+ 1.1 Human-in-the-Loop (HITL) Design
11
+ ─────────────────────────────────────
12
+ HaramGuard is a DECISION-SUPPORT system, not an autonomous enforcement
13
+ system. Every output is a recommendation to human operators.
14
+
15
+ OperationsAgent → emits action list (P0/P1/P2)
16
+ CoordinatorAgent → produces Arabic alert text
17
+ Human operator → decides whether to execute
18
+
19
+ No gate opens, no security is dispatched, no PA broadcasts without
20
+ a human approving the action. The system informs — humans decide.
21
+
22
+ Justification: Crowd management decisions affect thousands of pilgrims.
23
+ Automated enforcement without human review violates Islamic ethics of
24
+ consultation (Shura) and due diligence in decisions affecting lives.
25
+
26
+
27
+ 1.2 Privacy & Surveillance
28
+ ────────────────────────────
29
+ HaramGuard processes crowd COUNT data only — not individual identities.
30
+
31
+ - No facial recognition is performed
32
+ - No biometric data is stored
33
+ - YOLO detects person bounding boxes (anonymous blobs)
34
+ - Claude Vision counts persons (no identification)
35
+ - SQLite stores: risk scores, counts, timestamps — NO personal data
36
+
37
+ Stored data schema:
38
+ risk_events → frame_id, risk_score, risk_level, trend
39
+ op_decisions → priority, actions, risk_score
40
+ coordinator_plans → threat_level, arabic_alert, confidence
41
+ reflection_log → bias corrections, scores
42
+
43
+ None of these tables contain personally identifiable information (PII).
44
+
45
+
46
+ 1.3 Fairness & Bias
47
+ ─────────────────────
48
+ Potential bias: YOLO models trained on general datasets may under-detect
49
+ pilgrims in white ihram clothing (domain shift).
50
+
51
+ Mitigation implemented:
52
+ - VisionCountAgent (Claude Vision) provides a second counting layer
53
+ that is context-aware and understands "pilgrims in white garments"
54
+ - ReflectionAgent detects chronic under-counting (CHRONIC_LOW_BIAS)
55
+ and corrects upward — preventing bias from causing under-response
56
+
57
+ Residual risk: Model may still under-count in extreme occlusion.
58
+ Documented in evaluation.py Section 6 (Known Limitations).
59
+
60
+
61
+ 1.4 Transparency & Explainability
62
+ ────────────────────────────────────
63
+ Every decision in HaramGuard is logged with reasoning:
64
+
65
+ RiskAgent: logs risk_score, trend, window_avg — human-readable
66
+ ReflectionAgent: logs critique text explaining why bias was detected
67
+ OperationsAgent: logs which playbook actions were triggered and why
68
+ CoordinatorAgent: logs GPT-4o confidence score + guardrail issues
69
+
70
+ Example reflection log entry:
71
+ "RISING_TREND_IGNORED: trend=rising, persons=25, but risk=LOW.
72
+ Upgraded to MEDIUM."
73
+
74
+ Operators can audit every decision post-incident.
75
+
76
+
77
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
78
+ SECTION 2 — SYSTEM SAFETY
79
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
80
+
81
+ 2.1 Fail-Safe Behavior
82
+ ────────────────────────
83
+ If any agent fails, the pipeline continues with safe defaults:
84
+
85
+ PerceptionAgent fails → returns empty FrameResult (count=0)
86
+ RiskAgent fails → previous risk level is retained
87
+ VisionCountAgent fails → falls back to YOLO count (logged in flags)
88
+ CoordinatorAgent fails → P0 decision still issued without GPT plan
89
+ DB write fails → logged to console, pipeline continues
90
+
91
+ No single point of failure can silence an alert.
92
+
93
+
94
+ 2.2 Conservative Bias by Design
95
+ ──────────────────────────────────
96
+ The system is deliberately tuned to err toward HIGHER risk:
97
+
98
+ HIGH_COUNT = 50 (not 100) — triggers HIGH alert at moderate crowds
99
+ ReflectionAgent corrections always go UPWARD (never downgrade)
100
+ Missing confidence → defaults to 0.5 (not 0)
101
+
102
+ Rationale: In crowd safety, a false alarm is far less costly than a
103
+ missed stampede. The system is asymmetrically cautious.
104
+
105
+
106
+ 2.3 Rate Limiting as Safety Mechanism
107
+ ────────────────────────────────────────
108
+ P0 alerts are rate-limited to 1 per 5 minutes per zone (OPS_RATE_LIMIT_SEC=300).
109
+
110
+ Purpose: Prevents alert fatigue. If operators receive P0 every 10 seconds,
111
+ they stop responding. Rate limiting ensures each P0 is taken seriously.
112
+
113
+ This is a safety feature, not a suppression feature — the underlying
114
+ risk is still tracked and logged even when alerts are suppressed.
115
+
116
+
117
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
118
+ SECTION 3 — POTENTIAL MISUSE SCENARIOS
119
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
120
+
121
+ Scenario 1: Surveillance Creep
122
+ ────────────────────────────────
123
+ Risk: System extended to track individuals, not just crowds.
124
+ Impact: Privacy violation, chilling effect on religious practice.
125
+ Mitigation:
126
+ - Code explicitly discards bounding box data after spacing calculation
127
+ - No tracking IDs are persisted to DB
128
+ - Vision prompt explicitly states "count only — do not identify"
129
+ - Data retention policy: DB rows contain no PII by design
130
+
131
+
132
+ Scenario 2: False Positive Causing Panic
133
+ ──────────────────────────────────────────
134
+ Risk: System triggers HIGH alert incorrectly, security overreacts,
135
+ causing the very stampede it was meant to prevent.
136
+ Impact: Physical harm to pilgrims.
137
+ Mitigation:
138
+ - HITL design: human operator approves all P0 actions
139
+ - ReflectionAgent monitors for oscillation and bias
140
+ - 30-frame sliding window smooths single-frame spikes
141
+ - P0 rate limiting prevents cascading false alarms
142
+
143
+
144
+ Scenario 3: System Failure During Peak Crowd
145
+ ──────────────────────────────────────────────
146
+ Risk: Pipeline crashes during Tawaf peak hours, operators lose
147
+ visibility entirely.
148
+ Impact: No alerts, potential missed stampede event.
149
+ Mitigation:
150
+ - Fail-safe design: each agent failure is isolated
151
+ - DB is written every 30 frames — worst case 1 second of lost data
152
+ - Operators are trained to treat system silence as a trigger to
153
+ switch to manual monitoring protocols
154
+
155
+
156
+ Scenario 4: Adversarial Prompt Injection (CoordinatorAgent)
157
+ ─────────────────────────────────────────────────────────────
158
+ Risk: Attacker manipulates input data to inject malicious instructions
159
+ into the GPT-4o prompt.
160
+ Impact: Fabricated alerts, incorrect actions.
161
+ Mitigation:
162
+ - CoordinatorAgent prompt uses structured JSON-only output
163
+ - GR-C1..5 guardrails validate every field of the response
164
+ - threat_level constrained to whitelist: {CRITICAL, HIGH, MEDIUM, LOW}
165
+ - Consistency check: low risk_score cannot produce CRITICAL threat
166
+ - _guardrail_issues logged for every correction
167
+
168
+
169
+ Scenario 5: Disproportionate Security Response
170
+ ────────────────────────────────────────────────
171
+ Risk: P0 alert triggers aggressive security deployment that harms
172
+ pilgrims rather than protecting them.
173
+ Impact: Physical harm, violation of dignity of worshippers.
174
+ Mitigation:
175
+ - Playbook actions are crowd management actions, not enforcement:
176
+ P0: open gates, PA broadcast, dispatch crowd guides
177
+ (NOT: lockdown, force dispersal, barriers that trap people)
178
+ - Human operator has final authority on response type
179
+ - System recommends — operators decide magnitude of response
180
+
181
+
182
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
183
+ SECTION 4 — GUARDRAILS: IMPLEMENTATION & JUSTIFICATION
184
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
185
+
186
+ ┌─────┬──────────────────────┬────────────────────────────────────────┐
187
+ │ ID │ Agent │ Guardrail │
188
+ ├─────┼──────────────────────┼────────────────────────────────────────┤
189
+ │ GR1 │ PerceptionAgent │ Person count capped at MAX_PERSONS=1000│
190
+ │ │ │ Justification: YOLO occasionally hallu-│
191
+ │ │ │ cinates thousands of detections on busy │
192
+ │ │ │ textures. Cap prevents impossible counts│
193
+ │ │ │ from propagating to risk score. │
194
+ ├─────┼──────────────────────┼────────────────────────────────────────┤
195
+ │ GR2 │ PerceptionAgent │ Density score capped at MAX_DENSITY=50 │
196
+ │ │ │ Justification: Density formula can │
197
+ │ │ │ overflow on small frames. Cap ensures │
198
+ │ │ │ score stays in interpretable range. │
199
+ ├─────┼──────────────────────┼────────────────────────────────────────┤
200
+ │ GR3 │ RiskAgent │ Risk score clamped to [0.0, 1.0] │
201
+ │ │ │ Justification: Weighted sum of 3 scores│
202
+ │ │ │ could theoretically exceed 1.0 due to │
203
+ │ │ │ floating point. Clamp ensures all │
204
+ │ │ │ downstream thresholds remain valid. │
205
+ ├─────┼──────────────────────┼────────────────────────────────────────┤
206
+ │ GR4 │ OperationsAgent │ P0 rate-limited: 1 per 5 min per zone │
207
+ │ │ │ Justification: Alert fatigue is a real │
208
+ │ │ │ safety hazard. Operators who see 20 P0 │
209
+ │ │ │ alerts/hour begin ignoring them. │
210
+ ├─────┼──────────────────────┼────────────────────────────────────────┤
211
+ │GR-C1│ CoordinatorAgent │ Required JSON fields enforced │
212
+ │ │ │ Justification: LLMs occasionally omit │
213
+ │ │ │ fields. Missing arabic_alert or │
214
+ │ │ │ threat_level would break the dashboard.│
215
+ ├─────┼──────────────────────┼────────────────────────────────────────┤
216
+ │GR-C2│ CoordinatorAgent │ threat_level whitelist enforced │
217
+ │ │ │ Justification: Prevents GPT-4o from │
218
+ │ │ │ returning values like "EXTREME" or │
219
+ │ │ │ "UNKNOWN" that break downstream logic. │
220
+ ├─────┼──────────────────────┼────────────────────────────────────────┤
221
+ │GR-C3│ CoordinatorAgent │ confidence_score validated in [0,1] │
222
+ │ │ │ Justification: LLMs sometimes return │
223
+ │ │ │ confidence as percentage (85 vs 0.85). │
224
+ ├─────┼──────────────────────┼────────────────────────────────────────┤
225
+ │GR-C4│ CoordinatorAgent │ Consistency: low risk ≠ CRITICAL threat│
226
+ │ │ │ Justification: Prevents hallucinated │
227
+ │ │ │ CRITICAL alerts when risk_score < 0.4. │
228
+ │ │ │ Cross-validates LLM output with agent │
229
+ │ │ │ computed score. │
230
+ ├─────┼──────────────────────┼────────────────────────────────────────┤
231
+ │GR-C5│ CoordinatorAgent │ Arabic alert fallback if empty │
232
+ │ │ │ Justification: Arabic alert is │
233
+ │ │ │ safety-critical. Empty string on │
234
+ │ │ │ dashboard during P0 is unacceptable. │
235
+ ├─────┼──────────────────────┼────────────────────────────────────────┤
236
+ │ RF1 │ ReflectionAgent │ Chronic LOW bias detection │
237
+ │ │ │ Justification: Sliding window lag can │
238
+ │ │ │ cause 20+ frames of LOW during rapid │
239
+ │ │ │ escalation. This guardrail prevents │
240
+ │ │ │ the system from missing an emergency. │
241
+ ├─────┼──────────────────────┼────────────────────────────────────────┤
242
+ │ RF2 │ ReflectionAgent │ Rising trend + LOW = upgrade to MEDIUM │
243
+ │ │ │ Justification: A rising crowd with LOW │
244
+ │ │ │ risk is a contradictory state that │
245
+ │ │ │ indicates calibration failure. │
246
+ ├─────┼──────────────────────┼────────────────────────────────────────┤
247
+ │ RF3 │ ReflectionAgent │ Count-risk mismatch: 80+ persons + LOW │
248
+ │ │ │ Justification: Absolute count override │
249
+ │ │ │ ensures mathematical impossibilities │
250
+ │ │ │ (80 people = LOW risk) are corrected. │
251
+ └─────┴──────────────────────┴────────────────────────────────────────┘
252
+
253
+ Total: 12 guardrails across 4 agents
254
+ Each guardrail: implemented in code + justified architecturally
255
+
256
+
257
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
258
+ SECTION 5 — EVALUATION SUMMARY (Rubric Checklist)
259
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
260
+
261
+ ✅ End-to-end performance metrics → evaluation.py Section 5
262
+ 75-100% system accuracy across 4 synthetic scenarios
263
+ 139 fps average throughput
264
+
265
+ ✅ Component-level evaluation → evaluation.py Sections 1-4
266
+ PerceptionAgent, RiskAgent, ReflectionAgent, OperationsAgent
267
+ each evaluated independently with unit tests
268
+
269
+ ✅ Error analysis methodology → evaluation.py Section 6
270
+ Convergence speed, oscillation rate, FP rate, 5 known limitations
271
+ each with documented mitigation
272
+
273
+ ✅ Evidence of iterative improvement → evaluation.py Section 7
274
+ 4 documented iterations (v1→v2→v3→v4→v5)
275
+ each with before/after measurable metric
276
+
277
+ ✅ Ethical considerations → this file Section 1
278
+ HITL design, privacy-by-design, fairness, transparency
279
+
280
+ ✅ System safety → this file Section 2
281
+ Fail-safe behavior, conservative bias, rate limiting
282
+
283
+ ✅ Potential misuse scenarios → this file Section 3
284
+ 5 scenarios with impact assessment and mitigation
285
+
286
+ ✅ Guardrails implemented & justified → this file Section 4
287
+ 12 guardrails, each with implementation + architectural justification