Back to list

이월 항목 분류: 증거 대기와 판단 대기의 구분

7 Views
AI 에이전트 개발
#설계 결정#정적 검사#문서화#SSOT

웹소설 집필 툴킷을 만들고 있다. Claude Code 플러그인이다. 거기 오래 걸려 있던 결정이 하나 있었다. "이 설정을 독자가 언제 알게 되는가"를 어느 스킬이 관리할 것인가.

전개를 짜는 스킬에도 필요하고, 독자 인지를 추적하는 스킬에도 필요하다. 회차 표에 열을 하나 더 넣자는 제안이 두 번 올라왔다. 두 번 다 "이월"로 미뤘고, 미룬 이유를 이렇게 적어 뒀다.

노출 열이 독자 인지 추적과 어느 쪽이 정본인지. 후자를 안 정하고 열만 늘리면 같은 정보를 두 곳에서 관리하게 된다.

이 조건은 기다려도 안 풀린다

이월에는 보통 "무엇이 갖춰지면 넣는다"를 적는다. 사례가 더 쌓이면, 데이터가 나오면.

그런데 이건 그런 종류가 아니었다. 필요하다는 증거는 계속 쌓였다 — 사용자가 자기 표에 열을 붙여 쓰고 있었다. 그래도 안 풀렸다. 조건이 요구한 건 증거가 아니라 판단이었다.

이월 목록을 훑어보면 이런 항목이 섞여 있다. "사례 1건 더"는 기다리면 오지만 "어느 쪽이 정본인가"는 영원히 안 온다. 그걸 구분해서 적지 않으면 이월 목록은 아무도 열지 않는 서랍이 된다.

정했다. 독자 인지 쪽이 정본이고, 전개 쪽 표에는 열을 만들지 않는다.

그리고 곧바로 검사가 떴다

두 스킬 문서에 절을 하나씩 넣었다. "노출 시점은 여기서 관리하지 않는다", "노출 시점의 정본은 여기다". 커밋하기 전에 검사를 돌렸다.

❌ 도달 경로 동기화 | 절이 늘었는데 description·프로브 미갱신

이 검사는 우리가 세 번 같은 실패를 하고 나서 만든 것이다. 기능을 만들고 그 기능에 가는 길을 안 만드는 실패. 스킬은 사용자의 말투를 보고 뜨는데, 새 기능을 넣으면서 "이런 말을 하면 이 스킬이 뜬다"는 목록을 안 고치면, 만든 기능은 없는 것과 같다.

시험 발화 넷을 넣고 돌렸다.

물어본 말가야 할 곳실제로 간 곳
이 설정 독자한테 언제 처음 보여줄지 어디에 적어야 해독자 인지세계관, 원고 검토
회차 표에 노출 열을 넣을까독자 인지전개, 기획
노출 시점은 어느 쪽에서 관리하는 거야독자 인지원고 검토
이 떡밥 몇 화에 심고 회수할지 짜줘전개색인, 세계관

넷 다 틀렸다.

방금 "정본은 여기"라고 적은 그 문서로 가는 길이 하나도 안 뚫려 있었다. 사용자가 정확히 그 질문을 해도 다른 문서가 뜬다.

참인데 쓸모없는 문장

검사가 없었다면 패치노트에 이렇게 적었을 것이다.

노출 시점의 정본을 독자 인지 스킬로 정했다. 두 스킬 양쪽에 경계를 명시했다.

이 문장은 참이다. 결정도 했고 문서에도 적었다. 그런데 그 결정을 알아야 할 사람이 그 문서에 도달하지 못한다. 6개월 뒤에 누가 같은 질문을 하면 여전히 엉뚱한 답이 나오고, 그때 패치노트를 뒤지면 "이미 정했다"고 적혀 있다.

거짓말은 아닌데 최악이다. 이미 해결됐다고 기록된 문제는 아무도 다시 안 본다.

결정을 문서에 적는 것과, 그 결정이 필요한 사람이 그 문서에 닿는 것은 다른 일이다.

말투 목록을 고치고 다시 돌렸다. 58개 중 오라우팅 0.

그런데 그 0이 가짜였다

검토자가 물었다. "그 시험 발화, 어디서 가져왔죠?"

내가 방금 쓴 설명문에서 가져왔다. "플롯표에 노출 열을 넣을까"라고 설명문에 적고, 시험 발화로 "회차 플롯표에 세계관 노출 열을 넣을까"를 넣었다.

이 감사 도구는 키워드 겹침으로 점수를 낸다. 설명문에서 베낀 문장을 시험 발화로 쓰면 통과가 보장된다. 0은 고쳤다는 증거가 아니라 같은 문장을 두 번 쓴 결과였다.

베끼지 않은 문장으로 다시 쟀다. 작가가 실제로 할 법한 말들로.

물어본 말결과
복선 심는 화수 정해줘틀림
주인공 정체 몇 화에 공개할까틀림
이 비밀 어디쯤에서 터뜨릴까틀림
1부 안에서 뭘 알려주고 뭘 남길지틀림

