문서 충돌 점검
규정·지침·계약 문서 묶음을 읽어 서로 충돌하는 조항을 찾고, 효력 위계에 따라 어느 쪽이 우선하는지 판정해 리포트로 낸다. 외부 서비스 연동 없이 로컬 파일만으로 동작한다.
이 스킬이 푸는 문제
조직 문서의 충돌은 대부분 누가 틀려서가 아니라, 상위 문서가 개정될 때 그것을 인용하던 하위 문서가 함께 갱신되지 않아서 생긴다. 담당자가 바뀌면 왜 그렇게 정했는지 아는 사람이 사라지고, 충돌은 분쟁이나 감사 지적으로 드러날 때까지 누적된다. 사람이 이를 지적하려면 과거 결재를 문제 삼아야 하지만, 점검 결과로 출력되면 그 부담이 없다.
두 가지 모드
전체 감사 — 문서 묶음 전체를 훑어 충돌을 찾는다. 최초 도입 시, 또는 정기 점검용.
개정 영향 분석 — 특정 문서를 고칠 때 함께 고쳐야 할 곳을 찾는다. 개정안이 있거나 "이 조항을 이렇게 바꾸려는데" 같은 요청이면 이쪽이다. 상시 감시보다 이 모드가 실용적이다. 개정 시점에만 돌면 되고, 결과가 곧 작업 목록이 된다.
시작할 때 어느 모드인지 사용자에게 확인한다. 개정안 파일이 함께 제공되었거나 특정 문서를 지목했다면 개정 영향 분석으로 보고 진행하되, 한 문장으로 확인만 받는다.
절차
1. 수집 ingest.py 문서 → 조문 단위
2. 분해 (직접 판단) 조문 → 주장 + 메타데이터 ← 품질이 여기서 갈린다
3. 후보 pair.py 주장 → 충돌 후보 쌍
4. 판정 (직접 판단) 후보 쌍 → 충돌 유형·우선순위·조치
5. 리포트 report.py 판정 → 마크다운 + 엑셀
2단계와 4단계만 판단이 필요하고 나머지는 스크립트가 처리한다. 값싸고 정확한 부분을 판단에 맡기지 않는 것이 이 구조의 요점이다.
작업 폴더는 /home/claude/audit/를 쓴다. 최종 산출물만 /mnt/user-data/outputs/로 옮긴다.
1. 수집
python3 scripts/ingest.py <문서폴더> /home/claude/audit
units.jsonl(조문 단위)과 docs.json(문서 목록)이 생긴다.
docs.json의 tier, effective_from은 비어 있다. 각 문서의 앞부분과 부칙을 읽고
채운다. 위계를 잘못 넣으면 우선 적용 판정이 통째로 뒤집히므로, 문서명만으로 단정하지
말고 제정 근거 조항("○○규정 제△조에 따라")을 확인한다. 판단이 안 서면 null로 두고
사용자에게 묻는다. 위계 표는 references/claim-extraction.md에 있다.
.hwp는 지원하지 않는다. 미지원 파일이 보고되면 docx나 pdf로 변환해 달라고 요청한다.
2. 주장 단위 분해
시작 전에 references/claim-extraction.md를 읽는다. 이 단계의 품질이 전체 결과를
결정한다. 조문을 통째로 넘기면 무엇과 무엇이 부딪히는지 특정할 수 없고, 문장 단위로
잘게 쪼개면 조건과 예외가 분리되어 없는 모순이 생긴다.
units.jsonl을 읽고 /home/claude/audit/claims.jsonl을 만든다. 문서가 많으면 문서
단위로 나눠 처리하고 이어붙인다.
분해가 끝나면 진행하기 전에 표본을 보여준다. 주장 5~10건을 사용자에게 제시하고
"이 정도 단위가 맞는지, subject 표기가 실무 용어와 맞는지" 확인받는다. 여기서
어긋난 채 진행하면 뒤 단계를 전부 다시 해야 한다.
3. 후보 쌍 생성
# 전체 감사
python3 scripts/pair.py /home/claude/audit
# 개정 영향 분석 (D003 이 개정 대상)
python3 scripts/pair.py /home/claude/audit --changed D003
전수 비교는 주장 수의 제곱이라 감당이 안 된다. 스크립트가 적용범위 필터와 문자
n-gram 유사도로 후보를 좁힌다. pair_stats.json에 축소 비율이 나온다.
후보가 500건을 넘으면 --min-sim 0.35 등으로 조인다. 50건 미만으로 지나치게 적으면
subject 표기가 문서마다 흔들렸을 가능성이 높다. 2단계로 돌아가 주제 키를 통일한다.
4. 판정
시작 전에 references/conflict-types.md를 읽는다. 유형 정의, 비충돌 판정 기준,
우선 적용 규칙, 심각도 기준이 들어 있다.
pairs.jsonl의 각 쌍을 판정해 verdicts.jsonl에 한 줄씩 기록한다. 비충돌도
verdict: "N"으로 남긴다.
판정에서 가장 중요한 것은 충돌이 아닌 것을 걸러내는 일이다. 적용범위가 분리된
경우, 상위 규범이 명시적으로 위임한 특칙, 하위 문서가 상위를 구체화한 경우, 부칙에
따라 병존하는 경우는 전부 정상이다. 노이즈가 섞인 리포트는 두 번째 회차부터 아무도
읽지 않으므로, 애매하면 넣지 말고 confidence를 낮음으로 두거나 제외한다.
근로자 유리 원칙에 주의한다. 법정 기준보다 근로자에게 유리한 사내 규정은 위계 위반이 아니다. 법령이 정한 것은 하한이지 상한이 아니다.
5. 리포트
python3 scripts/report.py /home/claude/audit --out /mnt/user-data/outputs --title "..."
마크다운 리포트와 엑셀 목록이 나온다. 엑셀에는 담당·처리상태 열이 비어 있어 그대로
작업 대장으로 쓸 수 있다. present_files로 두 파일을 전달한다.
지켜야 할 것
원본 문서를 수정하지 않는다. 이 스킬의 출력은 제안이며, 채택 여부는 사람이 결정한다. 판정 결과를 원본에 반영해 달라는 요청을 받으면 사본을 만들어 작업한다.
확정처럼 쓰지 않는다. 리포트 문장은 "충돌 가능성", "확인 필요"의 톤을 유지한다. 법률 판단이 아니며, 심각도 높음 항목은 법무 검토가 필요하다는 점을 리포트에 남긴다.
근거를 반드시 붙인다. 모든 판정에는 문서명과 조항 번호가 따라붙어야 한다. 출처 없는 지적은 검증할 수 없어 그대로 폐기된다.
위계를 추측하지 않는다. tier가 불확실한 문서가 끼어 있으면 우선 적용을 단정하지
말고 확인 필요로 표시한다. 잘못된 우선순위 판정은 놓친 충돌보다 해롭다.
규모별 대응
| 문서 수 | 방식 |
|---|---|
| ~10건 | 그대로 진행 |
| 10~50건 | 분해를 문서 단위로 나눠 진행, 중간 저장 |
| 50건 이상 | 범위를 좁힐 것을 제안한다. 특정 주제(연차·출장비·징계)나 특정 위계 구간만 먼저 하는 편이 낫다. 전부 한 번에 하면 판정 품질이 떨어지고 리포트가 읽히지 않는다. |
재실행
claims.jsonl은 문서가 바뀌지 않는 한 재사용한다. 2단계가 가장 비싸다. 문서 일부만
추가되었으면 해당 문서만 분해해 이어붙이고 3단계부터 다시 돌린다.
정기 점검에서 같은 쌍을 반복 판정하지 않으려면 --skip-judged를 준다. 기존
verdicts.jsonl에 있는 쌍은 후보에서 빠진다.
python3 scripts/pair.py /home/claude/audit --skip-judged
pair_id는 실행할 때마다 다시 매겨지므로 판정 기록을 이어붙일 때는 key
필드(주장 ID 두 개)를 기준으로 맞춘다. verdicts.jsonl에 이 필드를 반드시
남긴다.