목록으로

검사가 본 단위와 실패한 단위: 어긋난 자리 3종

1 조회
개발 도구 신뢰성
#검증#테스트 설계#Claude Code#웹소설 툴킷

TL;DR

  • 회차 단위 검사를 스무 화가 전부 통과했는데, 통째로 읽히니 한 화 안에서는 안 보이는 것이 4건 나왔다
  • 개고 패치를 적용했더니 본문에 해설이 섞였다. 유일성 검사와 줄바꿈 검사가 둘 다 통과했고 걸린 것은 자수 72자였다
  • 셋 다 검사가 본 단위와 실패한 단위가 달랐다. 회차와 여러 화 범위, 문장과 기한, 치환 횟수와 치환된 내용이다
  • 세는 단위를 하나 더 뒀다. 회차 검토 뒤에 16화에서 24화 범위를 한 번 더 센다

웹소설 집필 도구를 만들고 있다. 이번 판에 밀린 요청 셋을 반영했는데, 증상이 전혀 다른 셋이 같은 모양이었다.

지난 판들에서 고친 것은 매번 검사 자체였다. 이번 셋은 검사를 고쳐도 안 잡힌다.

회차 검사가 통과시킨 되풀이 4건

한 프로젝트가 20화까지 썼다. 회차 단위 검사는 전부 통과했다. 매 화 사이다가 있고 매 화 주인공이 뭔가 하나는 얻는다.

그 20화를 설정집 없이 통째로 읽혀 봤다. 이런 것들이 돌아왔다.

잡힌 것회차 단위로 안 보이는 이유
사이다 10개 중 8개가 같은 형태각 화에는 사이다가 있다
주인공의 판단이 7번 나오고 한 번도 안 틀린다각 화에서는 정보 우위를 보여주는 장면이다
독자가 주인공에 대해 새로 안 것이 0회차마다 공개 건수를 세는 자리가 없다. 오래 안 열린 것을 세는 표는 있는데 그건 30화를 기준으로 본다
같은 문장이 응원 자리마다 4번각 화에서는 문체가 일관된 것이다

넷 다 한 화 안에서는 정상이다. '몇 가지였나'는 한 화 안에 없는 물음이라서 그렇다. 못 잡은 게 아니라 그 물음을 물을 자리가 없었다.

돌아온 결론은 이랬다. 20화 끝에서 독자가 주인공을 1화보다 덜 알고 있다.

치환이 정확히 1회 일어났는데 본문이 오염된 자리

같은 프로젝트에서 문체 개고를 다른 에이전트에 맡겼다. 찾을 문자열과 바꿀 문자열을 적은 패치 문서를 주고받는 방식이다.

에이전트가 치환 블록 뒤에 판단 근거를 산문으로 덧붙였다. 파서는 블록의 끝을 다음 제목으로 추정했고 그 사이의 산문이 통째로 치환 문자열이 됐다. 원고 본문에 이런 줄이 들어갔다.

10화의 나머지 두 갸웃(155행 처마 끝 · 277행 나란히 말하고)은 둘 다 계기가 안 맞는 자리라
정의에 맞는다. 손대지 않았다.

두 화가 그렇게 오염됐다. 검사 두 개가 돌고 있었는데 둘 다 통과했다.

  • 유일성 검사: 찾을 문자열이 원고에 몇 번 나오는지 센다. 정확히 한 번이었다
  • 줄바꿈 검사: CRLF 가 섞였는지 본다. 안 섞였다

둘 다 '어떻게 바뀌었나'를 볼 뿐 '무엇이 들어갔나'를 안 본다. 걸린 것은 자수였다. 13화가 5,969자여야 하는데 6,041자로 나왔다. 방향이 반대라 이상해서 diff 를 열어 본 것이 우연이었다.

여기서 가져갈 것은 한 줄이다. 치환 도구로 파일을 고쳤으면 늘어난 줄을 전부 본다.

git diff -U0 -- <원고 디렉토리> | grep '^+' | grep -v '^+++'

빈 결과는 통과가 아니다. 고친 쪽이 이미 커밋했으면 기준점이 지나간 것이라 이 명령은 0줄을 낸다. 그 화면은 '검사했고 깨끗하다'와 똑같이 생겼다.

문장 하나로 완결돼서 아무도 안 묻는 결정

같은 프로젝트의 설계 문서에 이런 줄이 있었다.

| 4 | 그는 여기서 해야 할 일이 있다. 무엇인지는 안 밝힌다 | 1화 |

'안 밝힌다'가 그 자체로 완결된 문장이라 검토를 통과한다. 읽는 쪽은 작가가 정해 뒀다고 읽고, 쓰는 쪽은 나중에 정하겠다고 남겨 둔다. 언제 밝히는지는 어디에도 없었다.

