# [12-4] 외부 인가 사전 주입형 한국어 철자변형 강건 정서 위기 선별과 100% 즉시 상담사 전환 라우팅 — 설계 명세서

| 항목 | 내용 |
| --- | --- |
| 참조 하네스 | `prevent12/t124.py` (표준 라이브러리 전용) · 신경망 인터페이스 `torch_ref/t124_model.py` |
| 고정 입력 | `fixtures/t124_router.json` |
| 단위 시험 | `tests/test_prevent12.py`의 `Task124Tests` 9건 · Hypothesis 규격 7건 · PyTorch 시험 1건 |
| 실행·감사 | `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` (재현 기록) |
| 자료 범위 | 자리표시자 토큰과 코드 포인트로 만든 음절만 사용. 상담 말뭉치와 인가 사전 원문은 이 저장소에 없다 |

2026-11-14 기준. 공공 청소년 상담 플랫폼에서 위기 징후를 가려내면 자율 AI 응답을 곧바로 멈추고 사람 상담사와 공식 위기상담망(청소년상담 1388, 자살예방 상담전화 109)으로 빠짐없이 넘기는 분류·라우팅 소프트웨어의 명세다.

**계획 수치**는 내부 연구 목표(위기 감지 후 즉시 전환율 100%)다. **가상 시험 실측**은 prevent12 참조 구현을 고정 입력으로 돌린 값이다. 외부 코호트 실측과 감사자 서명은 없다.

## 안전 경계

- 실제 은어, 우회 표기, 상담 발화는 이 문서·코드·고정 입력·시험 어디에도 없다. 어휘가 필요한 자리는 `<PROTECTED_RISK_TERM_01>`, `<BENIGN_DISTRESS_SAMPLE>`, `<NEUTRAL_SAMPLE>` 같은 자리표시자다.
- 도메인 어휘는 인가 기관의 접근통제 저장소(`AuthorizedLexiconStore`)에서 실행 시점에만 온다. 소프트웨어에 들어오는 것은 키 해시뿐이고 원문은 들어오지 않는다.
- 12-4 코드와 고정 입력에는 한글 문자가 한 글자도 없다. 한글 음절이 필요한 시험은 코드 포인트 산술로 만든다. 이를 검사가 강제한다(1.3절).

**두 지표를 나눈다.** 즉시 전환율은 "위기로 감지된 턴 가운데 전환이 끝까지 완료된 비율"이고 소프트웨어 불변식으로 100%를 보장하는 대상이다. 선별 모형의 재현율은 "실제 위기 가운데 감지된 비율"이고 통계적 하한으로만 관리된다. 앞의 100%가 뒤의 누락을 없애 주지는 않는다(2.7절).

자료 적합성: 출처 등록부대로 후보 말뭉치는 만 7–12세 아동 상담이고, 중·고등학생의 표현과 다중 턴 위기 시점·전환 기록이 붙은 자료인지는 확인되지 않았다. 이 명세는 말뭉치의 **스키마**(정서 범주, 위기 등급, 턴 시각)만 전제한다.

## 평가 등록부와의 관계

평가 등록부는 12-4의 실제 종점을 "12–17세 학교 상담에서 처음 확인되는 위기 사건과 독립 확인 시각, 인계 요청·완료 시각"으로 정하고 감지 재현율과 감지 후 즉시 전환율의 분모를 따로 세도록 했다. 해당 말뭉치는 보류 상태다. 가상 인계 사건 6건과 공개 조사 집계는 명부로 고정돼 있다.

- 이 명세의 두 지표 구분은 등록부와 같다. 선별 모형을 실제로 평가할 때는 등록부의 학교 단위 60:20:20 분할을 따른다.
- 가상 인계 6건이 다루는 위반 유형(지연, 누락, 전환 뒤 자유 응답, 순서 오류)은 공통 시험이 대조한다. 이 명세는 같은 유형을 고장 조합 1,728개와 판정기 변형 시험으로 넓혀 확인한다.

## 1. 외부 사전 분리형 토크나이저와 인코더

### 1.1 한글 자모 정규화

