move_detect/docs/superpowers/specs/2026-07-11-workplace-safety-ai-cctv-design.md
유창욱 a4f2ead211 docs: workplace safety AI CCTV design spec v2.0 + P1-A edge core plan
- 설계 스펙 v2.0 (다관점 리뷰 반영: 기절경로 분리, 시점강건 낙상, 인증/RBAC, 평가셋, fps 3티어, 컴플라이언스, 증거 무결성)
- P1-A 엣지 감지 코어 구현계획 (16 태스크 TDD)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ne4rU4FToTLHcBUMUvUnT1
2026-07-11 20:08:01 +09:00

456 lines
36 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 작업장 안전관리 AI CCTV — 설계 문서 (Design Spec)
- **문서 버전:** 2.0 (다관점 리뷰 반영 개정)
- **작성일:** 2026-07-11
- **코드명:** `move_detect`
- **상태:** 설계 확정 대기(사용자 리뷰 전)
> **v2.0 변경 요약:** 5개 렌즈(산업안전·엣지CV·운영UX·보안/개인정보·제품/배포) 다관점 리뷰 결과 반영.
> 핵심: (1) 기절 감지를 낙상 경로에서 **분리**(자세무관 부동 워치독 + 트랙소실 유령사고), (2) 시점/노이즈 강건 낙상(OR로직·공간바인딩·지터스무딩), (3) 대시보드 **인증/RBAC** 및 ingest/저장 하드닝, (4) **라벨 평가셋 + 드릴 커미셔닝 게이트**, (5) **fps 3티어 폴백**, (6) **PIPA·노사협의회 컴플라이언스 제품 내장**, (7) 증거 무결성(계층 보존·legal-hold·audit).
> **사용자 결정:** 호스팅 = Cafe24 유지(내부 하드닝) · v1+끼임 body-part(P2) · 라이브뷰 폐기(스냅샷 절대) · 컴플라이언스 제품 소유.
---
## 1. 개념 (Concept)
> Raspberry Pi 5 + AI HAT+ (Hailo-8, 26 TOPS)가 작업장 카메라 영상을 **실시간 자세추정(pose estimation)**으로 분석해, **넘어짐·미동/기절·위험구역 침입(+끼임)** 사고를 판단하고, 사고 순간 스냅샷과 함께 Cafe24 PHP 관제 대시보드로 즉시 경보하는 엣지 AI CCTV. 감지에 그치지 않고 **응답(에스컬레이션·119)·측정(정확도)·합법(컴플라이언스)·증거보존**까지 책임지는 안전관리 제품.
핵심 철학:
- **무거운 AI 판단은 전부 엣지(Pi)에서.** 클라우드는 얇게 — 수신·저장·표시·발송·대응관리.
- **영상 스트림/라이브뷰를 절대 내보내지 않는다.** 개인정보·대역폭 이유로 사고 순간 **정지 스냅샷만** (라이브뷰·클립 없음, 사용자 결정).
- **오탐(FP)은 안전 시스템에서 치명적.** 자세추정으로 앉음/숙임/의도적 눕기와 실제 낙상을 구분한다.
- **미탐(FN)은 더 치명적.** 가장 위험한 케이스(좌위 실신·가림 붕괴)에서 경보가 나가도록 설계한다.
- **감지≠안전.** 응답자에게 닿고, 정확도를 측정·튜닝하고, 법적 증거로 남아야 안전이 완성된다.
---
## 2. 범위 (Scope)
### 2.1 목표 (In scope)
- 사고 감지: 넘어짐, 넘어짐 후 장시간 미동(기절 의심), **자세무관 장시간 부동**, 위험구역 침입(2단계), **끼임 body-part 침입(P2)**.
- 1대의 Pi가 2~4대 카메라(CSI + USB UVC 혼합) 동시 처리, **fps 3티어 폴백**으로 우아한 저하.
- 사고 시 스냅샷 1~3장(사고 前/中/後, 링버퍼) + 메타데이터를 Cafe24 PHP로 HTTPS POST(HMAC+nonce).
- PHP 관제 대시보드: **인증/RBAC**, 실시간 사고 목록·상세, 대응 에스컬레이션, 위험구역 설정, 감도 다이얼, 장비/플릿 상태, 이력·통계, 오탐 피드백.
- 대응 계층: 확인 SLA·에스컬레이션 사다리·온콜 라우팅·119 안내 카드.
- 컴플라이언스 모듈(**제품 소유**): 노사협의회 협의 기록, PIPA 안내판/처리방침 메타, DPIA 체크리스트 게이트, 데이터주체 조회/삭제 도구, **배경인물 얼굴블러 default-ON**.
- 증거: 계층형 보존 + legal-hold(실사고 3~5년), 위변조방지 audit 로그, 서버 신뢰 타임스탬프.
- (선택) 위급 시 SMS(기존 `leak_sms` 게이트 재사용), 현장 GPIO 경보(경광등/부저).
### 2.2 비목표 (Out of scope, YAGNI)
- **라이브뷰·영상클립·상시 녹화·클라우드 스트리밍** — 절대 미포함(사용자 결정, no-streaming 원칙 고수).
- 얼굴 **인식**/개인 식별 — 미포함. (단 배경인물 **탐지-후-블러**는 최소화 요건으로 포함; 식별 아님)
- 실외·야간·IR 환경 — 대상은 **실내 공장/창고, 주간 조명**. (조명꺼짐은 `monitoring_degraded`로 처리)
- 떨어짐(추락)·부딪힘(차량)·밀폐공간 질식·화재/가스 — v1 미포함, 외부센서/별도클래스 필요 → P4 범위 결정(§16).
- 기계 비상정지(E-stop) **능동 개입** — 안전PLC 인증·책임 이슈로 v1 미포함, 훅만 설계(§16 미결정).
- 시간축 딥러닝 행동인식(ST-GCN) — v1은 자세 휴리스틱. 오탐 과다 시 P4 재검토.
- 대규모 온사이트 다중 Pi 집계 서버 — P4. (단 **경량 멀티사이트 플릿 레지스트리는 P2**로 포함 — 클라우드가 이미 device_id 키 기반)
### 2.3 컴플라이언스 (제품 소유 — v1 In scope)
v1.0에서 "운영정책, 범위밖"으로 뺐던 항목을 **제품 기능으로 내장**한다(사용자 결정, 차별화). 이는 배포의 법적 전제:
- **근로자참여법 §20-14:** 감시장비 설치는 노사협의회 **필수 협의 사항** → 협의 기록(일자·안건·근로자대표 서명) 관리 기능.
- **PIPA §25:** 영상정보처리기기 안내판, 운영·관리방침, 목적 제한(근태감시 전용(轉用) 차단), 데이터주체 조회/삭제 권리 도구.
- 낙상/실신 영상은 **민감정보 소지** → 최소수집·접근통제·접근로그.
- 배포 전 **DPIA 체크리스트 게이트**.
---
## 3. 요구사항 (Requirements)
### 3.1 기능 요구사항
| ID | 요구사항 | 단계 |
|----|----------|------|
| F1 | 사람이 넘어져 완전히 넘어진 자세(prone)가 > 3초 지속되면 넘어짐 이벤트를 발생시킨다. | P1 |
| F2 | 넘어짐 상태에서 관절 움직임이 임계 미만으로 ≥10초 지속되면 "위급(기절 의심)" 최고등급 경보를 발생시킨다. | P1 |
| F3 | 스스로 일어나면(자세 복원) 넘어짐/미동 경보를 취소·하향한다. | P1 |
| **F3b** | **낙상 전이 없이도** 추적 중인 사람이 자세와 무관하게 관절변위 임계 미만으로 N초(좌위 기본 90~180초, 위험구역 더 짧게) 지속되면 "이상 정지" 저·중등급 확인 경보를 발생시킨다. | **P1** |
| **F3c** | FALLING/FALLEN/NO_MOTION 트랙이 복원 확인 없이 **사라지면**(가림) 마지막 위치에 공간 "유령사고"를 만들고, T초 내 인근에 트랙 재출현 없으면 상향한다. | **P1** |
| F4 | 카메라별 위험구역 폴리곤(2단계: 경고/절대금지)에 사람 발끝이 진입하면 침입 이벤트를 발생시킨다. | P1 |
| **F4b** | 기계 위험점 구역에 대해 **임의 신체 관절점** 진입(발목만 아님)으로 끼임 위험을 판정한다. | **P2** |
| F5 | 모든 이벤트는 (트랙ID 또는 공간영역) 기준 1회 발생 + 쿨다운으로 반복 폭탄을 방지한다. | P1 |
| F6 | 이벤트 시 스냅샷 1~3장(前/中/後, 링버퍼) + 메타데이터를 Cafe24로 전송한다. | P1 |
| F7 | 관리자는 **인증 후** 실시간 사고 목록·상세를 보고, 위험구역을 그리고, 감도를 조정하고, 이력·통계를 조회한다. | P1 |
| F8 | 전송 실패 시 로컬 큐잉 후 재전송하여 사고를 유실하지 않는다. | P1 |
| **F9** | 미확인 위급 경보는 확인 SLA 초과 시 2·3차 온콜로 자동 에스컬레이션한다. | P3(위급 최소본 P1) |
| **F10** | 이벤트 처리결과(실제/오탐/현장처리/드릴/검토요)를 라벨링하고, 온디바이스 키포인트 시계열로 재생·튜닝한다. | P2 |
| **F11** | 임계값을 (device, camera, zone)별로 오버라이드하고, 관리자용 감도 프리셋(Conservative↔Aggressive)으로 노출한다. | P2 |
| **F12** | 카메라 가림/초점흐림/조명꺼짐/탬퍼를 self-check해 `monitoring_degraded`를 발생시킨다. | P2 |
| **F13** | 실사고로 분류된 건은 legal-hold로 자동만료에서 제외하고 증거묶음을 내보낸다. | P3 |
| **F14** | 컴플라이언스: 노사협의회 기록·안내판메타·DPIA·데이터주체 도구·얼굴블러를 제공한다. | P1 |
| **F15** | "현재 프레임 캡처" 명령으로 이벤트 전에도 구역 그리기·커미셔닝·탬퍼 기준 스냅샷을 얻는다. | P1 |
### 3.2 비기능 요구사항
| ID | 요구사항 |
|----|----------|
| NF1 | 낙상 중요 카메라 유효 **≥12~15 fps**, 저위험 8~10 fps. fps 티어별 보장. |
| NF2 | 사고 발생→대시보드 표시 지연 **≤ 5초**(정상 네트워크). 위급 확인 SLA 별도(§8). |
| NF3 | Pi 소프트웨어 **오프라인 설치**(모든 `.hef`·의존성 사전 번들; 폐쇄망). 업데이트는 **서명 검증 오프라인 번들**. |
| NF4 | 파이프라인 멈춤/카메라 끊김/가림 자동 복구·감지(워치독·재연결·self-check). |
| NF5 | POST는 HTTPS + **HMAC + nonce/timestamp(replay 방지) + per-device 키**. |
| NF6 | 보관은 **계층형** + **env 설정**(하드코딩 금지): 일상/오탐 이벤트 보존일·실사고 legal-hold 기간 모두 환경변수. 기본값 TBD(법률 확정 시 조정). |
| NF7 | 대시보드 **인증 필수**(argon2id·세션 하드닝·RBAC·brute-force 잠금). 무인증 접근 0. |
| NF8 | 사고 **정확도 목표**(낙상 recall, 오탐/카메라/일, 에스컬레이션 지연)를 정의하고 커미셔닝에서 검증. |
| NF9 | 심각도는 **색상 단독 금지**(텍스트+아이콘+WCAG-AA+색맹안전). 데스크 오디오·모바일 push. |
| NF10 | 사고 시각은 **신뢰 시간원**(HW RTC + 로컬 NTP) + 서버 received_at 이중기록. |
---
## 4. 아키텍처 (Architecture)
2계층: **엣지(Pi)** 감지·판단·대응트리거, **클라우드(Cafe24)** 수신·인증·표시·대응관리·컴플라이언스.
```
┌──────────── 엣지: Raspberry Pi 5 + AI HAT+ (Hailo-8 26TOPS, PCIe Gen3, HW RTC) ────────────┐
│ │
│ [CSI캠]─(별프로세스)─┐ ┌─▶ EventEngine (상태머신 × 트랙/공간) │
│ [USB캠 MJPEG]────────┼─▶ Capture ─▶ roundrobin ─▶ │ ├ FallDetector (OR로직, 시점강건) │
│ [USB캠 MJPEG]────────┘ (정규화640) hailonet │ ├ ImmobilityWatchdog (자세무관 부동) │
│ (공유 pose, └streamrouter│ ├ GhostIncident (트랙소실 공간사고) │
│ batch≥N) → Tracker │ └ ZoneIntrusion (발끝/body-part) │
│ (ByteTrack └────────────┬──────────────────────────┤
│ +공간바인딩, │ │
│ 지터스무딩) RingBuffer(前/中/後 프레임) │
│ │ ▼ │ │
│ Snapshotter+FaceBlur Alerter(POST+GPIO) │
│ │ │ │ │
│ LocalQueue◀─재시도─┘ HealthAgent │
│ (암호화) (하트비트/워치독/ │
│ │ 카메라 self-check)│
│ Config(구역·임계값 per-cam/zone, 동기) │
│ Secrets(TPM/keyring, per-device 키) │
└────────────────────────────────┼───────────────────────────────────────┬───────────────────┘
HTTPS POST(이벤트+JPEG, HMAC+nonce) GPIO │
하트비트(fps·온도·스로틀·큐·config버전) ▼
┌──────────────── 클라우드: Cafe24 웹호스팅 (PHP + MySQL) ─────────────────┐ [경광등/부저]
│ [인증/RBAC] ── 세션하드닝 ── 접근로그 │
│ Ingest API(HMAC+nonce검증, 이미지 재인코딩, rate limit) │
│ │ │
│ MySQL ── 스냅샷은 웹루트 밖 저장 → 인증 PHP 프록시로만 서빙 │
│ ├─ 실시간 관제(사고 목록·상세, 심각도 텍스트+아이콘, 데스크오디오) │
│ ├─ 대응(에스컬레이션 사다리·온콜 로스터·119 카드·NEW→CLAIMED→RESOLVED) │
│ ├─ 위험구역 설정(폴리곤 드로잉) + 감도 다이얼(per-cam/zone) │
│ ├─ 장비/플릿(사이트별, config버전, 온도/스로틀, 카메라 degraded) │
│ ├─ 오탐 피드백(처리결과 라벨·재생·튜닝 제안) │
│ ├─ 이력·통계·KPI + 증거묶음 내보내기(legal-hold, 산업재해조사표) │
│ └─ 컴플라이언스(노사협의회 기록·안내판메타·DPIA·데이터주체·블러정책) │
│ audit 로그(append-only 해시체인: 임계값·조회·내보내기·확인) │
│ SMS 발송(위급, leak_sms 재사용) · Config/구역 동기 API(버전확인) │
│ 모바일 PWA + Web Push (high/warning) · SMS(critical 폴백) │
└────────────────────────────────────────────────────────────────────────────┘
```
### 4.1 단일 공유모델 원칙 (유지)
모든 카메라가 단일 `yolov8s_pose` HEF를 공유하고, 사람 박스·발끝/관절(구역·끼임)·관절 기하(낙상)·관절 변위(미동)를 **같은 pose 출력에서 파생**. 2모델 동시는 컨텍스트스위치 손해라 회피.
---
## 5. 엣지 컴포넌트
| 컴포넌트 | 책임 | 신규/변경 |
|---|---|---|
| **Capture** | CSI=picamera2(카메라당 별 프로세스), USB=v4l2 MJPEG. 640 정규화. "현재프레임 캡처" 명령 지원. | +F15 |
| **Inference** | 공유 `yolov8s_pose` HEF. roundrobin→hailonet(batch≥N)→streamrouter. **fps 3티어**(§10.2). | +티어 |
| **Tracker** | ByteTrack/OC-SORT. **공간(IoU) 바인딩**으로 ID스위치 시 상태·타이머 승계. **per-keypoint One-Euro/Kalman 스무딩**. | 변경 |
| **EventEngine** | 트랙/공간 상태머신 4서브: FallDetector·ImmobilityWatchdog·GhostIncident·ZoneIntrusion(+body-part). | 대폭 |
| **RingBuffer** | 사전 프레임 링버퍼 → 사고 前/中/後 스냅샷 공급. 온디바이스 키포인트 시계열 기록. | 신규 |
| **Snapshotter+FaceBlur** | 링버퍼에서 1~3장 JPEG. **배경인물 얼굴 블러 default-ON**(피재자 제외 옵션). | +블러 |
| **Alerter** | 이벤트+스냅샷 POST(HMAC+nonce). 위급 시 GPIO + SMS 트리거. | +nonce |
| **LocalQueue** | 실패 시 **암호화(LUKS)** SQLite 큐, 백오프 재전송. | +암호화 |
| **Config** | 구역·임계값 **per-(device,camera,zone)** 로컬 관리, 클라우드 동기 + 적용버전 보고. | 변경 |
| **Secrets** | HMAC/SMS 키를 **TPM/keyring**, per-device. 평문파일 금지. | 신규 |
| **HealthAgent** | 하트비트(fps·온도·스로틀·큐깊이·config버전). 프레임정체·카메라끊김 복구. **카메라 가림/초점/조명/탬퍼 self-check → `monitoring_degraded`**. | 대폭 |
---
## 6. 이벤트 판정 로직
모든 픽셀 임계는 **사람 bbox 높이로 정규화**. 단 이는 스케일만 보정 — 렌즈왜곡·마운트유형(탑다운 vs 사각)은 **per-camera 캘리브레이션 프로파일**로 보완(§16 캘리브 도구). 임계는 실장비 튜닝 전 **시작값**, per-cam/zone 조정 가능.
### 6.1 트랙/공간 상태머신 (기절 경로 분리)
```
┌──────────── ImmobilityWatchdog (자세 무관, 독립) ───────────┐
│ 임의 트랙이 관절변위<임계 N초 지속 → "이상정지" 저·중경보 │
└──────────────────────────────────────────────────────────────┘
STANDING/SITTING ──(급격 수직하강 or 낙상 전이)──▶ FALLING ──(prone >3s)──▶ FALLEN
▲ │ │
│(자세복원, F3) │(복원) │(관절변위<임계 ≥10s)
└──────────────────────────────────────────────┴─────────────────────────┤
▼
NO_MOTION (위급/기절)
[임의 상태에서 트랙 소실(복원확인 없이)] ──▶ GhostIncident(마지막 위치) ──(T초 내 미재출현)──▶ 상향
```
- **핵심 변경:** 위급(기절) 경보는 이제 **FALLEN 경로 전용이 아니다.** ImmobilityWatchdog가 자세·트랙연속성과 무관하게 병렬로 돈다. 좌위 실신·기대 슬럼프도 잡힘.
- **incident 활성 중 baseline freeze:** §6.5 재보정이 넘어진 자세를 "정상"으로 재앵커하지 않도록, 임의 incident 상태 동안 정상자세 기준을 동결.
### 6.2 넘어짐 (Fall) — F1, 시점 강건 (OR 로직)
각도 = 몸통(어깨중심→엉덩이중심) 벡터가 수직축과 이루는 각. 서있음≈0°, 누움≈90°.
**FALLING 진입(전이):** 몸통각도 ~45° 상향 돌파 **AND** COM 하강속도·낙차 유의미(10프레임 윈도우, 정규화).
**FALLEN 확정 — 직교 단서 OR 결합(정면/후면 낙상 대응):**
- 다음 중 **하나 이상** 확신 + prone > 3초(20프레임 다수결):
- 몸통각도 수직대비 **> 70°**(측면 낙상), **또는**
- bbox **수직크기(높이) 급붕괴**(정면/후면 낙상 — 각도·종횡비 안 변해도 키가 확 줄음), **또는**
- COM 하강속도 큼 + 바닥권 정지, **또는**
- 머리 y > 엉덩이 y **또는** 종횡비 W/H > 1.25.
- **AND 게이트 폐기 이유:** 카메라 향해/등지고 넘어지면 몸통벡터 단축·종횡비 불변 → v1.0의 AND 조합은 한 방향 통째 미탐이었음.
- 관절 신뢰도 게이트: conf<0.5 폐기, 핵심 4관절 필수, 가시 ≥10.
### 6.3 미동/기절 (No-motion) — F2, F3, F3b
- **낙상 후 미동:** FALLEN 진입 시 타이머, 관절변위<임계 ≥10초 → NO_MOTION 위급(대시보드+SMS+부저).
- **자세무관 부동(F3b):** ImmobilityWatchdog가 임의 트랙에 대해 변위<임계 지속(좌위 90~180초, 위험구역 더 짧게) → 저·중 확인경보 → 미해소 상향.
- **지터 대응:** INT8 pose 관절은 FP보다 노이즈 큼 → per-keypoint 스무딩, 미동 임계 = **측정된 정지지터 + 마진**(무한 미발화 방지).
- 움직임 재개 → 취소·하향. 위급 후 쿨다운.
### 6.4 위험구역 침입 — F4 / 끼임 body-part — F4b(P2)
- **일반 침입(F4):** 발목 관절점 point-in-polygon. 경고구역(노랑)/절대금지(주황+옵션 부저). 디바운스 0.5~1초.
- **끼임 body-part(F4b, P2):** 기계 위험점 구역은 **임의 관절점**(손목·팔꿈치 등) 진입으로 판정. 손/팔이 프레스·롤러 위험점에 들어가는 상황 커버. point-in-polygon 소확장.
- 구역은 대시보드에서 스냅샷 위 폴리곤 드로잉. (E-stop 능동개입은 훅만, §16)
### 6.5 공통 억제 규칙
- (트랙ID 또는 공간영역)당 1회 + 유형별 쿨다운. GhostIncident는 공간영역 기준.
- 저신뢰 검출 판정 제외. **incident 활성 중 baseline 동결**(§6.1).
---
## 7. 클라우드 (Cafe24 PHP + MySQL) — 하드닝
> Cafe24 공유호스팅 유지(사용자 결정). 공유호스팅 한계를 인정하되 **내부 하드닝 최대**로. 스냅샷 웹루트 밖 + 프록시, 인증/RBAC, replay 방지가 필수.
### 7.1 인증 / 접근제어 (신규, P1)
- **로그인 필수**(argon2id, HttpOnly+Secure+SameSite 쿠키, CSRF 토큰, brute-force 잠금, HTTPS/HSTS).
- **RBAC:** admin(설정·임계값·컴플라이언스) / operator(확인·대응) / viewer(조회). 사이트 스코프.
- `acknowledged_by`는 인증 주체에 바인딩. 모든 조회/내보내기 접근로그(PIPA).
### 7.2 화면 (Dashboard)
| 화면 | 기능 |
|---|---|
| **실시간 관제** | 이벤트 실시간 목록, 미확인 상단고정, 심각도 = **텍스트(위급/높음/경고)+아이콘+색(색맹안전)**, **데스크 Web Audio**(위급 반복·무음불가). |
| **사고 상세** | 스냅샷 1~3장(前/中/後), 카메라·시각·구역·트랙ID·지속, 처리결과 라벨(실제/오탐/…), 확인처리(인증). |
| **대응** | 확인 SLA 타이머, 에스컬레이션 사다리(2/3차 온콜·음성콜), 온콜 로스터/교대, **119 카드**(위치도·주소·게이트코드·AED·응급처치), NEW→CLAIMED→RESOLVED. |
| **위험구역 설정** | 최신/현재캡처 스냅샷 위 폴리곤 드래그, 경고/금지/끼임 지정, Pi 동기. |
| **감도** | (device/camera/zone)별 프리셋 Conservative↔Balanced↔Aggressive + 고급 raw 슬라이더. |
| **장비/플릿** | 사이트별 Pi·카메라 상태, config 적용버전(drift 표시), 온도/스로틀/fps, `monitoring_degraded`. |
| **오탐 피드백** | 처리결과 라벨 집계, 키포인트 시계열 재생, 임계 튜닝 제안. |
| **이력·통계** | 날짜·구역·유형 이력, KPI(오탐률·MTTA), 히트맵, **증거묶음 내보내기**(legal-hold, 산업재해조사표 프리필). |
| **컴플라이언스** | 노사협의회 협의 기록, 안내판/처리방침 메타, DPIA 체크리스트, 데이터주체 조회/삭제, 얼굴블러 정책. |
| **모바일** | PWA 반응형 + Web Push(high/warning), SMS(critical 폴백), 딥링크. |
### 7.3 데이터 계약 (Ingest API) — 하드닝
`POST /api/events` (JSON+base64 또는 multipart), 헤더 `X-Signature: HMAC-SHA256(nonce+ts+body, per_device_secret)`, `X-Nonce`, `X-Timestamp`.
- **replay 방지:** nonce 1회성 + timestamp 윈도우 검증.
- **이미지:** 서버가 GD/Imagick로 **재인코딩**(페이로드 제거, 강제 .jpg, 랜덤 UUID 파일명), **웹루트 밖** 저장, **인증 PHP 프록시로만** 서빙(IDOR 차단).
- **SQL:** prepared statement + event_type/severity **화이트리스트** enum. 출력 인코딩 + CSP(저장 XSS).
- **남용:** per-device rate limit + 크기/inode 쿼터(위조 홍수로 스토리지·대시보드 다운 방지).
```json
{
"device_id": "pi-warehouse-01",
"camera_id": "cam-02",
"event_type": "fall | no_motion | immobility | ghost | zone_warning | zone_restricted | pinch | monitoring_degraded | device_fault",
"severity": "critical | high | warning | info",
"track_id": 42,
"zone_id": "zone-loading-dock",
"occurred_at": "2026-07-11T09:15:32+09:00",
"received_at": "(서버 기록)",
"duration_s": 12.4,
"disposition": "unset | real_emergency | false_alarm | handled_onsite | drill | needs_review",
"is_test": false,
"metrics": { "torso_angle": 78.2, "height_collapse": 0.55, "immobility_s": 10.1 },
"snapshots": ["<jpeg-1>", "<jpeg-2>", "<jpeg-3>"]
}
```
`POST /api/heartbeat` — device_id, 카메라별 상태·fps·온도·스로틀·큐깊이·config버전.
`GET /api/config?device_id=` — 구역·임계값(per-cam/zone) 최신본; Pi가 적용버전 회신.
### 7.4 DB 스키마(개략)
- `users(user_id, role, site_scope, password_hash, ...)`, `sites(site_id, name, address)`
- `devices(device_id, site_id, name, last_heartbeat, temp, throttle, config_version, status)`
- `cameras(camera_id, device_id, name, role[fall_critical|zone|low], last_frame_at)`
- `zones(zone_id, camera_id, level[warning|restricted|pinch], polygon_json, updated_at)`
- `events(event_id, device_id, camera_id, event_type, severity, track_id, zone_id, occurred_at, received_at, duration_s, disposition, is_test, legal_hold, metrics_json, acknowledged_by, acknowledged_at, lifecycle_state)`
- `event_snapshots(snapshot_id, event_id, file_uuid, content_hash, created_at)` — 웹루트 밖.
- `thresholds(device_id, camera_id, zone_id, key, value)` — per-cam/zone.
- `escalations(event_id, level, recipient, sent_at, delivered, responded_at)`, `oncall(site_id, shift, recipient, priority)`
- `audit_log(id, actor, action, target, before, after, ts, prev_hash, hash)` — append-only 해시체인.
- `compliance(site_id, nosa_record_json, dpia_json, signage_meta, subject_requests_json)`
- `retention_policy(data_class, days, legal_hold_years)`
---
## 8. 신뢰성 / 대응 / 에러 처리
- **오프라인 큐:** 실패 시 암호화 SQLite 저장, 백오프 재전송. 유실 0.
- **하트비트:** 30초 주기(fps·온도·스로틀·큐·config버전). 90초 무신호 → "감시 중단" 경보.
- **카메라 재연결 + self-check:** 끊김 자동 재오픈; 가림/초점흐림/조명꺼짐/탬퍼 → `monitoring_degraded`(다운과 구분). active-hours 스케줄로 off-shift 블라인드는 정상 처리.
- **워치독:** 프레임 정체 → systemd watchdog 재시작.
- **대응 에스컬레이션(F9):** 위급 미확인 SLA 초과 → 2/3차 온콜·음성콜 폴백 → 119 카드 → 지방노동관서 보고 초안. SMS 전송영수증 추적·미전달 재라우팅.
- **경보 이중화:** 위급 = 대시보드+SMS+부저+데스크오디오 동시.
- **신뢰 시간:** HW RTC + 로컬 NTP; 서버 received_at 병기; skew 플래그.
---
## 9. 개인정보 / 보안
### 9.1 데이터 / 프라이버시
- 클라우드엔 **사고 스냅샷만**(라이브뷰·영상 없음). 배경인물 **얼굴블러 default-ON**.
- **계층형 보존(NF6):** 일상/오탐 30~90일, 실사고 **legal-hold 3~5년**(산안법 §164 대응; 정확 값 법률 확정 §16). 자동삭제가 중대재해 증거 파기하지 않도록 legal-hold 우선.
- 목적 제한(근태감시 전용 차단), 데이터주체 조회/삭제, 모든 조회/내보내기 접근로그.
### 9.2 애플리케이션 보안
- 대시보드 인증/RBAC/세션하드닝(§7.1). ingest HMAC+nonce+per-device 키(§7.3).
- 스냅샷 웹루트 밖 + 프록시, 이미지 재인코딩, prepared statement, CSP, rate limit.
- **위변조방지 audit**: 임계값·구역·확인·조회·내보내기 전부 append-only 해시체인(누가·언제·전·후). 감도 몰래 낮춰 사고 은폐 탐지.
### 9.3 엣지 / 공급망
- 큐/스냅샷 파티션 **LUKS 암호화**, 시크릿 **TPM/keyring**(평문 금지), 함체 탬퍼 GPIO → 보안이벤트.
- SSH 키전용·root 비활성·egress 방화벽(Cafe24만). TLS 엄격검증 + **인증서 핀닝 fail-closed**.
- 모든 vendored 의존성·`.hef` **SHA256/GPG 검증**(빌드+로드시) + SBOM. (참고 fall repo의 Azure 문자열 유출 사례 = 공급망 리스크 근거.)
### 9.4 시크릿 관리
- HMAC·SMS·DB 키 환경변수/시크릿 매니저. 소스·아티팩트 하드코딩 금지. per-device 키 회전/폐기.
---
## 10. 하드웨어 · 모델 · 런타임 (조사 근거)
### 10.1 모델
- **주 모델 `yolov8s_pose`**(640×640, 17 관절). Hailo-8 pose HEF 라이트. 세 이벤트 전부 여기서 파생.
- Hailo HEF 배포 → 런타임 **ultralytics(AGPL) 비의존**.
### 10.2 fps 3티어 폴백 (신규, P1 설계 의무)
미검증 pose fps 리스크에 **제품적 답**. 카메라 `role`이 NPU 스케줄링 구동:
| 티어 | 처리 | 용도 | 부하 |
|---|---|---|---|
| **T1 full-pose** | 관절17 → 낙상+미동+구역+끼임 | fall_critical 카메라 | 최대 |
| **T2 detection-only** | 사람박스+발끝앵커 → 구역+거친 낙상(종횡비)만 | zone 카메라 | 중 |
| **T3 motion-occupancy** | 움직임/점유만 → 부동·구역 진입만 | low-priority | 최소 |
- **PCIe Gen3 강제**(`dtparam=pciex1_gen=3`), `batch-size ≥ N`, 640 유지.
- **실병목 = Pi CPU**(파이프라인당 ~1코어). 후처리 C/GStreamer, Python 콜백 최소.
- 3티어 전부 **P1에서 실장비 검증** → 우아한 저하 제품 확보 후 고객약속. 벤치 결과 → cameras-per-Pi·Pis-per-site·BOM·가격 산정.
- **스로틀 텔레메트리:** 뜨거운 밀폐 함체 스로틀이 fps 저하 → 온도·스로틀 하트비트로 티어 신뢰.
### 10.3 카메라 캡처
- CSI: picamera2, **카메라당 별 프로세스**. USB: v4l2 **MJPEG 필수**, **2개 USB3 컨트롤러 분산** + 전원 허브.
### 10.4 런타임 스택
- **hailo-rpi5-examples(MIT) + hailo-apps-infra + GStreamer.** `N소스 → hailoroundrobin → 단일 hailonet(공유 pose, batch≥N) → hailostreamrouter → 캠별 추적/룰`.
### 10.5 참조 BOM / 사이트 준비 (P2)
- 카메라 SKU·렌즈/FoV, **IP5x+ 방열·필터 함체**(동작온도 명시), 마운트/조준 가이드, 전원 허브, **소형 UPS**(정전 라이드), 네트워크 업링크/페일오버. "현재프레임 캡처"(F15)로 신규캠 구역 그리기 chicken-egg 해소.
---
## 11. 재사용 OSS 및 라이선스
| 용도 | 프로젝트 | 라이선스 | 방식 |
|---|---|---|---|
| 플러밍 뼈대 | hailo-ai/hailo-rpi5-examples | MIT | fork |
| 추적+체류 참조 | Seeed YOLOv11-Hailo-Tracker | MIT | ByteTrack+dwell → 구역/미동 타이머 |
| 구역/끼임 | roboflow/supervision | MIT | PolygonZone 앵커(발끝/임의관절) |
| 구역 드로잉 UI | roboflow/polygonzone | MIT | 참조 |
| 추적기 | ByteTrack / OC-SORT | MIT | 기본/대안 |
| 키포인트 스무딩 | One-Euro filter | 공개 알고리즘 | 자체 구현 |
| 낙상 휴리스틱 | InvictusRex, Y-B-Class 등 | 무라이선스 | 알고리즘만 참고·재구현 |
**라이선스 함정:** `ultralytics`(AGPL) 런타임 배제 → Hailo HEF + 자체 로직. 무라이선스 repo = 알고리즘 참고만. (`16dina/fall-detection` Azure 문자열 유출 블록 복사 금지.)
---
## 12. 테스트 / 검증 전략
- **유닛:** 상태머신(전이·부동 워치독·유령사고·디바운스·쿨다운·baseline freeze) 합성 시퀀스, 80%+ 코드커버리지.
- **탐지 정확도(NF8, 신규):** **라벨 평가셋** 구축 — 공개 낙상 코퍼스 + 매트 연출낙상 + **강한 하드네거티브**(앉음·깊은 숙임·의도적 눕기·무거운 물건 낙하·2인 겹침) + 정면/후면·가림·기어감·프레임가장자리 케이스. 목표: 낙상 recall, 오탐/카메라/일, 에스컬레이션 지연.
- **커미셔닝 게이트(신규):** **드릴 모드**로 실장착 카메라별 연출낙상 → pass/fail 리포트. `is_test=true`로 실제 119/SMS 억제. **go-live 전제 + 중대재해처벌법 due-diligence 증거.**
- **부하:** 4캠 라운드로빈 fps·CPU·온도·지연 실측(티어별).
- **E2E:** 모의사고 → 스냅샷 → Cafe24 수신(인증/HMAC) → 대시보드 → 에스컬레이션 → (위급) SMS.
- **오프라인:** 네트워크 차단 설치·구동(NF3), POST 실패→큐→복구 재전송.
- **보안:** 인증/RBAC·replay·IDOR·업로드·SQLi·rate limit 침투 테스트.
---
## 13. 단계별 로드맵 (리뷰 반영 재배치)
- **P1 (MVP + 안전 필수):** 1캠 낙상 + **자세무관 부동(F3b)** + **유령사고(F3c)** + 스냅샷 POST. **시점강건 낙상(OR)·지터스무딩·baseline freeze.** **대시보드 인증/RBAC(F7,NF7)** + **ingest 하드닝(NF5).** **라벨 평가셋 + 드릴 커미셔닝 게이트(NF8).** **fps 3티어 검증(§10.2).** **컴플라이언스 최소본(F14: 노사협의회·안내판·블러·DPIA).** 색맹안전 심각도(NF9). "현재프레임 캡처"(F15). 위급 최소 에스컬레이션.
- **P2:** 멀티캠(2~4) + **끼임 body-part(F4b)** + 위험구역 2단계·감도 다이얼(F11) + 오탐 피드백·링버퍼(F10) + 카메라 self-check(F12) + 신뢰시간(NF10) + 경량 멀티사이트 플릿 + 플릿 관측성·물리내구 + BOM/함체/UPS.
- **P3:** 대응 에스컬레이션 풀(F9) + 증거 무결성·legal-hold·audit(F13) + 엣지 하드닝(LUKS/TPM/탬퍼) + 서명 오프라인 OTA + SMS/GPIO 이중화 + 이력·통계·KPI.
- **P4 (선택/범위결정):** 떨어짐·부딪힘·밀폐공간(외부센서) · 끼임 E-stop 능동개입 · 행동인식(ST-GCN) · 대규모 다중 Pi 집계 · RTSP 레트로핏 수신.
---
## 14. 미해결 리스크 / 실장비 검증 체크리스트
1. **[최우선] Pi `yolov8s_pose` 엔드투엔드 fps 미검증.** 3티어 전부 실장비 벤치 → 캠 수·BOM 확정.
2. **PCIe Gen3 안정성** — 지속부하·발열 링크 안정.
3. **멀티 CSI 불안정** — 카메라당 별프로세스, 장시간 CSI+USB 동시 검증.
4. **USB UVC 대역폭** — MJPEG, 2 USB3 분산.
5. **마운팅 각도별 휴리스틱 오탐** — per-camera 캘리브 + 현장영상 튜닝.
6. **저fps 낙상 누락** — 낙상 중요캠 ≥12~15fps, 속도 휴리스틱 발화 확인.
7. **INT8 pose 정확도/지터** — recall·미동 임계에 영향, 평가셋으로 측정.
8. **가림/ID스위치** — 공간바인딩·유령사고 효과 실측.
9. **Cafe24 공유호스팅 하드닝 한계** — 웹루트밖·프록시·rate limit로 완화, 침투 테스트로 검증.
10. **폐쇄망 패키징** — `.hef`·휠·PHP 의존성 번들, 차단 설치 검증, HailoRT↔Compiler 버전 정렬.
11. **열/스로틀** — 함체 방열 검증, 스로틀 텔레메트리.
12. **SD 마모** — SSD/NVMe 부팅 + WAL로 "유실0" 보전.
---
## 15. 설정 파라미터 레퍼런스 (시작값, per-cam/zone 조정)
| 파라미터 | 시작값 | 비고 |
|---|---|---|
| 몸통각도(FALLING 전이) | ~45° 상향돌파 + 하강속도 | 서있음0° 누움90° |
| FALLEN 확정 (OR) | 각도>70° **또는** 높이급붕괴 **또는** COM하강 **또는** 머리<엉덩이/AR>1.25 | 시점강건 |
| bbox 종횡비 | > 1.25 (Δ>0.35 급변) | |
| 관절 신뢰도 | conf ≥ 0.5, 핵심4·가시≥10 | |
| 낙상 확정 지속 | prone > 3초 (20프레임 다수결) | |
| 낙상후 미동 | 관절변위<임계 ≥10초 | 5~15초 |
| 자세무관 부동(F3b) | 좌위 90~180초 / 위험구역 더 짧게 | |
| 미동 임계 | 측정 정지지터 + 마진 | 지터 무한미발화 방지 |
| 유령사고 재출현 대기(T) | 5~15초 | 미재출현 시 상향 |
| 구역 침입 디바운스 | 0.5~1초 | |
| 하트비트/다운 | 30초 / 90초 무신호 | |
| 보관 | 일상 30~90일 / 실사고 3~5년 legal-hold | 법률 확정 §16 |
| 낙상 중요캠 fps | ≥ 12~15 / 저위험 8~10 | |
| PCIe | Gen3 강제 | `dtparam=pciex1_gen=3` |
| 확인 SLA (위급) | 예: 60~120초 → 2차 에스컬레이션 | 온콜 구조 확정 §16 |
---
## 16. 남은 미결정 (사용자/법률 확인 필요)
- **보관기간:** env 설정으로 진행(정확값 TBD, 법률 확정 시 조정). 일상/실사고 legal-hold 모두 환경변수. 낙상/실신=민감정보 확정은 법률 확인.
- **끼임 E-stop 능동개입:** 안전PLC 인증·책임 감수하고 기계정지 출력? 아니면 detect-and-alert 한정? (v1은 훅만)
- **온콜/에스컬레이션 현실:** 각 사이트 24/7 온콜 구조? 119/노동관서 보고 연동 형태?
- **RTC BOM 비용:** 유닛마다 HW RTC + 로컬 NTP 추가 수용?
- **업데이트 물류:** 서명 번들을 사이트 업링크 vs USB 스니커넷? 서명·배포 권한자?
- **카메라 소싱:** 그린필드 CSI/USB 한정 vs 기존 IP/RTSP/ONVIF 수신 + 고객 VMS 이벤트 내보내기(레트로핏 세일즈)?
- **떨어짐/부딪힘/밀폐공간:** P4 착수 여부 및 우선순위(외부센서 필요).
---
_문서 끝. 다음 단계: 사용자 리뷰 → writing-plans 스킬로 P1 구현 계획 수립._