# camera24 실시간 FIGHT 설정 및 45초 관측

- 작업일: 2026-11-01 KST. profile `ltb1021`, server `test`.
- 범위: 기존 실행의 설정/Redis/DB 읽기, 45초 metadata cache 보존, 자연 발생 Event의 기존 아티팩트 복사와 기술 표본 확인.
- 변경하지 않은 항목: 설정, Start/Stop, Runtime/컨테이너, Web, Chrome, 미디어 서비스, 모델/Pose/Tracking/싸움 규칙.
- 결론: R5의 표시 metadata, 새 Event 생성, 썸네일/클립 생성, Web API 전달 경로가 관측됐다. 브라우저의 실제 표시/알람과 정오탐 정확도는 이번 조사로 확정하지 않는다.

## 1. 현재 실효 설정

관측 전후 설정과 run이 동일했고, configured/effective가 일치했다. camera24는 `RUNNING`, `restart_pending=false`였다.

| 항목 | 실제 적용값 | 의미 |
| --- | --- | --- |
| FIGHT / 엔진 | enabled / `r5` | 고정 R5 |
| ROI | 전체 화면 | Web의 빈 ROI 목록을 기본 전체 영역으로 해석 |
| 사람 score | `>=0.25` | FIGHT 계산 하한 |
| 관절 score | `>=0.30` | Web의 높은 요청값을 유지. 오프라인 검토의 0.10과 다름 |
| R5 schema_version | `1` | 새 설정 블록 버전 |
| window_seconds | `1.0` | 최근 실제 관측창 |
| min_samples | `2` | 일반 규칙의 유효 근거 관측 수 기준 |
| contact_min_samples | `3` | 접촉 계열 규칙의 유효 근거 관측 수 기준 |
| 외부 FIGHT Event cooldown | `10초` | 저장된 시나리오별 cooldown |
| 내부 episode 정책 | cooldown 2초 / quiet rearm 2초 / missing expiry 5초 | 외부 전송 cooldown과 별개 |
| 빨강 표시 유지 | `1초` | 현재 충족 이후 표시 정책. 신규 Event나 근거 누적과 다름 |
| analysisFpsTarget | `10` | 목표값이며 장기 실측 보장이 아님 |

`min_samples=2`는 아무 조건 두 개만 만족하면 된다는 뜻이 아니다. 필요한 관절, 공간 관계, 현재/최근 움직임과 규칙별 억제 조건을 통과한 유효 근거를 세는 값이다.

Pose 표시 설정은 `enabled=false`, `show_bbox=true`, `show_joints=false`, `show_edges=false`였다. 별도 Pose 검토 표시가 꺼진 상태이지 Pose 추론이 꺼진 상태가 아니다. 관측 metadata의 provider는 모두 `RFDETRKeypointPreview`였다. Tracking은 enabled, activation 0.25, matching 0.8, lost_buffer 30이며 이번에 변경하지 않았다.

## 2. Web Start에서 AI 실효값까지

확인 경로는 Web DB의 camera24 FIGHT 행과 Web의 Start 조립/catalog 소스, AI 설정 처리 소스, 실제 runtime/persistent 설정이다. **아래 요청은 실제 DB와 조립 소스로 재구성한 FIGHT 항목이며, HTTP 원문을 packet capture한 결과는 아니다.**

```json
{
  "scenarioCode": "FIGHT",
  "enabled": true,
  "rois": [],
  "parameters": {
    "person_confidence": 0.15,
    "pose_confidence": 0.3,
    "cooldown_seconds": 10,
    "pair_distance_ratio": 1.8,
    "pair_close_hold_seconds": 0.1,
    "arm_motion_ratio": 0.1,
    "required_bursts": 1
  }
}
```

| Web 입력 | AI 처리 | 실제 결과 |
| --- | --- | --- |
| person_confidence 0.15 | FIGHT 하한으로 보정 | 0.25 |
| pose_confidence 0.30 | 0.10 이상이므로 유지 | 0.30 |
| cooldown_seconds 10 | 공통 Event 정책에 반영 | FIGHT 10초 |
| pair_distance_ratio 1.8 | R5에서 구형 동작값 무시 | `LEGACY_NOT_APPLIED` |
| pair_close_hold_seconds 0.1 | 동일 | R5 고정 공간 정책 사용 |
| arm_motion_ratio 0.1 | 동일 | R5 고정 동작 정책 사용 |
| required_bursts 1 | 동일 | R5 유효 근거/episode 정책 사용 |
| fight_r5 블록 없음 | 저장된 R5 설정 유지 | window 1.0 / min 2 / contact 3 |