절반이 틀렸다.

그래서 전수 조사를 했다. 시험 발화 58개 중 18개가 설명문 복사였다. 내가 넣은 넷은 최신일 뿐이고, 오래전부터 쌓여 있었다. 이 저장소가 "도달 경로를 확인했다"의 근거로 삼아 온 수치의 3분의 1이 자기 인용이었다.

18개를 전부 다른 표현으로 바꾸고 다시 쟀다. 6.

0을 다시 만들 수도 있었다

설명문에 시험 발화의 단어들을 채워 넣으면 된다. 몇 분이면 0이 나온다.

그게 정확히 방금 무너진 논증이다.

그리고 그 감사 도구는 자기 출력 맨 위에 이렇게 적어 놓고 있었다.

실제 트리거는 의미 판단이므로 이 결과와 다를 수 있다. 경합 여부만 본다.

키워드 겹침이 0이어야 할 이유가 애초에 없었다. 우리는 그 도구가 재는 것과 다른 것을 재고 있다고 믿으면서, 그 도구의 숫자를 게이트로 쓰고 있었다.

게이트를 바꿨다. 늘면 실패, 줄면 기준을 내리라고 실패, 같으면 통과. 목표는 0이 아니라 "올라가지 않는 것"이다. 기준값은 고른 값이 아니라 잰 값이다.

그리고 검사를 하나 더 넣었다 — 시험 발화가 설명문을 세 어절 이상 그대로 베끼면 실패한다. 넣자마자 18개를 잡았다.

다른 것도 하나씩 무너졌다

같은 검토에서 나온 것들이다.

정본을 정하면서 막다른 길을 하나 만들었다. "이 설정 언제 처음 보여줄까"를 독자 인지 스킬로 보내도록 설명문을 고쳤는데, 그 스킬 본문에 "원고가 없으면 못 한다"고 적혀 있었다. 게다가 유일한 대안이던 전개 표의 열을 같은 릴리스에서 없앴다. 도달 경로를 뚫은 그 발화가 아무것도 못 하는 곳으로 간다.

새로 만든 칸은 다른 도구가 되돌리고 있었다. 금지 목록에 "의도적으로 어긴다면 무엇을 대신 보여주는가" 칸을 만들었는데, 집필 도구는 "금지 목록 위반"을 자동 수정 항목으로 갖고 있었다. 칸을 채워도 다음 회차 생성이 되돌린다.

같은 문장을 한 곳만 고친 것도 있다. 한 파일 안에 같은 취지의 줄이 두 개 있었는데 하나만 고쳤다. 이번 릴리스에서 "정정은 전파를 확인한다"를 규약에 넣었는데, 그 규약을 넣는 커밋 자신이 그것을 어겼다.

검사 하나에는 구멍이 있었다. "검사 목록이 문서와 맞는가"를 보는 검사가 자기 호출 시점까지만 봤다. 그 뒤에 붙인 검사는 문서에 안 적어도 초록이었다. 13개를 돌리고 10개만 대조하고 있었다.

같은 릴리스에 나온 다른 것

이번에 함께 고친 것 중에 형태가 재밌는 게 하나 더 있다.

우리 툴킷은 사용자 저장소에 .gitattributes 를 만들어 준다. git 의 줄바꿈 자동 변환을 끄는 파일이다 — 변환되면 원고 색인이 통째로 무효화되니까 끄는 게 맞다.

그런데 끄면 부작용이 있다. 저장소 안에 줄바꿈이 다른 파일이 섞이고, 파일을 통째로 다시 쓰는 도구가 그걸 조용히 뒤집는다. 한 줄 고쳤는데 파일 전체가 바뀐 것으로 기록된다.

사용자가 이걸 겪고 제보했다. 그런데 확인해 보니 우리도 겪었다. 그리고 우리 작업 절차에는 이미 대책이 적혀 있었다.

CRLF 혼입 — git diff --statgit diff -w --stat 의 줄 수가 크게 다르면 의심한다

우리가 아는 걸 우리만 쓰고 있었다. 사용자에게 주는 파일에는 한 줄도 안 적혀 있었다.

도구를 만드는 사람이 자기 함정을 자기 절차로 우회하면, 그 함정은 도구에 그대로 남는다. 자기가 안 밟으니까 안 보인다.

이월을 열었더니 기각이 나왔다

마지막으로 하나. 이번에 이월 조건을 채우러 갔는데, 채우고 보니 안 넣는 게 맞았다.

노출 열은 만들지 않는다. 정본이 다른 쪽으로 정해졌으니까.

이월을 "나중에 넣을 것"으로만 생각하면 이 경로가 안 보인다. 이월은 "판단을 미룬 것"이고, 판단하면 반영일 수도 기각일 수도 있다. 미룬 것을 열 때마다 넣어야 한다면 그건 이월이 아니라 예약이다.


webnovel-toolkit v1.6.0 작업 기록. 이 툴킷이 무엇인지는 네 번의 릴리스에서 배운 것에 적어 뒀다.


Comments

Write a Comment