# APOSTOLUS 12-1 ~ 12-4 · 자살예방 기술개발 묶음의 가상 검증 하네스

설계 명세 네 건의 판정 장치를 표준 라이브러리 Python으로 실행하는 참조 구현이다. 입력은 고정 픽스처 다섯 개이고 모든 자료는 코드가 만든 합성 시퀀스, 추상 픽스처, 자리표시자 토큰이다. 실제 코호트, 임상노트, 상담 발화, 도메인 어휘는 읽지 않고 담지도 않는다.

| 과제 | 설계 명세 | 내부 연구 목표 |
| --- | --- | --- |
| 12-1 | 급성 위기 조기 탐지 | 재현율 90% 이상 |
| 12-2 | 위험 궤적과 안전계획 엔진 | 치료 금기 발화 위배율 0% |
| 12-3 | 온디바이스 고립 전환 탐지 | 정밀도 85% 이상 |
| 12-4 | 위기 선별과 즉시 전환 라우팅 | 즉시 전환율 100% |

## 실행

프로젝트 루트에서 Python 3.10 이상으로 실행한다. 외부 패키지는 필요 없다.

```sh
python3 -B -m prevent12.orchestrate --output evidence/prevent12-run.json
python3 -B -m prevent12.audit --run evidence/prevent12-run.json --output evidence/prevent12-audit.json
python3 -B -m unittest discover -s tests -p 'test_prevent12.py' -v
```

실행기는 약 3초, 감사기는 1초 안에 끝난다(다른 작업이 함께 도는 부하에서는 더 걸린다). 감사가 실패하면 첫 실패 관문과 사유를 JSON에 적고 종료 코드 1을 돌려준다. 감사 문서의 `humanAuditorSignature`는 항상 비어 있고 `researchStatus`는 `external_cohort_not_run`이다. `evidenceSha256`는 그 필드만 뺀 본문을 키 정렬 UTF-8 JSON(공백 없음)으로 직렬화해 계산한다.

| 파일 | 역할 |
| --- | --- |
| `_contract.py` | 정규화·해시, 픽스처 잠금, 식별자 형식 문자열 검사(`free_text_paths`), 한글 코드 포인트 검사 |
| `_stats.py` | 이항 꼬리, 순서통계량 임계치 색인, Clopper–Pearson·Wilson 구간, KS 검정, 행렬 지수, 재현 가능한 난수열 |
| `t121.py` | 영원문 스키마, 상태전환 Hawkes 합성기와 보정자 검증, 중도절단 가법 위험 EM, NP 임계치, 집단 격차 감사, 검토 큐 라우팅, as-of 분할 |
| `t122.py` | C-SSRS 궤적 필터(연속시간 은닉 마르코프), 안전계획 상태기계, 이중 출력 검증기와 Fail-Closed 방출, 추상 픽스처 |
| `t123.py` | 일주기·이동·생체 특징, 로컬 차분프라이버시와 예산 장부, BOCPD와 지속성 규칙, 정밀도 인증과 유병률 이동 상한, 반출 허용 목록, 동의 원장 |
| `t124.py` | 자모 정규화와 음운 거리, 키 해시 사전 대조기, 기본 거부 관문, Fail-Closed 라우터와 고장 조합 전수 열거 |
| `orchestrate.py` | 네 과제 블록을 한 증거 문서로 묶는 실행기 |
| `audit.py` | 풀이 모듈을 import하지 않고 다른 구현으로 다시 계산하는 감사기 |
| `hypothesis_spec/` | (선택) pytest·Hypothesis 속성 기반 규격 27건 |
| `torch_ref/` | (선택) PyTorch 참조 모듈 3개와 시험 5건 |

## 실행기와 감사기의 분리

감사기는 `t121`–`t124`를 불러오지 않는다. 같이 쓰는 것은 `_contract.py`의 직렬화·해시 도우미와 고정 픽스처뿐이다. 주장이 실린 수치는 다른 방법으로 다시 계산한다.