Web는 브라우저에서 저장한 설정을 DB에서 읽고 catalog의 허용 항목과 합쳐 Start를 만든다. 현재 catalog에 새 `fight_r5` 블록은 없었다. AI의 legacy 설정 필드에 숫자가 남아 있다는 이유만으로 그 숫자가 R5 판정에 사용된다고 해석하면 안 된다. 구형 요청이 반복되더라도 실효 설정이 같으면 불필요한 run 교체를 하지 않는 계약이며, 이번 구간의 runId/runGeneration/configVersion도 유지됐다. 개별 반복 HTTP 요청의 시각/원문은 이번에 직접 수집하지 않았다.

## 3. 45초 관측 결과

AI 서버 관측 시각: **13:47:35.206 ~ 13:48:20.281 KST**, 실제 45.074초.

| 확인 항목 | 결과 |
| --- | --- |
| Redis metadata 관측 | 452건 |
| 짧은 구간 발행률 | 약 10.03건/초 |
| FIGHT 빨강 표시가 있는 관측 | 28/452건, 6.19% |
| 연속 빨강 표시 묶음 | 7구간, 마지막은 관측 종료로 잘림 |
| 빨강 관측의 FIGHT 객체 수 | 각 관측 2개 |
| FIGHT state와 `#FF3030` 불일치 | 0건 |
| PTS/Frame 순서 | 엄격 증가 |
| PTS 간격 | 최소 0.039초 / 중앙값 0.099초 / 최대 0.155초 |
| run/config/컨테이너 변경 | 없음 |
| Redis 읽기 오류 | 없음 |
| 새 FIGHT Event | 1건 |

**28건은 현재 조건 충족과 1초 표시 유지를 합친 게시 상태다. 정확한 현재-rule 통과 건수, 정탐 프레임 비율, 정확도 또는 재현율이 아니다.** 공개 metadata만으로 현재 충족과 유지 각각의 수를 분리할 수 없어 임의로 추정하지 않았다. 표시 유지와 내부 재무장/외부 cooldown 때문에 빨강 구간 수와 Event 수는 일치할 필요가 없다. 각 비발급 사유의 전체 내부 trace를 수집한 것은 아니다.

| 빨강 관측 시각(KST) | frameSeq 범위 | 관측 수 |
| --- | --- | ---: |
| 13:47:36.657 ~ 13:47:37.048 | 12656 ~ 12666 | 5 |
| 13:47:40.283 ~ 13:47:40.763 | 12743 ~ 12755 | 6 |
| 13:47:50.131 ~ 13:47:50.765 | 12980 ~ 12995 | 7 |
| 13:47:57.176 | 13149 | 1 |
| 13:48:07.150 | 13388 | 1 |
| 13:48:10.264 ~ 13:48:10.919 | 13463 ~ 13478 | 7 |
| 13:48:20.281 | 13703 | 1, 종료 경계 |

frameSeq는 이 실시간 run의 원본 디코딩 순번이다. 과거 camera24 검토 클립의 Source Frame 번호와 직접 같다고 가정하지 않는다. 입력 프레임률과 분석 10FPS가 다르므로 frameSeq가 2~3씩 증가하는 것 자체는 누락 증거가 아니다.

## 4. 새 Event와 아티팩트

- Event ID: `7da55541-7109-4bd8-a577-419dad502542`.
- AI 기록 시각: **13:48:20.277 KST**, frameSeq `13703`, PTS `574148734431 ns`.
- 후속 ledger 조회: `artifact_state=READY`, `delivery_state=SENT`, HTTP `200`, 오류 없음.
- 썸네일: 640x360. 클립: 1280x720, 60프레임, 약 6.034초.
- captureReason `COMPLETE`, preShortMs/postShortMs 0, metadataQueueDrop 0.
- 관측 종료 직후 첫 DB 조회는 비동기 Event 수락보다 빨라 새 행이 없었다. 이후 해당 ID만 재조회해 READY/SENT를 확인했다. 이전 Event는 이번 새 Event 수에 넣지 않았다.
- 원본 파일 SHA256과 test 복사본이 일치했다. 기존 파일을 복사했으며 새 녹화나 Event 주입은 하지 않았다.
- 클립의 원래 packet PTS/DTS는 모두 증가하고 원본 timebase를 유지한 전체 디코딩은 통과했다. 최초 기본 null-mux 검사에서 출력 timebase 반올림에 따른 중복 DTS 경고가 있었으나, 원본 packet 확인과 passthrough 검사에서는 오류가 없었다.