| 단계 | 처리 |
| --- | --- |
| 1 | NFKC 정규화. 호환 자모, 반각 자모, 전각 문자가 표준형이 되고 초성+중성 나열은 음절로 합쳐진다. |
| 2 | 폭 없는 문자, 공백, 문장부호·기호를 지운다(끼워 넣기 우회 대응). |
| 3 | 음절 $c\in[\mathrm{U{+}AC00},\mathrm{U{+}D7A3}]$를 산술로 분해한다: $L=\lfloor(c-\mathrm{AC00}_{16})/588\rfloor$, $V=\lfloor((c-\mathrm{AC00}_{16})\bmod 588)/28\rfloor$, $T=(c-\mathrm{AC00}_{16})\bmod 28$. |
| 4 | 종성을 자음 기호로 바꾼다. 겹받침은 두 자음으로 나누고, 종성 이응은 별도 기호로 둔다. 소리 없는 초성 이응은 버린다. 그러면 받침을 다음 음절 초성으로 넘겨 쓴 표기가 같은 기호열이 된다. |
| 5 | 같은 기호의 연속은 하나로 줄인다(늘여 쓰기 대응). |
| 6 | 닮은꼴 문자·숫자 → 자모 대응은 **외부 표**로만 적용한다. 코드에 대응 쌍이 없다. |

결과는 기호열이다: 자음 `("C", 0..19)`, 모음 `("V", 0..20)`, 그 밖의 문자 `("A", 코드 포인트)`, 숫자 `("D", 값)`. 자음 골격(`skeleton`)은 모음을 뺀 열로, 초성만 적은 표기와 맞춘다.

종성 27개의 자음 대응표는 손으로 적었고, 시험이 유니코드 문자 이름과 대조한다. 구현: `to_symbols`, `skeleton`, `collapse`.

### 1.2 음운 유사도

자음은 (조음 위치, 조음 방법, 발성 유형), 모음은 (높이, 전후, 원순, 활음)의 자질 벡터를 갖는다. 대치 비용은 다른 자질의 비율이고 삽입·삭제 비용은 1이다.

$$c_{\text{sub}}(a,b)=\frac{\lvert\{f:\ \phi_f(a)\ne\phi_f(b)\}\rvert}{\lvert\phi\rvert},\qquad d(x,y)=\min_{\text{편집열}}\sum\text{비용},\qquad \mathrm{sim}(x,y)=1-\frac{d(x,y)}{\max(\lvert x\rvert,\lvert y\rvert,1)}$$

평음·경음·격음처럼 가까운 소리의 바꿔 쓰기는 비용이 작다. 자질이 모두 같은 모음 쌍은 거리 0이라 $d$는 유사거리다(삼각부등식은 성립한다). 구현: `phonetic_distance`, `similarity`.

### 1.3 외부 인가 사전 인터페이스

```python
class AuthorizedLexiconStore(Protocol):          # 인가 기관이 구현·운영
    def fetch(self) -> tuple[dict, bytes]: ...    # (서명된 묶음, 키 핸들)

class LexiconMatcherProtocol(Protocol):
    version: str
    def healthy(self) -> bool: ...
    def match(self, symbols) -> tuple[Match, ...]: ...   # Match(term_id, category, view, start, end)
```

- **묶음에는 원문이 없다.** 인가 기관 쪽 도구(`build_bundle`)가 용어를 1.1절 기호열로 바꾼 뒤 창별 HMAC-SHA256만 담는다. 키는 `보기:길이:해시`, 값은 불투명 용어 ID와 범주 코드다.
- **보기 두 가지.** `CANON`(전체 기호열)과 `SKELETON`(자음 골격). 골격 보기는 길이 3 이상인 용어만 허용한다.
- **대조.** 입력 기호열의 각 창을 같은 키로 해시해 찾는다. 정규화 뒤 정확 일치만 본다. 사전에 없는 새 변형은 1.4절 모형이 맡는다.
- **무결성과 실패 방향.** 묶음 전체에 서명이 있다. 서명이 안 맞거나 저장소에 닿지 못하면 대조기는 `healthy() == False`이고 규칙 판정은 `UNAVAILABLE`이다. 라우터는 이를 **위기 트리거**로 본다.
- **하드코딩 금지 검사.** `hangul_lines(path)`가 한글 코드 포인트가 든 줄을 찾는다. 대상은 `t124.py`, `torch_ref/t124_model.py`, 고정 입력 JSON 전부, Hypothesis 규격 파일 전부이고 기준은 0줄이다. 단위 시험과 독립 감사기가 각각 실행한다.