20화를 다 쓴 뒤 나눠 읽혔더니 읽은 쪽마다 이걸 최상위 문제로 짚어 왔다. 그 자리는 시한이 채우고 있었는데 시한은 '이 사람이 죽을까'를 궁금하게 만들지 '무엇을 하려는가'를 궁금하게 만들지 않는다.

설계 문서를 검사하는 쪽에서 보면 그 줄에는 흠이 없다. 주어가 있고 서술어가 있고 결정 표에 들어가 있다. 빠진 것은 그 문장 안이 아니라 그 문장이 안 가진 칸에 있다. 문장 단위로 훑는 검사는 없는 칸을 못 센다.

세 경우의 공통 모양

flowchart LR
  A[회차 단위 검사 통과] --> Z[통과가 아무것도 안 말한 자리]
  B[치환 유일성과 줄바꿈 검사 통과] --> Z
  C[설계 문서 문장 검토 통과] --> Z
검사가 본 단위실제로 실패한 단위
회차 하나16화에서 24화 범위
문장 하나그 문장에 없는 기한
치환 횟수와 줄바꿈치환으로 들어간 내용

셋 다 통과했고 셋 다 틀렸다. 검사가 약해서가 아니라 보는 자리가 달라서다. 이 글의 핵심 사실은 이 한 줄이다. 검사가 본 단위와 실제로 실패한 단위가 다르면 통과는 아무것도 말하지 않는다.

처리와 개선

검사를 늘리지 않았다. 세는 단위를 하나 더 두는 쪽으로 갔다.

  • 회차 검토를 다 돌린 뒤에 16화에서 24화 범위를 한 번 더 센다. 항목은 넷이고 webnovel-toolkit/skills/webnovel-review/SKILL.md 에 있다
  • 설계에 '안 밝힌다'가 있으면 둘을 되묻는다. 언제 밝히는지, 그때까지 독자는 무엇으로 버티는지
  • 원고를 고쳐 넣었으면 늘어난 줄을 전수로 본다
  • 종류를 가르는 기준은 검토자가 그 자리에서 정하고 한 줄로 적는다
  • 공개 건수를 셀 때는 고른 기준을 함께 적는다

항목 넷은 위 표의 넷 그대로다. 처음 제안은 여섯이었는데 둘이 실측 밖 추정이라 뺐다. 아직 한 번도 안 터진 것에 검사를 붙이면 고칠 곳만 는다.

범위를 잘못 잡으면 이 검사도 같은 문제를 낸다. 그래서 16화에 못 미치는 범위를 닫는 것이면 쓰지 말라는 줄을 넣었다. 이 배제 조건을 종류 이름으로 적으면 그 종류의 크기 범위와 검사의 하한이 겹치는 구간이 통째로 막힌다. 사건 묶음은 5화에서 20화이고 새 검사의 하한은 16화다. 16화에서 20화짜리 사건 묶음은 이 검사가 정확히 맞는 대상인데 이름만 보고 걸린다. 배제 조건은 종류가 아니라 수로 적는다.

수치는 이렇다. 회차 검토가 끝난 뒤에 보는 항목이 0개에서 4개가 됐다. 저장소 검사 개수 21개 그대로, 발화 테스트 94개에서 103개, 엉뚱한 스킬로 가는 건수는 6으로 같다. 이 도구는 사람이 말한 문장이 어느 기능으로 붙는지를 문서의 설명문으로 정하는데, 기능을 넣고 그 설명문을 안 고치면 만든 기능에 아무도 도달하지 못한다. 그래서 기능 하나에 발화 예시를 함께 넣는다. 넣은 뒤 엉뚱한 곳으로 가는 건수가 늘지 않는지 본다. 늘어도 실패고 줄어도 실패다. 줄면 기준을 내려 적으라는 뜻이다.

남은 것

새로 둔 4항목을 원래 놓쳤던 그 20화에 되돌려 돌려 보지 않았다. 그 원고가 저장소 밖에 있어 같은 상태로 다시 만들 수가 없다. 이 검사가 붉어지는 것을 본 적은 아직 없다.

'같은 방식'을 가르는 기준표가 없다. 색인이 사이다에 붙이는 값은 세기 0에서 3과 계기를 적는 자유 문자열뿐이고, 종류를 적는 칸은 아예 없다. 두 사람이 같은 원고에서 비슷한 수를 내는지는 안 재 봤다. 재려면 같은 원고를 두 사람이 따로 세는 표본이 필요한데 그 표본이 없다.

어떤 설정이 몇 화에 처음 나왔고 몇 화에 독자에게 공개됐는지를 적어 두는 파일이 따로 있다. 그 파일의 공개 목록에 인물 필터가 없다. 주인공에 대한 것만 사람이 골라야 해서 그 숫자는 도구가 결정적으로 내는 값이 아니다. 필터를 붙이려면 인물을 무엇으로 식별할지부터 정해야 하는데 그건 안 정했다.


댓글

댓글 작성