`metadataMissingFrames=85`, `omittedFramesWithoutMetadata=85`는 원본 RGB 가운데 exact-PTS metadata가 없는 프레임을 아티팩트에서 제외한 수다. 원본 약24FPS와 분석 약10FPS의 차이 및 `EXACT_PTS_METADATA` 선택 정책을 고려해야 하며 85건의 모델 추론 유실이라고 단정하지 않는다. `nativeDrop=4`는 기록된 카운터이며 이번 45초에 4건이 새로 발생했다고 해석하지 않는다.

**HTTP 200은 Web API가 받았다는 근거다. 사용자 브라우저에 알람 팝업이 실제로 보였는지, URL을 브라우저에서 열었는지는 별도 확인이다.**

## 5. 의견과 다음 판단

1. 기술 흐름은 작동하는 것으로 보인다. 10FPS 수준의 짧은 구간 metadata, FIGHT 빨강, 새 Event, 두 미디어와 Web 응답까지 연결됐다. 장시간 안정성 또는 라이브 일반화 보장은 아니다.
2. 아티팩트 표본은 왼쪽 두 사람을 빨강, 주변 사람을 녹색으로 구분했다. 썸네일에서는 왼쪽 라벨끼리 겹친다. 클립 후반 표본에는 같은 부근의 bbox가 중복처럼 보이는 경우가 있어 입력/표시 품질의 추가 사용자 확인 대상으로 남긴다. 이 관찰만으로 전체 정오탐이나 Tracker 오류를 확정하지 않는다.
3. 현재 관절 기준은 오프라인 검토의 0.10이 아니라 0.30이다. 사용할 수 있는 관절이 달라질 수 있으므로 시각 피드백 비교 시 중요한 차이다. 이번에는 0.10 재계산이나 하향 조정을 하지 않았으며 감지 증가/오판 감소를 예측 수치로 제시하지 않는다.
4. source-time과 관측 시각 사이 중앙값 약 19.7초 차이가 있었지만 frameTime은 447건 ESTIMATED, 5건 UNAVAILABLE이고 외부 anchor/호스트 시계 정합은 검증하지 않았다. 이를 곧바로 AI 처리 지연이라고 부르지 않는다. ingest-to-observe 중앙값 20ms도 전체 종단 지연 측정은 아니다.
5. 사용자 피드백은 camera24와 대략적 브라우저 시각, 빨강/알람/썸네일/클립을 구분해 주면 된다. 이번 Event 시각과 브라우저 시각이 다르면 timestamp 기준부터 대조한다.

## 6. 보존 자료와 재사용

- [요약 JSON](summary.json): 설정, 구간 통계, Event 상태와 한계.
- [45초 metadata cache](camera24_metadata_45s.json): 452관측의 bbox, keypoints, 원래 ID, PTS/frameSeq, 표시/이벤트 참조. 모델 직출력 전체가 아닌 **실시간 게시 metadata cache**다.
- [Web FIGHT 항목](web_fight_start_item.json): DB/실제 조립 소스 기반 재구성본.
- [썸네일](event_sample/thumbnail.jpg), [기존 Event 클립](event_sample/clip.mp4): 관측 중 자연 생성된 기존 파일의 복사본.
- [전송 지문](media_transfer.json), [미디어 기술 검증](media_verification.json), [전체 산출물 manifest](manifest.json).
- `../private/`: 접근 제한된 설정/DB/소스/후속 확인 원본. 일반 전달 대상이 아니다.
- `../helpers/`: 실제 수집/분석 명령의 재현 근거. `monitor.py`는 새 관측을 시작하므로 단순 통계 재검토를 위해 다시 실행하지 않는다.

필수 검증은 관측 시간/설정 불변/동일 run/PTS/색상 대응과 새 Event 미디어/전송 근거에 한정했다. 브라우저 실제 알람 확인은 사용자 검토, 장시간 부하 및 정확도 평가는 보류다. 저장소/운영 변경 없이 비저장소 evidence만 추가했다.