구현: `build_bundle`, `HmacLexiconMatcher`, `rule_verdict`, `hangul_lines`.

### 1.4 다중 작업 분류 모형

턴 $t$의 기호열을 인코더 $E$(기호 임베딩 → 3·5기호 합성곱 → 트랜스포머 → 마스크 평균)가 $u_t$로 바꾼다. 세션 문맥은 $g_t=\mathrm{GRU}\big([u_t;\ \log(1+\Delta_t)]\big)$다($\Delta_t$는 직전 턴과의 간격).

| 작업 | 출력 | 손실 |
| --- | --- | --- |
| 위기 등급(순서형, $K$단계) | $P(y_t>k)=\sigma\big(w^{\top}[u_t;g_t;m_t;d_t]-b_k\big)$, $b_1\le\dots\le b_{K-1}$ | 누적 이진 교차엔트로피, 높은 등급 누락에 가중 |
| 정서 범주(다중 라벨) | $\sigma(W_e u_t)$ | 이진 교차엔트로피 |
| 변형 표기 여부 | $\sigma(w_o^{\top}u_t)$ | 이진 교차엔트로피 |
| 정서가(문맥 급락 감지용) | $v_t=\tanh(w_v^{\top}u_t)$, 급락 $d_t=\tfrac{1}{t-1}\sum_{s<t}v_s-v_t$ | 평균제곱오차 |
| 대조 학습 | 표현 $x$와 그 변형 $x^{+}=\tau(x)$, $\tau\in\mathcal T$ | $\mathcal L_{\text{con}}=-\log\dfrac{e^{\mathrm{sim}(u,u^{+})/T}}{\sum_j e^{\mathrm{sim}(u,u_j)/T}}$ |

$m_t$는 사전 대조 결과의 불투명 특징(범주·보기별 일치 수)이다. 절단점은 $b_k=b_1+\sum_{i<k}\operatorname{softplus}(s_i)$로 두어 $P(y>k)$가 $k$에 대해 줄어들게 한다. 변형 군 $\mathcal T$는 자모 풀어 쓰기, 초성만 쓰기, 가까운 소리로 바꾸기, 구분자 끼우기, 늘여 쓰기, 닮은꼴 치환의 여섯 **종류**로 정의하고 예시는 싣지 않는다. 어려운 음성으로는 철자가 비슷한 무해 표현을 섞어 오탐을 누른다. 서브워드 갈래를 함께 쓸 때는 사전학습 인코더의 서브워드 표현 $u^{\text{sw}}_t$를 자모 갈래 표현과 이어 붙이고, 같은 턴의 두 표현을 양성 쌍으로 하는 같은 대조 손실로 정렬한다. 사전에 없는 변형 표기에서 서브워드가 깨져도 자모 갈래가 표현을 붙잡는다. 전체 손실은 $\mathcal L=\mathcal L_{\text{crisis}}+\lambda_1\mathcal L_{\text{emo}}+\lambda_2\mathcal L_{\text{obf}}+\lambda_3\mathcal L_{\text{con}}+\lambda_4\mathcal L_{\text{val}}$이다. 인터페이스: torch_ref/t124_model.py (`JamoEncoder(ids (B,L)) -> (B,dim)`, `CrisisScreen(ids (B,T,L), gaps (B,T), match (B,T,M)) -> dict`).

### 1.5 보수적 임계치와 트리거

모형 위험 확률은 $p_t=P(y_t\ge\text{위기 등급})$이다. $\theta_{\text{conservative}}$는 12-1 명세 2.4절의 순서통계량 방법으로 정한다. 보정 집합의 위기 양성 $n$건의 $p$를 오름차순으로 놓고 $k^{*}$번째를 임계치로 잡으면 확률 $1-\delta$ 이상으로 재현율이 $1-\alpha$ 이상이다. $\alpha=0.02$, $\delta=0.05$면 양성이 149건 이상 있어야 한다.

$$\text{트리거}_t=\big[p_t\ge\theta_{\text{conservative}}\big]\ \vee\ \big[\text{규칙 일치}\big]\ \vee\ \big[\text{모형 시간 초과·오류}\big]\ \vee\ \big[\text{사전 불능}\big]$$

