# 임계값을 만지지 않았다

> 126케이스 한 런에서 FAIL은 하나. 그 하나를 통과시키는 방법을 알고 있었고, 쓰지 않았다.

- 수치: FAIL 1건
- 상태: wip
- 사람이 보는 화면: https://aitryed.com/ko/writing/verdicts/threshold/
- 반대 언어: https://aitryed.com/en/writing/verdicts/threshold/index.md
- 이 사이트 안내(AI용): https://aitryed.com/ko/llms.txt

---

**케이스 126개를 돌려서 실패가 «하나» 나왔습니다. 그 하나를 통과시키는 방법을 알고 있었고, 쓰지 않았습니다.**

## 상황

자동 테스트를 한 번 돌렸습니다. **126개 중 실패 1개.**

그리고 저는 **그 하나를 초록색으로 만드는 방법을 알고 있었습니다.** 판정 기준을 조금만 느슨하게 하면 통과합니다. 한 줄 고치면 됩니다.

**안 고쳤습니다.** 이 글은 그 이야기입니다.

## 왜 안 고쳤나

기준을 느슨하게 하면 **그 케이스만 통과하는 게 아닙니다.** 그 기준을 쓰는 **나머지도 같이 느슨해집니다.**

| | 고치면 |
|---|---|
| 지금 실패한 1건 | **통과** |
| **지금 통과 중인 다른 건들** | **더 쉽게 통과** — 진짜 문제가 생겨도 안 걸림 |

즉 **보이는 실패 하나를 없애려고, 안 보이는 구멍을 여럿 만드는** 거래입니다.

그리고 그 구멍은 **당장은 아무 증상이 없습니다.** 전부 초록이니까요.

## 그런데 왜 이게 유혹인가

정직하게 적습니다. **고치고 싶었습니다.**

실패 1건이 있는 화면과 전부 통과인 화면은 **보기에 완전히 다릅니다.** 그리고 그 차이를 **한 줄로 없앨 수** 있습니다.

「기준이 너무 빡빡했던 것 같은데」라는 **그럴듯한 이유**도 얼마든지 붙일 수 있습니다. 그리고 **그게 사실일 수도** 있습니다 — 그게 이 유혹이 어려운 이유입니다.

가르는 질문은 하나였습니다.

> **이 기준을 바꾸는 근거가, 이 케이스를 만나기 «전»에도 있었나?**

없었습니다. **케이스를 만나고 나서 생긴 근거**였습니다. 그러면 그건 근거가 아니라 **핑계**입니다.

## 판정이 다섯 종류인 이유

이 런에서 쓴 판정은 **통과/실패 둘이 아니라 다섯**이었습니다.

칸이 둘뿐이면 애매한 게 전부 한쪽으로 밀립니다. 칸이 다섯이면 **애매한 것이 자기 자리에 앉습니다.**

그리고 자기 자리에 앉으면 **나중에 세어 볼 수** 있습니다 — 「확인 못 한 게 몇 건이지?」에 답할 수 있습니다.

## 제가 틀렸던 진단

이 런에서 제 진단도 한 번 틀렸습니다.

실패 원인을 처음에 한 가지로 봤는데, **확인해 보니 다른 것**이었습니다. 그리고 그 차이가 **처방을 완전히 바꿨습니다.**

그래서 이 글에 그 오진도 같이 적어 뒀습니다. **맞은 판정만 적으면 다음에 같은 오진을 합니다.**

## 그래서 남긴 것

> **초록색으로 만들 수 있는데 안 만들었다면, 「만들 수 있었다」는 사실까지 같이 적습니다.**

안 적으면 이 글은 **「제가 정직했습니다」 자랑**이 됩니다. 어떤 방법이 있었는지가 적혀 있어야, 읽는 사람이 **자기 상황에서 같은 유혹을 알아봅니다.**

## 여기부터는 자세한 기록입니다

126케이스를 완주했다. 937초. FAIL 하나.