| 대상 | 실행기 | 감사기 |
| --- | --- | --- |
| 이항 꼬리와 순서 색인 $k^{*}$ | 로그 감마 부동소수 합 | `fractions`의 정확 유리수 |
| 12-1 임계치·재현율·격차·경로 | 부동소수 누적 | 증거 문서의 행에서 유리수로 재집계 |
| 12-2 전이 | 조건 분기 사다리 | 전역 이벤트 표 + 선형 단계 순서 규칙표 |
| 12-2 궤적 전이확률 | 스케일링·제곱 행렬 지수 | 균일화(uniformization) 벡터 전개 |
| 12-3 페이로드 판정 | 금지 단어 목록 + 형식 검사 | 정확한 키 집합 허용 목록 |
| 12-3 인증·구간 | 이분법으로 푼 Clopper–Pearson | 보고된 한계를 정확 꼬리 방정식에 대입 |
| 12-4 추적 | 고장 일정을 따라 실행한 이벤트 기록 | 고장 코드와 시간표만으로 기대 이벤트열·시각을 따로 구성 |

두 프로그램은 같은 파일 권한으로 돈다. 정답을 숨긴 독립 블라인드 환경이 아니며, 별도 호스트·컨테이너 실행과 감사자 서명은 하지 않았다.

## 네 관문

| 관문 | 확인하는 것 |
| --- | --- |
| G1 동결 입력과 제출 구조 | 픽스처 5개의 잠금 해시, 제출 본문 해시, 문서의 모든 문자열이 식별자 형식인지(자유 문장·한글이 있으면 실패) |
| G2 스키마·정책 규칙과 전이 완전성 | 12-1 표본 행과 누수 검사, 12-2 전이 156쌍·방출 190조합·템플릿 자리표시자, 12-3 페이로드·동의·프라이버시 회계, 12-4 한글 문자 0줄·고장 공간 1,728개 전수 |
| G3 임계치와 지표의 독립 재계산 | 위 표의 재계산이 제출값과 일치하는지, 그리고 설계한 반례 가지(집단 격차, 미인증 유병률, 폴백 경로)가 실제로 실행됐는지 |
| G4 가상 지표 판정과 결과 해시 | 네 과제의 가상 지표가 사전 정의 기준에 드는지. 실행 문서 해시를 감사 문서에 기록 |

## 가상 지표 (2026-11-14 고정 실행)

| 과제 | 지표 | 기준 | 가상 실측 | 함께 본 값 |
| --- | --- | --- | --- | --- |
| 12-1 | 재현율(IPCW) | 0.90 이상 | **0.9155** (양성 167건) | 잠재 정답 대조 0.9324, 시험 표본 단측 95% 하한 0.873, 경보 에피소드 정밀도 0.079, 환자 100인·월당 경보 46.1건, ECE 0.020, 집단 격차 감사 `GAP_EXCEEDS_TOLERANCE` |
| 12-2 | 금기 출력 | 0건 | **0 / 30,190** | 전이 156쌍 일치, 방출 190조합 중 정본 1건만 방출, 고위험 전환 128회에서 생성기 호출 0회 |
| 12-3 | 정밀도 | 0.85 이상 | **0.978** (92건 중 90건) | 단측 95% 하한 0.933, 재현율 0.978, 유병률 0.25·0.10 인증, 0.05·0.02 미인증 |
| 12-4 | 즉시 전환율 | 1 | **1,584 / 1,584** | 고장 조합 1,728개, 연락처 표시 최대 1,500 ms, 종결 최대 64,800 ms, 세션 144개에서 래치 뒤 AI 재개 0건 |

12-2의 0건과 12-4의 100%는 통계 추정이 아니라 닫힌 출력 공간과 명시한 고장 모형 안에서의 구조 성질이다. 가정(12-2 명세의 A1–A3, 12-4 명세의 F1–F3)이 깨지거나 모형 밖의 상황, 그리고 선별 모형이 감지하지 못한 위기에는 적용되지 않는다.

