블로그 목록

검토 5라운드 회수 43건: 직전 수정이 만든 회귀 8건

검토 다섯 라운드에서 43건을 회수했는데 그중 8건은 직전 라운드의 회수가 만든 오류였다. 거짓 양성을 고치면 같은 무게의 거짓 음성이 생기고, 검토 레인이 죽으면 빈 배열이 초록으로 읽힌다. 반쯤 고친 자리들의 기록.

공개 조회 2

웹소설 집필 도구를 만들고 있다. 이번 판에서 고치려던 것은 하나였다. 끌 수 없는 경고.

세 자리에서 같은 일이 벌어지고 있었다. 원고 폴더에 규칙 문서(README.md)를 두면 매 실행 "대조에서 빠진 파일" 경고가 떴다. 복선이라 일부러 비워 둔 칸에도 매번 "채워야 스캔된다"가 붙었다. 키워드 조용이 「조용해야 했다」라는 은신 서술 네 줄에 걸려서 가장 무거운 진단인 정보 격차 위반 후보로 올라갔다.

셋 다 옳은 경고를 내려다 만든 것이다. 그런데 매번 뜨는 경고는 곧 안 보게 되고 안 보기 시작하면 같은 자리의 진짜 결함도 같이 묻힌다. 프롤로그.md가 대조에서 빠진 것과 원고 폴더의 README 가 같은 줄에 뜬다.

첫 수정과 첫 되돌림

낱말 경계를 넣었다. 키워드 앞에 한글이 붙어 있으면 다른 낱말의 꼬리로 보고 뒤에 한글이 이어지면 그게 조사일 때만 등장으로 센다.

로컬 검사 17개가 전부 초록이었다. 그 상태로 독립 검토를 띄웠다. 검토 쪽에서 원고 여섯 편을 직접 만들어 돌려 보고 이렇게 짚어 왔다.

스승 → hits 0 / filtered 3
현수막 → hits 0 / filtered 3
query --spoiled → ## 들킨 반전 후보 / _없음_

원고에 「스승님」이 여섯 번 나오는데 키워드 스승의 등장이 0이었다. 조사만 받고 님·들 같은 접미사를 안 받은 탓이다. 거짓 양성을 고치면서 같은 무게의 거짓 음성을 만들었다.

이게 다섯 라운드 내내 반복된 형태다. 회수 43건 중 8건이 직전 라운드의 회수가 만든 오류였다.

한 자리를 네 번 놓친 기록

가장 오래 걸린 건 /wn-adopt --force 였다. 기존 프로젝트를 다시 등록하는 명령인데, 작가가 손으로 적은 설정을 지우고 있었다.

1차로 설정을 통째로 갈아끼우던 코드를 update 로 바꿨다. 2라운드가 짚었다. 그 cfg 는 기본값 사본이라 update 가 기본값을 덮을 뿐이고 코드는 안 고쳐졌다. 주석과 패치노트만 참이 됐다.

2차로 기존 설정을 바닥에 깔고 병합했다. 3라운드에서 두 레인이 각각 돌려 보고 같은 걸 짚어 왔다. 덮을지 말지를 "값이 다른가"로 판단했는데, 덮는 쪽이 기본값 사본이라 기본값이 작가 값을 이겼다.

before: title='내 작품', exclude=['메모*.md'], count_whitespace='exclude'
after : title=None,     exclude=['README*', ...], count_whitespace='include'

3차로 추론 함수가 자기가 실제로 채운 키 목록을 같이 돌려주게 했다. 판단이 "값 비교"에서 "출처 확인"으로 바뀌었다.

4라운드가 네 번째를 짚었다. 그 목록에 paths.index·style_profile·reveal 이 들어 있었는데, 그건 찾은 값이 아니라 박아 둔 문자열이다. 작가가 설정/색인 으로 옮겨 둔 경로가 .webnovel/index 로 되돌아갔다.

5라운드가 다섯 번째를 짚었다. paths.aliases 도 같았다. 그건 bible 로 조립한 값이지 찾은 값이 아니다.

위치로 가를 수 없는 것

4라운드에서 회수 계획 판정도 고쳤다. 「영구 미공개」가 회수 계획으로 판정되고 있었다. 공개 를 부분 문자열로 찾아 「미공개」 안에서 걸린 것이다. 함께 "안 하기로 정한 것은 회차 번호가 붙어 있어도 계획이 아니다"를 넣었다.

5라운드가 그 수정이 만든 회귀를 짚었다.

17화에 회수. 그 전까지는 밝히지 않는다   → 계획인데 미기입으로 떨어짐
3부 중반에 공개, 그 전에는 안 밝힌다     → 계획인데 미기입으로 떨어짐

노출 시점을 적는 가장 흔한 형태가 전부 사라졌다. 그런데 「3부에서 안 밝히기로 결정」은 거부가 맞다.

셋의 구조가 문제였다. 셋 다 지점이 부정보다 앞에 온다. 앞뒤 순서로는 구분이 안 된다. 쉼표와 마침표로 절을 나눠서 거부도 미결도 없는 절에 회수 지점이 있으면 계획으로 판정하도록 바꿨다. 그러자 셋이 갈렸다.

자기 규격이 자기 추론을 깬 자리

5라운드가 하나 더 짚었다. 바이블 정본 파일 이름 00-core.md 가 회차 패턴 ^(\d{1,4})[\s_.-] 에 걸려 0화로 읽히고 있었다. 설정 디렉토리가 회차 디렉토리로 세어지고, 원고 루트 추론이 두 디렉토리의 공통 조상으로 밀리고, --force 가 그 값을 저장해 작가의 paths.manuscript 가 "." 이 됐다.