논리합이므로 결합 재현율은 모형과 규칙 각각의 재현율보다 낮지 않다. 선별 구성요소가 답하지 못하는 경우도 트리거다.

## 2. 즉시 전환율 100% 보장 Fail-Closed 라우팅 상태기계

### 2.1 세션 래치

위기 래치는 세 곳에 있고 어느 하나라도 서 있으면 세션은 잠긴다. 한번 선 래치는 사람 상담사의 명시적 종결 말고는 내려가지 않는다.

| 래치 | 서는 시점 | 버티는 고장 |
| --- | --- | --- |
| 메모리 | 트리거 판정 직후, 어떤 입출력보다 먼저 | 저장소 장애 |
| 영속 | 전환 트랜잭션 커밋 | 프로세스 재시작 |
| 단말 | 연락처 패널을 받거나 단말 감시 타이머가 패널을 띄울 때 | 서버 충돌, 커밋 전 장애 |

### 2.2 생성 경로의 물리적 차단

생성 모형은 관문(`Gateway`) 뒤에만 있다. 기본값은 거부다.

- 생성은 "이번 세션·이번 턴의 `SAFE` 판정" 승인표가 있고 세션이 잠기지 않았을 때만 호출된다. 지난 턴의 승인표, 다른 세션의 승인표, 판정이 없는 요청은 거부된다.
- 생성물은 보내는 순간 다시 래치를 본다. 앞 턴에서 만들어 두고 아직 보내지 않은 응답은 트리거가 나면 취소되고 버려진다.
- 잠긴 세션의 다음 사용자 메시지는 선별을 거치지 않고 사람 채널로 간다.

참조 구현은 이를 객체 권한으로 모형화했다(생성기를 관문 객체만 쥔다). 배치에서는 생성 서비스를 별도 프로세스로 두고 관문 프록시와 네트워크 정책이 같은 규칙을 강제한다. 응용 코드에 버그가 있어도 생성 서비스에 닿는 길이 없다.

### 2.3 원자적 전환 절차

```
① 메모리 래치 (입출력 전에)
② 연락처 패널 직접 전송 ── 정적 구성(1388, 109), 저장소와 무관 ── 수신 확인이 없으면 단말 감시 타이머가 내장 패널 표시
③ 트랜잭션 { 영속 래치, 전환 티켓, 아웃박스(대기열 통지·패널 재전송·ACK 타이머) } ── 실패 시 정해진 횟수 재시도
      └ 모두 실패: 저하 모드 = 대역 외 호출 + 사고 기록
④ 상담사 대기열 배정 ── 포화면 예비 인력 풀로 넘김
⑤ ACK 사다리: 담당 상담사 → (시간 초과) 백업 당직자 → (시간 초과) 감독자 → (시간 초과) 공식 상담전화 연결 안내 + 사고 기록
```

③의 세 기록은 한 트랜잭션에서 함께 커밋되거나 함께 실패한다. 아웃박스 메시지는 멱등 키를 달아 적어도 한 번 전달한다. 사용자에게 공식 연락처를 보여 주는 ②는 저장소에 기대지 않으므로 ③이 실패해도 이루어진다. 서버가 ② 전에 죽으면 단말 감시 타이머가 내장 패널을 띄우고 단말 래치를 세우며, 재접속 때 단말 래치가 전환을 다시 일으킨다.

종결 상태는 `COUNSELOR_CONNECTED`(사다리 어느 단에서든 사람이 응답)와 `EXTERNAL_BRIDGE`(마지막 단: 공식 상담전화 연결 안내와 사고 기록) 둘이다.

### 2.4 고장 모형

| 차원 | 값 | 모형화한 상황 |
| --- | --- | --- |
| 모형 판정 | `SAFE` `RISK` `TIMEOUT` `ERROR` | 모형 시간 초과·오류 |
| 규칙 판정 | `NO_MATCH` `MATCH` `UNAVAILABLE` | 사전 저장소 불능 |
| 커밋 | `OK` `RETRY_OK` `FAIL` | 저장소 지연·장애 |
| 대기열 | `OK` `FULL` | 상담원 큐 포화 |
| 응답 | 1단 / 2단 / 3단 / 무응답 | 수신 확인 시간 초과 |
| 패널 수신 확인 | 있음 / 없음 | 네트워크 지연·유실 |
| 서버 충돌 | 없음 / 패널 전 / 커밋 전 | 프로세스 장애 |

