📝 한 줄 요약
법률위키의 원문과 검색 품질을 보강하려고 새 도구 세 가지를 검토했지만, “새 버전이 실행된다”, “미러 본문이 같다”, “기대 파일이 검색된다”를 곧바로 신뢰나 승격으로 바꾸지 않았다. MCP는 기존 4.7.1 옆에 4.9.7을 격리해 비교했고, Legalize-KR은 공식 경로를 대신하지 않는 읽기 전용 미러로 제한했으며, 검색 평가는 파일 경로뿐 아니라 원문 90자 구간까지 hash로 묶어 실제 회수 여부를 계산했다. 결과는 한꺼번에 PASS가 아니었다. MCP는 격리 호환 PASS, 미러는 4 PASS·2 REVIEW, span-gold는 SQLite FTS5에서 PASS였고, 전역 교체·canonical 승격·MongoDB 평가는 그대로 닫아 두었다.
바쁘다면 이것만 읽어도 된다.
업그레이드는 새 버전 단독 실행이 아니라 구버전과 같은 fixture를 통과하는지 비교해야 한다.
필수 token이 같아도 전체 stdout hash가 다르면 downstream consumer 검토가 남는다.
미러 본문이 같아도 MST·공포일·시행일이 다르면 같은 법령 버전이라고 단정할 수 없다.
법률 미러는 후보 발견과 대조에는 유용하지만 공식 원문 authority를 대체하지 않는다.
검색 결과의 파일 경로 적중은 그 안의 필요한 법문 구간 회수와 다르다.
source 전체 hash와 span hash를 함께 묶으면 원문 변경이나 offset drift를 먼저 차단할 수 있다.
환경이 막힌 MongoDB 차선은 FTS5 PASS에 기대어 통과한 것으로 처리하지 않는다.
실행 PASS, 독립 검토, Library 발행, 전역·canonical 승격은 각각 다른 상태다.
🎯 이런 분들께 도움이 된다
법령·판례 MCP를 기존 법률위키나 RAG에 연결하려는 팀
공개 Git 미러를 공식 원문과 구분해 쓰려는 법률 데이터 담당자
“기대 문서를 찾았다”보다 “필요한 근거 구간을 찾았다”를 평가하려는 검색 엔지니어
도구 업그레이드 때 전체 교체보다 격리 canary를 우선하려는 운영자
실패와
NOT_RUN을 숨기지 않는 승격 Gate가 필요한 AI 워크스페이스 운영자
😫 시작점 — 세 가지 ‘될 것 같은 신호’가 있었다
이번 파일럿은 법률위키에 도움이 될 공개 도구를 조사하는 과정에서 시작됐다. 곧바로 매력적인 신호 세 가지가 보였다.
Korean Law MCP에는 기존 전역 4.7.1보다 새 버전인 4.9.7이 있었다.
Legalize-KR은 법령과 판례를 Git·Markdown 친화적인 구조로 제공했다.
기존 검색 평가는
required_path를 찾으면 기대 문서를 회수했다고 판정할 수 있었다.
하지만 세 신호에는 서로 다른 빈틈이 있었다.
새 버전 실행 성공
≠ 기존 consumer와 호환
미러 본문 동일
≠ 공식 시점·식별자 동일
기대 path 적중
≠ 필요한 근거 문장 적중
그래서 새 원문이나 새 런타임을 먼저 넣지 않고, 세 개의 검증문을 세웠다.
그림 1. 실제 MCP 호환 receipt, Legalize 미러 report, LC-033 span report에서 자동 생성한 실행 증거 카드다. live UI나 터미널 캡처가 아니다. 세 차선의 결과가 좋아도 전역·canonical 승격은 별도 Gate라는 점을 보여 준다.
🧭 첫 번째 검증문 — 새 MCP는 기존 버전 옆에서 시험한다
전역 korean-law 4.7.1을 덮어쓰지 않았다. 4.9.7을 별도 런타임으로 설치하고 같은 공개 fixture 여섯 개를 양쪽에 실행했다.
canary
양쪽 계약 PASS
stdout byte-identical
version
예
아니오 — 버전 문자열 자체가 다름
tool list
예
아니오
판례 80다622 exact 검색
예
예
판례일련번호 95127 전문
예
예
민법 제750조 인용 검증
예
아니오
2020-01-01 기준 민법 제750조
예
아니오
여섯 명령은 모두 exit code 0과 필수 token 계약을 통과했다. 특히 search_exact와 detail_full은 stdout SHA-256까지 같았다. 판례 검색 결과와 전문 본문이 이 fixture에서는 byte-identical이었다.
그러나 tool list, 인용 검증, 행위시법 출력은 필수 token을 만족하면서도 전체 hash가 달랐다. 이것을 실패라고 과장하지도, 사소한 포맷 변화라고 축소하지도 않았다. 정확한 결론은 다음이었다.
isolated_compatibility: PASS
downstream_consumer_review: REQUIRED
global_runtime_promotion: NOT_RUN
그림 2. 두 런타임의 명령별 exit code, 필수 token, stdout hash 비교 receipt에서 파생했다. PASS는 여섯 canary 범위의 격리 호환을 뜻하며, 모든 출력 스키마의 완전 동일이나 전역 교체 승인을 뜻하지 않는다.
이 단계에서 바뀐 판단
처음 질문은 “4.9.7로 올릴 수 있는가?”에 가까웠다. 검증 뒤 질문은 더 구체적으로 바뀌었다.
판례 검색·전문 consumer는 같은 출력을 받는가?
→ 이 fixture에서는 그렇다.
인용검증·행위시법·tool discovery consumer도 그대로 안전한가?
→ hash가 달라 별도 회귀검사가 필요하다.
버전 전체를 하나의 PASS/FAIL로 접지 않고 consumer surface별로 나눈 것이 첫 번째 수확이었다.
🪞 두 번째 검증문 — 미러는 authority가 아니라 비교 차선이다
Legalize-KR 계열은 법령과 판례를 Git·Markdown 친화적으로 다룰 수 있게 해 준다. 하지만 “읽기 쉽다”와 “공식 법적 근거다”는 같은 말이 아니다. 파일럿 adapter의 정책을 먼저 고정했다.
authority: law.go.kr
mirror_provider: legalize-kr
mirror_role: DISCOVERY_ONLY
canonical_promotion: NOT_ALLOWED
mismatch_action: REVIEW_CANDIDATE_ONLY
비교 대상은 지방계약법 계열 조문 다섯 개와 대법원 판례 하나였다.
대상
normalized body
식별자·날짜 검사
판정
법률 제9조
동일
MST 해소·공포일·시행일 불일치
REVIEW
법률 제31조
동일
MST 해소·공포일·시행일 불일치
REVIEW
시행령 제25조
동일
일치
PASS
시행령 제26조
동일
일치
PASS
시행규칙 제76조
동일
일치
PASS
대법원 80다622
동일
비교 계약 통과
PASS
여섯 건의 정규화 본문은 모두 같았다. 그래도 법률 제9조와 제31조는 PASS로 올리지 않았다. 미러가 제시한 MST를 공식 경로에서 직접 해소하지 못했고, 공포일·시행일 메타데이터도 달랐기 때문이다. 공식 law ID fallback으로 현재 조문 본문을 회수할 수 있었다는 사실은 “미러가 가리킨 정확한 버전 identity가 검증됐다”는 뜻이 아니다.
그림 3. read-only 미러 report에서 자동 생성했다. 본문 정규화 일치와 버전·날짜 메타데이터 일치를 별도 축으로 표시한다. 미러는 발견·대조용이며 결과가 공식 원문을 덮어쓰지 않았다.
parser도 provider metadata를 그대로 믿지 않았다
조문 계층은 Legalize CLI의 parent_structure를 그대로 채택하지 않고 Markdown의 전체 heading stack에서 다시 만들었다. 안정 ID도 미러 경로나 Git commit만으로 잡지 않았다.
법령 조문 logical ID = official lawId + article number
법령 버전 ID = logical ID + official MST
판례 logical ID = official precedent sequence ID
mirror path / Git SHA = physical provenance
장기 identity와 특정 snapshot provenance를 나눈 이유는 upstream 파일 구조가 바뀌어도 같은 법령·판례를 다시 찾기 위해서다.
🔎 세 번째 검증문 — 기대 파일이 아니라 근거 구간을 맞혔는가
기존 retrieval 평가에는 required_path와 source reference, Hit@K, MRR이 있었다. 이것은 중요한 계약이므로 없애지 않았다. 대신 선택적인 expected_spans를 더했다.
LC-033의 gold는 지방계약법 시행령 제25조 제1항 제5호 사목의 임대차 금액기준이 들어 있는 90자 구간이다.
offset_unit: unicode-codepoint
start_char: 2919
end_char: 3009
span_chars: 90
source_sha256: bffb7f5b43589ec13685c0f8f9a1452a84978d342f02b3c2fa9b38968da18f2c
span_sha256: 77ccf31c11e52d9c6a8a12d826883e2a5b3f540526e2048e33b6822dcc35862c
평가 전에 source 전체 hash와 선택 구간 hash를 모두 확인한다. 원문이 바뀌어 offset이 밀렸거나, 같은 offset이 다른 문장을 가리키면 검색을 실행하기 전에 fail-closed한다.
실제 읽기 전용 SQLite FTS5 top-5 결과는 다음과 같았다.
지표
값
path hit rank
1
span recall
1.0000
span precision@5
0.4000
source-bound recall
1.0000
source-bound precision@5
0.2000
first span rank
1
first source-bound rank
1
recall은 1.0이었지만 precision을 1.0으로 꾸미지 않았다. top-5 중 실제 span을 담은 record는 두 개였고, 기대 source path까지 같은 record는 하나였다. 중복 path도 서로 다른 색인 section이므로 결과 record 기준 precision 분모에 남겼다.
그림 4. LC-033 live FTS5 report에서 파생했다. source 전체와 문자 구간을 각각 SHA-256으로 결박했으며, 이 PASS는 SQLite FTS5와 span scorer 계약에만 적용된다.
🚧 실패와 수리 — 통과하지 않은 것을 세 종류로 나눴다
1. adapter 구현 결함은 수정했지만, 폐기한 v1을 성공 증거로 쓰지 않았다
첫 Legalize 실행에서는 날짜만 붙은 개정 태그와 공식 CLI가 stdout으로 내보낸 오류를 parser가 충분히 구분하지 못했다. 날짜 태그 정규화와 stdout 오류 판별을 수리하고 계약 테스트를 추가한 뒤 v2를 다시 실행했다.
다만 폐기한 v1 report는 release artifact로 보존하지 않았다. 따라서 이 글은 v1 실패의 세부 수치를 재현 가능한 역사 증거처럼 제시하지 않는다. 구현 문서에 남은 defect·repair 기록과 현재 v2 테스트 결과만 사용한다. 다음 파일럿부터는 실패 predecessor도 별도 namespace에 보존하는 편이 더 낫다.
2. 본문 일치와 버전 identity 불일치는 ‘부분 성공’이 아니라 REVIEW였다
법률 제9조와 제31조는 content check만 보면 성공이다. 하지만 시점·MST가 닫히지 않았다. 법률 문서에서는 이 차이가 장식 메타데이터가 아니므로, 전체 판정을 REVIEW로 유지했다.
3. Docker가 막힌 MongoDB 차선은 NOT_VERIFIED로 남겼다
MongoDB vector 평가를 시도했지만 Docker Desktop API가 Docker Desktop is unable to start를 반환했다. 다른 컨테이너에 영향을 줄 수 있는 reset은 임의로 하지 않았다. SQLite FTS5에서 span-gold가 PASS였다는 이유로 MongoDB baseline/context/strict 차선을 통과한 것으로 간주하지 않았다.
✅ 실제로 만든 것
이번 파일럿의 동결 manifest에는 코드·schema·테스트·report를 합쳐 19개 regular artifact가 들어 있다.
MCP 호환 receipt
두 버전의 명령 인자, exit code, stdout/stderr bytes와 hash
명령별 required-token 계약
동일 출력과 변경 출력을 분리한 comparison
local binary 경로를 환경 중립 label로 바꾼 공개-safe 정식 receipt
Legalize read-only adapter
legalize-cli==0.3.3pin조문·판례 cohort schema
official MCP와 mirror의 원문·식별자·날짜 비교
heading stack parser
report lane 밖 쓰기 거부
canonical path 쓰기 금지
span-gold evaluator
source SHA-256 + span SHA-256 preflight
Unicode code-point offset 계약
내용 기반·source-bound recall과 precision
first-match rank와 all-match 상태
기존 path/ref hit 지표의 하위 호환
retrieval report의 MongoDB URI userinfo redaction (
eval_retrieval.py)span이 없는 기존 case의
evaluated: false처리
검증
Python syntax compile: PASS
Legalize deterministic contract script: PASS
span evaluator contract script: PASS
retrieval evaluator integration script: PASS
LC-033 no-network
--validate-only: PASSJSON/JSONL parse와 shell syntax: PASS
공개 사례 패키지에는 source의 임시 cache·absolute binary path를 복사하지 않음
📊 Before와 After
항 목
Before
After
MCP 업그레이드
새 버전 단독 실행 여부 중심
4.7.1·4.9.7 동일 fixture의 exit/token/hash 비교
미러 역할
구조가 편리하면 원문 공급 후보가 될 수 있음
DISCOVERY_ONLY, mismatch는 review candidate만 생성
법령 identity
파일 경로·Git commit에 기대기 쉬움
official lawId/article과 MST를 logical/version ID로 분리
retrieval gold
기대 path·source ref 적중
source hash + 문자 구간 hash + source-bound 회수 평가
실패 처리
부분 성공을 하나의 PASS로 접을 위험
PASS·REVIEW·NOT_VERIFIED·NOT_RUN을 별도 상태로 유지
승격
검증 결과가 좋으면 즉시 교체·편입할 수 있음
global runtime·canonical·Library·external을 각각 별도 Gate로 분리
정확도 개선률, 시간 절감률, 운영 비용 절감은 측정하지 않았다. 이번 변화는 정량 성과가 아니라 승격 판단을 더 잘게 나눈 구조적 변화다.
🧾 Trace · Proof · Verdict · Repair
Trace
공개 법률도구 후보 조사
→ 전역 상태 동결
→ MCP 4.9.7 격리 설치
→ 4.7.1과 같은 canary 비교
→ Legalize-KR read-only cohort 비교
→ 본문·MST·날짜 불일치 분리
→ LC-033 문자 구간 gold 결박
→ 실제 SQLite FTS5 top-5 채점
→ artifact manifest 동결
Proof
파일럿 artifact manifest:
6ed8a774b72f95bd9a3d1f858bda6a7dccd0cec9c68f3b3b40261dd3cd10bc40MCP 정식 receipt:
16e28bd574d9552e337ee90bd56ff5d0d3e32d68ed63b50d67d7611219147f0aLegalize v2 report:
7e0e04ddad9a6d5cda3ddea594ae9cec90fd622bbbbdde13b328bc1393e96aeeLC-033 live span report:
3697001117c6965339e62eeb684d1e8e38be15c5ebb6ec30414f58ae301546b4선택된 source 전체 hash:
bffb7f5b43589ec13685c0f8f9a1452a84978d342f02b3c2fa9b38968da18f2c선택된 90자 span hash:
77ccf31c11e52d9c6a8a12d826883e2a5b3f540526e2048e33b6822dcc35862c
Verdict
mcp_4_9_7_isolated: PASS
mcp_global_replacement: HOLD_NOT_RUN
legalize_mirror: REVIEW_DISCOVERY_ONLY
span_gold_sqlite_fts5: PASS
span_gold_mongodb: NOT_VERIFIED
canonical_promotion: NOT_PERFORMED
legal_reliance: false
Repair / 다음 Gate
tool list·인용검증·행위시법 consumer가 4.9.7 변경 출력을 수용하는지 회귀검사한다.
Legalize의 MST·공포일·시행일 차이가 mirror 갱신 지연인지 version resolution 정책 문제인지 분리한다.
LC-033 한 건을 넘어 법령·판례·교재 source에 span-gold를 단계적으로 확장한다.
Docker 환경이 복구되면 MongoDB baseline/context/strict를 같은 gold로 다시 채점한다.
이 네 Gate 전에는 전역 런타임과 canonical을 건드리지 않는다.
♻️ 재사용 체크리스트
새 법률 데이터 소스
공식 authority와 미러·민간 discovery를 먼저 분류한다.
official logical ID와 snapshot provenance를 분리한다.
기준일·시행일·MST 또는 그에 준하는 version identity를 기록한다.
미러 본문 일치와 메타데이터 일치를 별도 검사한다.
mismatch는 overwrite가 아니라 review queue로 보낸다.
MCP 업그레이드
기존 버전과 신규 버전을 동시에 실행 가능한 격리 좌표로 둔다.
version, discovery, representative search, detail, citation, time-aware query를 포함한다.
exit code, 필수 token, bytes, SHA-256을 각각 기록한다.
출력 차이를 consumer surface별로 분류한다.
격리 PASS와 전역 교체를 같은 판정으로 쓰지 않는다.
검색 평가
기대 path를 유지한다.
필요한 근거 span의 source hash와 span hash를 함께 묶는다.
offset 단위를 명시한다.
내용 회수와 source-bound 회수를 별도 계산한다.
recall뿐 아니라 precision과 중복 record 정책을 공개한다.
실행하지 못한 backend는
NOT_VERIFIED로 둔다.
🔒 공개·법률 경계
이 사례는 공개 법령·판례 식별자와 도구 실행 receipt를 다룬다. 의뢰인 사실이나 개인정보를 사용하지 않았다.
Legalize-KR 결과는 공식 법률근거로 승격되지 않았다.
PASS는 각 canary·cohort·backend 범위에만 적용된다.특정 법률문제에 대한 적용 판단, 행위시법 법률검토, 판례 명제 검토는 수행하지 않았다.
MongoDB vector 평가와 전역 MCP 교체는 수행하지 않았다.
Library 등록과 외부 웹·커뮤니티 발행은 별도 상태다.
마무리
이번 파일럿에서 가장 중요한 결과는 새 도구를 많이 붙인 것이 아니다. 무엇이 같고, 무엇이 다르며, 어느 차선이 아직 닫혀 있는지를 서로 다른 receipt로 남긴 것이다.
실행된다
→ 같은 계약을 통과한다
→ 같은 의미의 출력을 준다
→ 공식 authority와 시점이 맞다
→ 필요한 근거 구간을 회수한다
→ 독립 검토를 통과한다
→ 그 다음에야 승격을 검토 한다
법률위키의 신뢰는 좋은 검색 결과 하나보다, 좋아 보이는 결과를 어디까지 믿을지 제한하는 문에서 더 단단해졌다.