Regulatory Ingestion · Gate F

규제 수집 파이프라인 아키텍처

법령 원문을 외부 공식 API에서 수집해 조문 단위로 쪼개고, 카드사 의무 후보로 분류한 뒤 사람이 검토·승인하는 append-only 파이프라인. 모든 판단 근거와 원문이 원장에 남습니다.

  1. 수집
  2. 보존
  3. 분해
  4. 분류
  5. 보강
  6. 검토
  7. 산출
36,466소스 라인
15,757테스트 라인 (57파일 · 297개)
38원장 테이블 (schema v28)
62CLI 명령
0런타임 의존성
한 줄로 말하면

쏟아져 들어오는 법령을 낱장으로 정리해, "우리 카드사가 확인할 의무"만 근거와 함께 검토대에 올리는 선별 공장입니다. 기계는 1차 후보를 추리고 관련 조문을 붙이는 데까지 맡고, 승인 도장은 법무·컴플라이언스 담당자만 찍습니다.

증거를 다루는 방식은 두 가지 원칙으로 고정됩니다. 원문은 절대 고쳐 쓰지 않고, 요약 대신 법 문장 그대로를 보여줍니다. 또 과거 판단을 지우거나 덮어쓰지 않고, 누가 언제 어떤 근거로 판단했는지 새 줄로 계속 남깁니다. 감사·검사 때 "왜 이렇게 판단했나"를 원문까지 거슬러 올라가 설명하기 위한 장부입니다.

데이터 흐름

각 단계는 독립 CLI 명령이고, 결과를 원장에 쓴 뒤 다음 단계가 그것을 읽습니다. 중간 산출물이 전부 테이블로 남아 어느 단계든 단독 재실행·검증이 가능합니다.

쉽게 말하면
  1. 받아온다 — 법제처·개인정보위·금융위의 공식 창구에서 법령 원문을 내려받습니다.
  2. 봉인한다 — 받은 원본에 고유 지문(해시)을 찍어 금고에 넣습니다. 이후 한 글자라도 달라지면 즉시 확인됩니다.
  3. 자른다 — 법 한 편을 제○조 제○항 제○호 단위로 잘라 낱장 카드 11,150장을 만듭니다.
  4. 1차 선별한다 — "~하여야 한다" 같은 표현과 "신용카드업자" 같은 대상을 기준표와 대조해 의무 후보를 만듭니다. 아직 최종 결론은 아닙니다.
  5. 한 번 더 읽힌다 — 규칙이 놓치기 쉬운 문장(예: 끝에 <개정 2025.2.5.>가 붙은 경우)을 AI가 다시 읽고 참고 판정을 붙입니다.
  6. 사람이 확정한다 — 법무·컴플라이언스 담당자가 원문과 두 판정 근거를 보고 최종 승인·기각합니다. 여기가 현재 병목입니다.
  7. 꺼내 쓴다 — 사람이 승인한 것만 엑셀이나 사내 지침 초안으로 내려받습니다.

공정마다 결과물을 장부에 내려놓고 다음 공정이 가져가는 구조입니다. 그래서 4단계 기준표를 고쳐도 1~3단계를 되풀이할 필요 없이, 4단계만 다시 돌려 결과를 비교할 수 있습니다.

01 수집

외부 공식 API 호출

run-due 727 sources
879 fetch_observations
02 보존

원본 바이트 고정

collect-source 1,542 artifacts
771 source_versions
03 분해

조·항·호 단위 절단

project-fragments 11,150 source_fragments
04 분류

규칙 기반 의무 판정

project-obligations 10,408 obligation_candidates
05 보강

AI 재해석 (선택)

generate/apply-llm-classifications 8,300 재판정 완료
06 검토

사람이 승인·기각

review-obligation 2 reviews
07 산출

CSV · 지침 초안

export-obligations 원문 그대로 인용
조문 간 관계 추출 위임·인용·제재 엣지를 조문 단위로 연결 project-relations → 10,377 fragment_relations
업무별 의무 매칭 처리활동 태그 교집합 — 결정론적 규칙, 유사도 아님 match-activities → 1,475 activity_obligation_matches
개정 감지 · 재검토 법령 재수집 시 승인건이 구버전 기준인지 추적 project-source-changes → 771 source_changes
뉴스 모니터링 제재·유출 보도를 수집, 의무와 사람이 직접 연결 naver-news → 240 NEWS fragments
쉽게 말하면