조합은 4 × 3 × 3 × 2 × 4 × 2 × 3 = **1,728개**이고 그 가운데 트리거가 걸리는 것이 1,584개다.

### 2.5 불변식

트리거가 걸린 모든 턴에 대해:

| 불변식 | 내용 |
| --- | --- |
| R1 생성 차단 | 그 턴과 이후 모든 턴에서 생성 승인·AI 응답 이벤트가 없다 |
| R2 즉시 래치 | 트리거 이벤트 바로 다음이 메모리 래치다(저장·통지보다 앞) |
| R3 연락처 표시 | 서버 패널 수신 확인 또는 단말 감시 패널 가운데 하나가 한도 시간 안에 있다 |
| R4 단말 래치 | 단말 래치가 선다(서버 충돌 뒤 복구의 근거) |
| R5 전환 완료 | 종결 상태가 둘 중 하나이고 한도 시간 안에 닿는다 |
| R6 폴백 경로 | 커밋 전부 실패 → 저하·대역 외 호출·사고 기록. 큐 포화 → 예비 풀. 충돌 → 재전환. 무응답 → 상담전화 연결 안내·사고 기록 |

$$\text{즉시 전환율}=\frac{\lvert\{\text{트리거 턴}:\ R1\wedge\dots\wedge R6\}\rvert}{\lvert\{\text{트리거 턴}\}\rvert}$$

시간 한도는 구성값의 함수다: 패널 $\le\max(T_{\text{screen}}+T_{\text{push}},\ T_{\text{watchdog}})$, 종결 $\le$ 패널 한도 $+T_{\text{reconnect}}+N_{\text{commit}}T_{\text{commit}}+3\,T_{\text{ack}}$. 참조 고정 입력의 값(선별 300 ms, 패널 50 ms, 감시 1,500 ms, 재접속 3,000 ms, 커밋 100 ms × 3, 응답 대기 20,000 ms × 3)은 가상 매개변수이며 운영 약속이 아니다.

### 2.6 가정

R1–R4는 조건 없이 성립해야 하는 안전 성질이다. R5(끝까지 닿음)는 다음 가정 아래의 성질이다.

- F1: 서버 충돌 뒤 단말이 다시 접속한다. 접속하지 못해도 R3의 내장 패널은 이미 떠 있다.
- F2: 공식 연락처 패널이 단말에 정적으로 실려 있고 번호가 최신이다.
- F3: 사다리 마지막 단(상담전화 연결 안내)은 사람의 응답을 요구하지 않는 동작이다.

고장 모형 밖의 일(단말 전원 꺼짐, 통신 전면 두절)은 이 불변식이 다루지 않는다.

### 2.7 모형이 놓친 위기에 대한 보완 통제

전환율 100%는 감지된 건에 대한 보장이다. 감지되지 않은 건을 위해 (a) 모든 화면에 사람 연결 버튼과 공식 연락처를 늘 둔다, (b) 보수적 임계치와 규칙의 논리합을 쓴다, (c) 세션 안에서 매 턴 다시 선별한다, (d) 선별 구성요소가 불능이면 생성 자체를 닫는다.

## 3. 형식·속성 기반 검증과 지연·무누락 시험

### 3.1 전수 열거

고장 조합 1,728개 전부에 대해 한 턴을 실행하고 이벤트 추적으로 R1–R6을 판정한다(`run_scenarios`, `check_turn`). 세션 수준에서는 선별 결과 쌍 144개(12 × 12)에 무해한 셋째 턴을 붙여, 트리거 뒤 턴이 전부 사람 채널로만 가는지 본다. 미전송 응답이 있는 상태에서 트리거가 걸리는 11가지도 따로 본다(`run_sessions`).

### 3.2 Hypothesis 규격

test_t124_properties.py. 입력은 자리표시자 토큰과 실행 중에 코드 포인트 범위에서 뽑은 음절뿐이다.