이 도구가 만들라고 시킨 파일 이름이 이 도구의 추론을 깬 것이다.

오래 안 보인 이유가 있다. --force 가 값을 보존하지 않던 시절에는 이 추론이 틀려도 그냥 틀린 채로 덮였다. 보존을 넣고 나서야 "무엇을 덮고 무엇을 안 덮는가"가 중요해졌고 그때 추론의 정확도가 처음으로 문제가 됐다.

검토 레인이 죽고 초록을 반환한 자리

4라운드는 12개 에이전트 중 11개를 세션 한도로 잃었다. 최종 반환은 이랬다.

{"total":10,"now":[],"issue":[]}

겉보기에는 아무 문제 없음이다. 살아남은 것은 지적을 낸 레인 하나였고 죽은 것은 그 지적을 검증하는 쪽이었다. 검증이 없으면 결과 배열이 비고, 비면 초록으로 읽힌다.

반환값을 안 믿고 실행 기록에서 원본 지적 10건을 꺼내 직접 돌려 봤다. 10건 전부 재현됐고 그중 셋이 심각한 것이었다.

이 저장소는 무인 판정 도구에 "조회 실패와 할 일 없음은 다른 결과다"를 종료 코드로 박아 뒀다. 검토 레인에는 안 박혀 있었다.

검사로 고정하고 죽여 보기

같은 판단 셋이 라운드마다 반대 방향으로 틀렸다. 라운드마다 예를 새로 만들어 확인했고 그 예는 어디에도 안 남았다.

통합 점검 스크립트에 케이스 표를 넣었다. 낱말 경계 13개, 회수 계획 판정 19개, 건수 선언 15개. 각 줄이 실제로 한 번씩 틀렸던 자리다. --force 값 보존도 같은 형태로 고정했다.

그리고 검사를 각각 죽여 봤다. 저장소 밖에 스킬 폴더를 복사해서 절 규칙과 병합 루프를 원래대로 되돌린 뒤 돌렸다.

❌ 판정식 회귀 케이스 | 의도 「150화까지 비공개, 151화에 공개」 True≠False ...
❌ --force 가 작가 값을 보존 | manuscript.exclude: ['메모*.md']→['README*', ...]

붉어지지 않는 검사는 없는 검사다.

고친 뒤의 값

같은 원고 여섯 편에서 키워드 스승의 등장이 0에서 4로 돌아왔고 「들킨 반전」이 _없음_에서 실제 후보를 낸다. 경계에서 걸러진 히트는 수만이 아니라 꼬리 문자열까지 나온다.

--force 재등록에서 보존되는 키가 0개에서 13개가 됐다. 커밋되는 설정 파일에 윈도우 경로 구분자가 안 들어간다.

결함이 하나도 없는 프로젝트가 "이상 없음"에 도달한다. 전에는 건수 선언 문장이 없다는 이유로 영구히 경고 1건이었고 이 도구가 배포하는 문서 틀에는 그 문장이 없다.

통합 점검은 55개에서 58개가 됐다. 회귀 케이스는 0개에서 47개다.

남은 것

조사 목록이 못 담는 꼬리가 있다. 「현수막이었고」의 이었고 같은 연결형이다. 목록을 넓히면 「조용해야」류가 다시 들어오므로 안 넓혔다. 대신 걸러낸 꼬리를 화면에 적는 것으로 두었다. 이게 충분한지는 실제 원고에서 재 보지 않았다.

두 음절 이상 키워드의 접미사 오탐도 남았다. 아가가 「아가씨」에 걸린다. 음절 수 조건으로는 못 가른다.

"확인 못 함" 사유에서 경로를 줄이는 처리가 윈도우 드라이브 경로만 본다. 리눅스 절대경로는 그대로 남는다. 이 도구를 쓰는 사람 대부분이 윈도우라 뒤로 미뤘고 미뤘다는 사실만 적어 둔다.

다음부터

판단 경계를 고치는 수정을 여러 번 되풀이할 때는 매번 틀렸던 예를 거짓 양성과 거짓 음성 양쪽으로 회귀 케이스에 남기고, 고친 코드를 되돌렸을 때 그 케이스가 실제로 실패하는지 확인한다. 지적을 내는 쪽과 검증하는 쪽을 따로 돌릴 때는 빈 결과를 문제 없음으로 받기 전에 검증 쪽이 끝까지 살아 있었는지 먼저 본다.

댓글

아직 보이는 댓글이 없습니다.

댓글 쓰기

댓글은 관리자가 승인한 뒤에 보입니다. 이메일은 공개하지 않습니다.

개인정보 수집·이용 동의 (필수)
  • 수집 항목: 이름, 이메일, 댓글 내용
  • 목적: 댓글 게시와 관리, 댓글에 관한 연락
  • 보유 기간: 이름과 내용은 댓글을 게시하는 동안, 이메일은 1년. 게시하지 않은 댓글은 90일 뒤에 지웁니다.
  • 스팸을 막으려고 접속 IP 주소를 90일 동안 저장합니다. 이 저장은 동의가 아니라 운영자의 정당한 이익에 근거합니다.
  • 동의를 거부할 권리가 있습니다. 거부하면 댓글을 쓸 수 없습니다. 자세한 내용은 개인정보처리방침에 있습니다.