위의 메인 공정이 원문을 의무 후보로 바꾸는 컨베이어 벨트라면, 이 넷은 그 옆의 보조 작업대입니다. 조문 간 관계는 법전의 각주와 화살표를 이어 붙이고, 업무 매칭은 의무 카드를 담당 부서의 서류함에 나눠 넣습니다. 개정 감지는 예전 승인에 "다시 확인" 표지를 붙이고, 뉴스 모니터링은 관련 보도를 스크랩해 둡니다. 뉴스와 의무의 최종 연결은 사람이 확인합니다.

계층 구조

의존 방향은 항상 안쪽으로만 흐릅니다. 왼쪽 색띠는 장식이 아니라 신뢰 경계입니다 — 외부에서 들어온 미검증 데이터가 어디서 정규화되고, 어디서부터 원장에 고정되는지를 나타냅니다.

커넥터

src/connectors/ 외부 · 미검증

공식 API·HTML만 호출합니다. 호스트 화이트리스트, 429·5xx 재시도, 이용약관 검토 상태를 통과하지 못하면 수집 자체가 차단됩니다(fail-closed).

밖에 나가서 물건을 받아오는 구매 담당. 거래처가 승인 목록에 없으면 아예 안 나갑니다.

law-open-apilaw-open-api-preclaw-open-api-ppclaw-open-api-fscnaver-newspipc-press-releasesfsc-press-releasesllm-classifier-anthropicsecure-httpfactory
3,09413 파일

도메인

src/domain/ 순수 · 의존성 0

파싱과 판정 규칙만 있습니다. DB도 네트워크도 모릅니다. 의무 분류 규칙 (obligation-rules)이 여기 있고, 어미·수범자 패턴이 전부 명시 상수라 판정 근거를 조문 단위로 되짚을 수 있습니다.

벽에 붙은 판정 기준표 그 자체. 아무 일도 하지 않고, 기준만 적혀 있습니다.

obligation-rulessource-fragmentslaw-documentadmrul-documentprecedent-documentppc-decision-documentfsc-decision-documentnaver-news-articlefragment-relationsendpoint-definitionintegritycanonical-jsonnormalized-diff
3,20916 파일

애플리케이션

src/application/ 오케스트레이션

파이프라인 각 단계가 한 파일씩 대응됩니다. 커넥터·도메인·원장을 조립만 하고 비즈니스 규칙은 갖지 않습니다. 사람 판단이 필요한 동작(검토·중복지정·뉴스연결·재검토 해소)은 모두 여기서 명시적 액션으로만 실행됩니다.

현장 반장의 작업 지시서. "누가 무엇을 어떤 순서로"만 정하고, 판정 기준은 바꾸지 않습니다.

collect-sourcecollect-batchproject-fragmentsproject-obligationsproject-relationsreview-obligation-candidategenerate-llm-classificationsapply-llm-classificationsmatch-activity-obligationsexport-obligation-reviewsdraft-guideline-documentacknowledge-stale-obligationlink-news-to-obligationrun-due-endpointsverify-runtime
5,64431 파일

인프라

src/infrastructure/ 영속화 · append-only

SQLite 원장 하나(node:sqlite 내장, 외부 DB 없음)와 콘텐츠 주소 저장소. 원본 바이트는 sha256으로 주소화해 불변 보존하고, 검토 이력은 수정 없이 누적만 됩니다. 스키마 v28까지 마이그레이션이 전부 코드에 남아 과거 백업도 현재 스키마로 복원됩니다.

봉인 금고 + 손으로 쓴 장부. 새 줄만 추가되고, 이미 쓴 줄은 고치거나 지울 수 없습니다.

sqlite-ledgercontent-addressed-storejsonl-event-sink
10,7373 파일

운영 · 콘솔

src/operations/ 사람 대면

루프백 전용 웹 콘솔 9화면과 건강도·백업·소크 판정. 쓰기 경로는 딱 4개 (의무 검토, 수범자 승인, 뉴스 연결, 재검토 해소)로 제한되고 나머지는 전부 읽기 전용입니다. DNS 리바인딩 방어를 위해 Host 헤더까지 검사합니다.

사람이 실제로 보는 창구 화면. 볼 수 있는 건 많지만, 손댈 수 있는 건 4가지뿐입니다.

console-serverconsole-assetsoperations-snapshotpipeline-healthruntime-backupsoak-readiness
7,6376 파일
쉽게 말하면

이 다섯 계층은 바깥에서 들어온 정보를 믿을 수 있는 기록으로 바꾸는 순서입니다. 커넥터가 외부 자료를 받아오면 도메인이 순수 규칙으로 뜻을 판정하고, 애플리케이션이 처리 순서를 조율합니다. 인프라는 결과를 원장에 영구 보존하며, 운영·콘솔은 사람이 마지막으로 확인하고 다루는 창구가 됩니다.