| 속성 | 내용 |
| --- | --- |
| `test_single_turn_invariant` | 임의 고장 일정에서 R1–R6과 시간 한도 |
| `test_once_latched_no_ai_output_ever_returns` | 임의 길이(1–8턴)의 고장 일정 열에서 래치 뒤 AI 출력 0건, 전달 수 = AI 응답 이벤트 수 |
| `test_placeholder_screening_survives_obfuscation` | 자리표시자에 구분자·폭 없는 문자·대소문자·늘여 쓰기를 임의로 넣어도 판정 불변 |
| `test_screen_then_route_end_to_end` | 사전 대조 → 고장 일정 → 라우팅을 이어서, 위험 토큰·사전 불능·모형 이상 가운데 하나라도 있으면 전환 종결 |
| `test_normalisation_ignores_inserted_noise_and_encoding_form` | 임의 음절열의 잡음 삽입·분해형(NFD, NFKD) 불변 |
| `test_phonetic_distance_is_a_pseudo_metric` | 동일성, 대칭, 삼각부등식 |
| `test_gateway_is_default_deny` | 승인표·세션·턴·래치의 임의 조합에서 허용은 정확히 한 경우뿐 |

### 3.3 독립 감사와 변조 반려

독립 감사기(audit.py)는 라우터를 불러오지 않는다. 고장 코드와 시간 구성만으로 **기대 이벤트열과 패널·종결 시각을 따로 만들어** 제출된 추적 1,728개와 한 건씩 대조하고, 그 위에서 R1–R5와 요약 수치를 다시 센다. 폴백 가지(감시 패널, 충돌, 저하, 예비 풀, 상담전화 연결 안내)가 모두 실제로 실행됐는지도 확인한다.

변조 시험: 트리거 뒤에 AI 응답을 끼운 추적, 래치 뒤 AI가 다시 응답하는 세션, 패널 시각을 한도 밖으로 바꾼 행, 시나리오 한 줄 삭제, 사전 위조 판정 변경을 각각 넣으면 감사가 실패한다. 풀이 쪽 판정기(`check_turn`)에도 추적에서 이벤트를 하나씩 빼거나 늦춘 9가지 변형을 넣어 각각 해당 위반 코드가 나오는지 본다.

### 3.4 형식 명세로 옮길 때의 불변식

상태 변수 `latched`, `aiDelivered`, `panelShown`, `state`에 대해 모형 검사기로 옮길 성질은 다음과 같다.

```
Safety    ==  [] (latched => ~aiDelivered')            \* R1: 래치 뒤에는 AI 전달이 일어나지 않는다
Monotone  ==  [] (latched => latched')                 \* 래치는 내려가지 않는다
Display   ==  [] (trigger => <> panelShown)            \* R3
Liveness  ==  [] (trigger => <> state \in {COUNSELOR_CONNECTED, EXTERNAL_BRIDGE})   \* R5, 가정 F1–F3 아래
```

참조 구현의 고장 공간은 유한하고 작아서 전수 열거가 곧 이 성질들의 유계 모형 검사다. 메시지 순서 뒤바뀜이나 여러 서버 사이의 경합까지 넣으려면 별도의 모형 검사 명세가 필요하고, 이번에는 작성하지 않았다.

## 4. 가상 시험 실측 (고정 입력, 2026-11-14)

| 항목 | 값 |
| --- | --- |
| 정규화 등가 | 8종 × 200회 전부 일치(호환 자모 풀어 쓰기, 조합형 자모, 폭 없는 문자, 구분자, 늘여 쓰기, 받침 넘겨 쓰기, 초성만 쓰기, 가까운 모음) |
| 한글 문자 검사 | 모듈 0줄, 고정 입력 0줄 |
| 사전 대조 | 자리표시자 4개 × 변형 7종 = 28건 전부 기대와 일치(위험 토큰은 일치, 무해 토큰은 불일치) |
| 사전 위조·부재 | 둘 다 `UNAVAILABLE` |
| 고장 조합 | 1,728개, 트리거 1,584개 |
| **즉시 전환율** | **1,584 / 1,584** |
| 트리거 뒤 AI 출력 | 0건 |
| 연락처 표시까지 | 최대 1,500 ms (한도 1,500 ms) |
| 종결까지 | 최대 64,800 ms (한도 64,800 ms) |
| 세션 | 144개에서 래치 뒤 AI 재개 0건, 미전송 응답 11건 전부 폐기 |