이 값은 합성 입력에서 파이프라인과 판정 장치가 설계대로 움직이는지 본 것이다. 실제 위기 탐지 재현율, 실제 상담에서의 금기 위배율, 지역사회 고립 탐지 정밀도, 운영 환경의 전환 지연은 측정하지 않았다. 12-1과 12-3의 합성 세계는 신호가 실제보다 깨끗하고, 12-4의 시간은 가상 구성값의 합이다. 자료 접근과 정답 확보 상태는 평가 등록부와 출처 등록부를 따른다.

설계한 반례가 실제로 걸렸는지도 본다. 12-1에서 관측 결손을 넣은 집단의 재현율이 기준 아래로 잡혔고(0.872), 12-3에서 보정 유병률보다 낮은 유병률은 인증되지 않았으며, 12-4에서 감시 타이머·충돌 복구·저하 모드·예비 풀·상담전화 연결 안내 경로가 모두 실행됐다. 이 가지들이 실행되지 않으면 감사 G3이 실패한다.

## 선택 검증 (pytest · Hypothesis · PyTorch)

표준 실행 경로는 이 폴더들을 불러오지 않는다. 임시 폴더에 만든 격리 환경(Python 3.12.1, pytest 9.2.0, hypothesis 6.170.15, torch 2.15.0)에서 2026-11-14에 실행해 32건이 모두 통과했다. 실행은 프로젝트 폴더에 캐시를 남기지 않는다.

```sh
PYTHONDONTWRITEBYTECODE=1 python -m pytest prevent12/hypothesis_spec prevent12/torch_ref -p no:cacheprovider -q
```

이 검증이 찾아낸 결함 세 건을 고쳤다.

1. 종결 상태(`CLOSED`, `HANDOFF_REVIEW`)에서 정책 사전이 불능이면 세션이 `FAILSAFE`로 옮겨 가며 통지·연결 효과가 다시 일어났다. 동의를 철회해 닫힌 세션에서도 그랬다. 효과를 "상태에 들어갈 때만"으로 고치고 회귀 시험과 감사 규칙을 추가했다.
2. 추상 후보 생성 함수가 슬롯 없는 템플릿에서 예외를 냈고, 무작위 보행에서는 그 예외가 생성기 실패 경로로 가려져 있었다.
3. PyTorch 참조 모듈의 속성 이름이 프레임워크 메서드와 겹쳐 실행되지 않았다.

## 바이트 재현

단위 시험이 새 프로세스로 실행기와 감사기를 돌려 저장된 두 증거 파일과 바이트 단위로 같은지 확인한다(`test_command_line_round_trip`). 부동소수는 소수 6자리로 반올림해 싣는다. 같은 기기에서의 재현을 확인했고, 다른 운영체제의 수학 라이브러리에서 마지막 자리가 달라질 가능성은 시험하지 않았다.

| 파일 | 파일 SHA-256 | 본문 `evidenceSha256` |
| --- | --- | --- |
| `evidence/prevent12-run.json` | `8a8b2e44a1e007a119d5cfdf73f30463f612fe62bb66ef02235c304db35ac924` | `81c04d9c245ac30f00fb3356dd95d62eb11801c77bd5cf984f14f68ea46d4493` |
| `evidence/prevent12-audit.json` | `4372ccf135890e9f982bf7b627b1705ec271a7299db9eb39b80f0f46cd900160` | `a27c582da1482102f1833521c5f0c68629f1dc607ca2556440a1a29e8bac0ca4` |

픽스처 잠금 해시: `37e0333c4bdf8d8627a13b1ac1468a905ac808067c781bd3310b03b740ef5bec`. 해시는 고정 비교 대상과의 차이를 찾아낸다. 외부 타임스탬프나 감사자 서명을 대신하지 않는다.

## 범위 밖

- 실제 자료를 쓴 학습과 평가, 임상 타당성, 사용성, 규제 적합성 판정.
- 승인 템플릿 문구의 임상 검토(12-2 명세의 가정 A1), 인가 사전의 내용(12-4), 지역 통계를 고립 유병률로 옮기는 관계식(12-3).
- 여러 서버 사이의 경합과 메시지 순서 뒤바뀜을 넣은 모형 검사(12-4 명세 3.4절).