원장 (SQLite · schema v28)

실제 운영 런타임 .runtime/gate-f-2026-08-04 기준 행수. 38개 테이블 중 데이터가 있는 21개입니다.

쉽게 말하면

별도 데이터베이스 서버 대신 약 390MB짜리 파일 하나가 전체 장부입니다. 장부 파일을 통째로 복사하면 그 시점의 백업이 되고, 다른 PC로 옮겨도 같은 기록을 열 수 있습니다.

아래 표의 행은 장부에 쌓인 기록 수입니다. 가장 중요한 대비는 의무 후보 10,408건 vs 사람 검토 2건입니다. 자동 선별 결과는 충분히 쌓였지만, 이를 최종 확정하는 사람의 검토는 거의 시작되지 않았다는 뜻입니다.

모든 테이블이 STRICT 모드이며, 검토·승인 이력 테이블은 UPDATE 없이 INSERT만 허용됩니다.
테이블역할
수집 · 증거 보존
sources수집 대상 문서 식별727
source_versions불변 스냅샷 (재수집마다 새 버전)771
artifacts원본 바이트 sha256 주소화1,542
collection_runs수집 실행 이력96
collection_items배치 내 개별 항목879
fetch_observationsHTTP 응답 관측 기록879
source_availability_observations가용성 상태 전이879
source_changes버전 간 실질 변경 분류771
분해 · 판정
source_fragments조·항·호 단위 원문 조각11,150
obligation_candidates의무 후보 + 판정 근거10,408
fragment_relations위임·인용·제재 엣지10,377
obligation_candidate_reviews사람의 최종 결정 (append-only)2
업무 연결
business_activities처리활동 인벤토리 (현재 가상 데이터)21
activity_obligation_matches업무 × 의무 매칭 + 근거1,475
regulated_subjects승인된 수범자 패턴24
거버넌스 · 운영
source_endpoint_versions승인된 엔드포인트 정의51
endpoint_governance_states중단·재개·검토기한 게이트50
endpoint_governance_actions거버넌스 조치 이력50
scheduled_endpoints수집 스케줄 · 리스50
outbox_events외부 발행 대기 이벤트814
operational_events운영 조치 감사 로그88

현재 상태와 병목

수집·분류는 사실상 완료됐고, 병목은 전부 사람 검토 단계에 몰려 있습니다.

법령 수집
771 / 771
조문 분해
11,150
규칙 분류
10,408
AI 재해석
8,300
사람 검토
2 / 2,056
전수 검토는 성립하지 않습니다

미검토 DUTY 1,094건 + DISCRETION 962건 = 2,056건. 건당 3분이어도 103시간, 법률 해석이 필요한 건은 10분이 넘습니다. 큐 UI를 아무리 빠르게 만들어도 2,056 → 0은 달성 불가능한 목표입니다.

그래서 재구성 방향은 셋입니다 — ① DISCRETION 962건은 "할 수 있다"이지 의무가 아니므로 검토 대상에서 제외, ② 제재조항이 연결된 DUTY 204건만 전수 검토 트랙으로 분리(감사 대응 논리가 가장 명확), ③ 나머지는 조문 단위가 아니라 이미 구축된 업무 21개 · 매칭 1,475건을 축으로 부서가 나눠 확인. 실제 사람 부담이 2,056건 → 204건 전수 + 업무 21개로 떨어집니다.

쉽게 말하면

위 막대는 앞의 자동 공정은 끝났지만 마지막 사람 검토 줄만 거의 비어 있음을 보여줍니다. 서류 분류와 참고 표시까지는 끝났는데, 최종 결재함에 문서가 쌓여 있는 상태입니다.

남은 2,056건을 한 명이 처음부터 끝까지 모두 보는 방식은 현실적으로 지속할 수 없습니다. 그래서 목표를 "전부 검토한다"에서 "중요한 것을 빠뜨리지 않았다고 증명할 수 있다"로 바꿉니다.

DISCRETION은 "~할 수 있다"는 선택 규정이므로 이 계획의 전수 검토 줄에서는 분리합니다. 제재조항이 걸린 204건은 어기면 과태료·형벌로 이어질 수 있어 전부 확인하고, 감사에도 "제재가 연결된 건은 모두 봤다"고 설명할 수 있게 합니다. 나머지는 법전 순서대로 넘기는 대신 "카드발급 업무에 걸린 의무 15건"처럼 업무별 묶음으로 보내 담당 부서가 자기 업무 기준으로 확인합니다. 실제 현업의 책임 단위와 같은 방식입니다.