**보증 범위.** 전환율 100%는 감지된 턴에 대해, 2.4절 고장 모형의 1,728개 조합 안에서 성립하고, 그 가운데 R5(종결 도달)는 가정 F1–F3 아래에서 성립한다. 감지되지 않은 위기(선별 모형의 누락), 고장 모형 밖의 상황, 실제 운영 환경의 지연에는 적용되지 않는다.

읽는 법: 전환율 100%는 2.4절 고장 모형 안의 모든 조합에서 불변식이 성립했다는 뜻이다. 선별 모형은 학습하지 않았으므로 감지 재현율 수치는 없다. 시간은 가상 구성값의 합이고 실제 지연 측정이 아니다.

## 5. IEC 62304 추적

전환이 빠지거나 늦으면 중대한 위해에 이를 수 있으므로 라우터·관문·래치 단위는 잠정 Class C로 둔다(IEC 62304:2006+AMD1:2015의 위험 기반 분류, 최종 분류는 위험관리 결과로 확정). 표준 본문(4.3절)은 유료라 열지 못했고 분류 문구는 2차 요약으로 확인했다.

| 요구 | 단위 | 검증 | 위험 통제 |
| --- | --- | --- | --- |
| SRS-124-01 어휘 비내장 | `LexiconMatcherProtocol`, `build_bundle`, `hangul_lines` | `test_no_hangul_in_code_fixtures_or_specs`, `test_lexicon_bundle_holds_no_term_text_and_fails_closed`, 감사 G2 | 은어 목록 유출 |
| SRS-124-02 변형 표기 정규화 | `to_symbols`, `skeleton` | `test_spelling_variants_meet_in_one_form`, `test_coda_table_agrees_with_the_unicode_database` | 우회 표기 미감지 |
| SRS-124-03 선별 실패 방향 | `rule_verdict`, `model_verdict` | `test_lexicon_bundle_holds_no_term_text_and_fails_closed` | 구성요소 장애 시 무감지 |
| SRS-124-04 생성 차단 | `Gateway` | `test_gateway_is_default_deny`, Hypothesis `test_gateway_is_default_deny` | 위기 중 AI 응답 |
| SRS-124-05 전환 완결 | `handle_turn`, `check_turn` | `test_every_fault_schedule_ends_in_a_handoff`, 감사 G3의 추적 재구성 | 전환 누락·지연 |
| SRS-124-06 래치 지속 | `Session`, `run_sessions` | `test_latch_survives_later_turns_and_cancels_inflight_output` | 전환 뒤 AI 재개 |
| SRS-124-07 판정기의 검출력 | `check_turn` | `test_checker_detects_broken_traces` | 검증 도구의 거짓 통과 |

## 6. 확인한 원문

이번 세션의 하위 작업자가 2026-11-14에 원문을 열어 대조했다.

- 109는 2024-01-01 개통한 자살예방 상담전화다. 1388의 공식 명칭은 청소년상담 1388이고 365일 24시간 운영이다. [보건복지부 보도자료](https://www.mohw.go.kr/board.es?mid=a10503010100&bid=0027&act=view&list_no=1479607&tag=&nPage=1) · [109 안내](https://www.129.go.kr/109) · [청소년상담 1388 안내](https://www.mogef.go.kr/cc/ccy/cc_ccy_f001.do)
- 순서통계량 임계치의 위반 확률 상계와 최소 표본 식. [Tong, Feng, Li (2018)](https://arxiv.org/abs/1608.03109)
- IEC 62304 현행판 식별과 FDA 인정 번호. [IEC 웹스토어](https://webstore.iec.ch/en/publication/22794) · [FDA 인정 표준](https://www.accessdata.fda.gov/scripts/cdrh/cfdocs/cfstandards/detail.cfm?standard__identification_no=38829)

한글 음절의 산술 분해와 호환 자모의 정규화는 유니코드 표준의 정의를 썼고, 구현은 파이썬 표준 라이브러리의 유니코드 데이터베이스와 대조하는 시험으로 확인했다. 순서형 누적 로짓과 대조 손실은 표준 형식을 썼고 원문을 따로 열지 않았다.