그 하나를 통과시키는 방법은 알고 있었다. 판정 창을 30초에서 60초로 늘리면 된다. 한 줄이다.

## 판정이 다섯 종류인 이유

PASS와 FAIL만 두면 자동화는 거짓말을 한다. 확신이 없는 케이스가 갈 곳이 없어서 둘 중 하나로 밀려 들어가고, 밀려 들어가는 쪽은 대개 PASS다.

그래서 판정은 다섯이다. 로그 앵커로 기계가 단정할 수 있을 때만 PASS와 FAIL. 화면은 남겼는데 못 정하면 EVIDENCE. 실행 자체를 못 했으면 SKIP. 범위 밖이면 NA.

| 판정 | 건수 |
|---|---|
| EVIDENCE | 66 |
| SKIP | 39 |
| PASS | 16 |
| NA | 4 |
| FAIL | 1 |

가장 큰 덩어리가 EVIDENCE 66건이다. 기계가 혼자 단정한 건 절반이 안 된다는 뜻이고, 그 숫자를 감추지 않는 것이 이 분류의 목적이다.

## FAIL 하나

연속한 두 케이스가 같은 조작을 같은 로그 앵커로 판정하고 있었다. 앞 케이스가 30초를 기다렸고, 앵커는 그 뒤에 도착해 다음 케이스의 창에서 잡혔다.

이벤트는 정상 발생했다. 첫 번째 창이 놓쳤을 뿐이다. 제목이 같은 다른 네 건은 이번 런에서 전부 통과했고, 직전 런에서는 앵커가 30초 안에 도착해 이 케이스도 통과했다.

즉 결과가 타이밍에 좌우된다.

> 창을 늘리면 이번 런은 초록색이 된다. 원인은 그대로 남고, 다음 런에서 같은 자리가 다시 흔들린다.

구조 문제는 앵커 중복이다. 처방은 고유 앵커를 주거나 두 케이스를 합치는 쪽이고, 어느 쪽이든 기대값 확인이 먼저다. 이번 런은 FAIL 하나를 안고 닫았다.

## 내가 틀렸던 진단

SKIP 39건 중 9건이 "탭 대상 미매핑"으로 떴다. 좌표만 채우면 회수된다고 적었다. **가장 싼 커버리지 증가분이라고 썼다.**

틀렸다. 채워도 0건 회수된다.

위젯 덤프 7,455개를 통째로 떠서 확인하니 대상은 실재했고 이름도 다 있었다. 막힌 건 좌표가 아니라 도달이었다. 조상 컨테이너 하나가 비표시라 좌측 HUD가 통째로 접혀 있었고, 런 내내 한 번도 열리지 않았다.

| 인게임 덤프 72개 중 | 등장 |
|---|---|
| 우측 HUD | 72 |
| 좌측 HUD | 0 |

좌표를 넣으면 SKIP 사유가 "미매핑"에서 "동작 실패"로 바뀔 뿐이다. 커버리지를 늘리려면 매핑이 아니라 그 화면에 도달하는 경로가 필요하다.

문자열 하나가 진단을 통째로 잘못된 방향으로 끌고 갔다. 사유 문자열은 로그 장식이 아니라, 사람이 읽고 다음 행동을 정하는 인터페이스다.

## 어디에 시간이 갔나

937초 중 브리지 왕복이 302초(32.3%). 그중 위젯 트리 덤프 하나가 186초, 런 전체의 19.8%다.

판정할 때마다 트리를 통째로 받아오는 구조라 그렇다. 필요한 위젯만 묻는 호출을 두면 줄어든다 — 얼마나 줄어드는지는 도입 전후를 같은 케이스 셋으로 재봐야 안다.

이 숫자를 보기 전까지는 셰이더 컴파일이 병목인 줄 알았다.

## 판정

FAIL 1건은 제품 결함이 아니었다. 그렇다고 초록색으로 만들지도 않았다.

이 두 문장을 같이 쓸 수 있게 만드는 것이, 판정을 다섯으로 쪼개고 사유 문자열을 남기는 이유다.
