요건사실론 파이프라인 산출물·사양 문서 일괄 반영 (배치 1~11)

여러 머신에서 Dropbox로 동기화되며 누적된 작업을 한 번에 반영한다.

## 산출물
- 사건종류_요건사실론문서/ 90건. 게이트 v4.0 기준 64건 PASS(71.1%).
  남은 26건은 골격 v2·v3 세대 산출물로 골격 11.5가 개정 불요로 정한 것들이다.
- 사건종류_요건사실론문서자료/ 96건, 청구취지작성규칙 문서 110건.

## 사양 문서
- 요건사실론_문서_공통골격_v4.md — v4-r5.
  §4.2·§6 항변 템플릿의 `주장책임 / 증명책임`에 「슬래시 하나로 나눈 두 값」 규칙 신설.
  이 필드에 문장을 쓰면 §7 총괄표의 두 열에 같은 값이 복제되는데 게이트가 잡지 못한다.
- 요건사실론_1차드래프트_생성_프롬프트_opus_v.5.txt — v.5-r4.
  같은 규칙 반영, `<efficiency_rules>` 4 (a)의 예산 60/80 자기모순 제거,
  법령 검색 응답의 <법령명한글>도 CDATA임을 `<external_lookup_conventions>` 0에 추가.
- 보존본 10건의 파일명을 `_r<n>_outdated` 기본형으로 정리했다.
  정리 전에는 `_orig`·`_old`·`_9_4_outdated`·`_r`·`_r2`가 섞여 있었고
  `..._v4_r.md`가 v4-r2를, `..._v4_r2.md`가 v4-r4를 담아 숫자가 실제와 어긋났다.
  이동 전후 해시를 대조해 내용 변형이 없음을 확인했다.

## 검증 자산
- tmp/rf_draft/_shared/ — 게이트 표준 구현체(rf_gate.py, RF_GATE_VERSION v4.0),
  배치별 preflight, 패치 후보, targets. tmp/rf_draft/leaf_id.py.
- MEMORY.md — 사건종류별 누적 교훈.

## .gitignore
- *.pdf 제외. 교재·자료 스캔 합계 1.7GB이고 여러 파일이 100MB를 넘어 호스트가 거부한다.
- tmp/ 스크래치 제외(_shared·leaf_id.py는 유지). law.go.kr XML 캐시 3,449개와
  페이지 추출 이미지·텍스트가 대부분이며 전부 재생성 가능하다.
- 그 결과 이 커밋은 497개 파일 32MB이고 2MB를 넘는 파일이 없다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-05 13:10:29 +09:00
co-authored by Claude Opus 5
parent f4d8a80e68
commit 19a6fc234a
497 changed files with 274599 additions and 21 deletions
+36
View File
@@ -0,0 +1,36 @@
# 실행: python3 tmp/rf_draft/leaf_id.py "<####>"
import sys, re, unicodedata as u
CHO=['g','kk','n','d','tt','r','m','b','pp','s','ss','','j','jj','ch','k','t','p','h']
JUNG=['a','ae','ya','yae','eo','e','yeo','ye','o','wa','wae','oe','yo','u','wo','we','wi','yu','eu','ui','i']
JONG=['','k','k','k','n','n','n','t','l','k','m','l','l','l','p','l','m','p','p','t','t','ng','t','t','k','t','p','t']
def rom(s):
o=[]
for c in u.normalize('NFC', s):
n=ord(c)
if 0xAC00<=n<=0xD7A3:
i=n-0xAC00; o.append(CHO[i//588]+JUNG[(i%588)//28]+JONG[i%28])
elif c.isascii() and c.isalnum(): o.append(c.lower())
else: o.append('-')
return re.sub(r'-+','-',''.join(o)).strip('-')
def norm(s):
s=u.normalize('NFC', s)
return ''.join(ch for ch in s if ch not in ' \t・·•,()')
SKIP={'가사소송','가족관계등록','행정소송'}
leaves=[]
for ln in open('case_kinds.md', encoding='utf-8'):
ln=u.normalize('NFC', ln).strip()
if not ln.startswith('|'): continue
cells=[c.strip() for c in ln.strip('|').split('|')]
if len(cells)<3 or cells[0]=='소송 대분류' or set(cells[0])<=set('- '): continue
big, dis, kinds = cells[0], cells[1], cells[2]
if big in SKIP: continue
leaves += [dis] if not kinds else [p.strip() for p in kinds.split(',') if p.strip()]
assert len(leaves)==137, f'leaf 총수 {len(leaves)} != 137 — 중단'
for n, nm in ((1,'대여금 청구'),(60,'종류물(대체물)의 지급 또는 인도를 구하는 소'),
(66,'매매를 원인으로 한 소유권이전등기 청구'),(128,'기타 확인청구'),
(137,'주주총회결의취소의 소')):
assert norm(leaves[n-1])==norm(nm), f'검산 실패 PROV-{n:03d}: {leaves[n-1]}'
q=norm(sys.argv[1]); hit=[(i,x) for i,x in enumerate(leaves,1) if norm(x)==q]
assert len(hit)==1, f'사건종류 매칭 {len(hit)}건 — 중단'
i, name = hit[0]
print(f'PROV-{i:03d}', name, rom(name), sep='\t')