수집 → 경계 검사 → 정규화·채점 → 영속화 → 소비 5단으로, 9/18 리뷰 수정에서 나온 불변식을 그림으로 고정한다. 제공자별 풀·버킷(RiskScorer v3) · 라운드트립이 원 점수를 재현 (_evidence_payload <-> _domain_evidence_from_ui) · host 는 저장 시 해석하고 복원 시 우선 반환 · 지식DB 지문 매칭이 풀링 밖 유일한 high 승격 경로 작성 중 확인한 사실도 반영했다: 프로덕션 LLM 경로는 영속화된 payload 를 _domain_evidence_from_ui 로 복원해 넣는다(store_operations.py:487). 그래서 프롬프트가 host 를 보는 것은 복원 경로 덕분이다 — analysis/evidence_enrichment.py 의 EvidenceEnricher 는 테스트에서만 쓰인다. 소스는 evidence-dataflow.dataflow.json (archify dataflow v1). 그림을 고치려면 JSON 을 고쳐 재생성한다. 산출물은 자체 완결 HTML 로 외부 요청이 없다. 검증: archify showcase 통과(아티팩트 검사 9/9 · 합성 오류 0 · 경고 0), visual-check 통과(1440x900 · 2048x1320 각 Light/Dark, 오버플로 0, 최소 투영 텍스트 6.71px >= 6px). html sha256 268f3352 (822,655 B). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BStHFrjQj2VypecSG9ex1V
304 lines
7.3 KiB
JSON
304 lines
7.3 KiB
JSON
{
|
|
"schema_version": 1,
|
|
"diagram_type": "dataflow",
|
|
"meta": {
|
|
"title": "증거 데이터 흐름 — 수집에서 판정까지",
|
|
"output": "docs/diagrams/evidence-dataflow.html",
|
|
"quality_profile": "showcase",
|
|
"views": [
|
|
{
|
|
"id": "collect-boundary",
|
|
"label": "수집 경계",
|
|
"focus": [
|
|
"vision",
|
|
"cse",
|
|
"naver",
|
|
"policy",
|
|
"normalizer"
|
|
],
|
|
"note": "외부 응답이 Evidence 가 되기까지 통과하는 데이터 등급 경계."
|
|
},
|
|
{
|
|
"id": "scoring",
|
|
"label": "채점",
|
|
"focus": [
|
|
"normalizer",
|
|
"scorer",
|
|
"knowledge"
|
|
],
|
|
"note": "제공자별 풀·버킷과, 풀링 대상이 아닌 지식DB 승격 경로."
|
|
},
|
|
{
|
|
"id": "roundtrip",
|
|
"label": "라운드트립",
|
|
"focus": [
|
|
"payload",
|
|
"sqlite",
|
|
"restore",
|
|
"scorer"
|
|
],
|
|
"note": "저장과 복원이 원 점수를 재현해야 하는 고리."
|
|
}
|
|
],
|
|
"viewBox": [
|
|
1080,
|
|
500
|
|
]
|
|
},
|
|
"stages": [
|
|
{
|
|
"label": "수집"
|
|
},
|
|
{
|
|
"label": "경계 검사"
|
|
},
|
|
{
|
|
"label": "정규화 · 채점"
|
|
},
|
|
{
|
|
"label": "영속화"
|
|
},
|
|
{
|
|
"label": "소비"
|
|
}
|
|
],
|
|
"nodes": [
|
|
{
|
|
"id": "vision",
|
|
"type": "external",
|
|
"label": "Cloud Vision",
|
|
"sublabel": "웹 탐지 · 엔티티",
|
|
"tag": "match",
|
|
"brand": "google-cloud",
|
|
"stage": 0,
|
|
"row": 0
|
|
},
|
|
{
|
|
"id": "cse",
|
|
"type": "external",
|
|
"label": "Google 맞춤 검색",
|
|
"sublabel": "이미지 · 웹문서",
|
|
"tag": "match=page",
|
|
"stage": 0,
|
|
"row": 1
|
|
},
|
|
{
|
|
"id": "naver",
|
|
"type": "external",
|
|
"label": "네이버 검색",
|
|
"sublabel": "블로그 · 웹문서",
|
|
"tag": "promoted",
|
|
"stage": 0,
|
|
"row": 2
|
|
},
|
|
{
|
|
"id": "knowledge",
|
|
"type": "database",
|
|
"label": "지식DB · 주의목록",
|
|
"sublabel": "등록 이미지 지문",
|
|
"tag": "내부",
|
|
"stage": 2,
|
|
"row": 2
|
|
},
|
|
{
|
|
"id": "policy",
|
|
"type": "security",
|
|
"label": "데이터 등급 검사",
|
|
"sublabel": "payload 허용 목록",
|
|
"tag": "SEARCH_EVIDENCE",
|
|
"stage": 1,
|
|
"row": 1
|
|
},
|
|
{
|
|
"id": "normalizer",
|
|
"type": "backend",
|
|
"label": "증거 정규화",
|
|
"sublabel": "Evidence 레코드",
|
|
"tag": "source",
|
|
"stage": 2,
|
|
"row": 0
|
|
},
|
|
{
|
|
"id": "scorer",
|
|
"type": "backend",
|
|
"label": "RiskScorer",
|
|
"sublabel": "제공자별 풀 · 버킷",
|
|
"tag": "v3",
|
|
"stage": 2,
|
|
"row": 1
|
|
},
|
|
{
|
|
"id": "payload",
|
|
"type": "backend",
|
|
"label": "_evidence_payload",
|
|
"sublabel": "도메인 → payload",
|
|
"tag": "host 해석",
|
|
"stage": 3,
|
|
"row": 0
|
|
},
|
|
{
|
|
"id": "sqlite",
|
|
"type": "database",
|
|
"label": "evidence 테이블",
|
|
"sublabel": "payload JSON · WAL",
|
|
"tag": "cascade",
|
|
"stage": 3,
|
|
"row": 1
|
|
},
|
|
{
|
|
"id": "restore",
|
|
"type": "backend",
|
|
"label": "증거 복원",
|
|
"sublabel": "payload → 도메인",
|
|
"tag": "복원",
|
|
"stage": 3,
|
|
"row": 2
|
|
},
|
|
{
|
|
"id": "console",
|
|
"type": "frontend",
|
|
"label": "운영자 콘솔",
|
|
"sublabel": "증거 카드 · host 칩",
|
|
"tag": "판정",
|
|
"stage": 4,
|
|
"row": 0
|
|
},
|
|
{
|
|
"id": "llm",
|
|
"type": "backend",
|
|
"label": "LLM 증거 판독",
|
|
"sublabel": "상위 12행 화이트리스트",
|
|
"tag": "ko-v4",
|
|
"stage": 4,
|
|
"row": 1
|
|
}
|
|
],
|
|
"flows": [
|
|
{
|
|
"id": "vision-payload",
|
|
"from": "vision",
|
|
"to": "policy",
|
|
"label": "웹 탐지 결과",
|
|
"classification": "외부 응답",
|
|
"route": "top-channel"
|
|
},
|
|
{
|
|
"id": "cse-payload",
|
|
"from": "cse",
|
|
"to": "policy",
|
|
"label": "검색 결과",
|
|
"classification": "외부 응답",
|
|
"route": "straight"
|
|
},
|
|
{
|
|
"id": "naver-payload",
|
|
"from": "naver",
|
|
"to": "policy",
|
|
"label": "블로그 · 웹문서",
|
|
"classification": "외부 응답",
|
|
"route": "bottom-channel"
|
|
},
|
|
{
|
|
"id": "allowed-fields",
|
|
"from": "policy",
|
|
"to": "normalizer",
|
|
"label": "허용 필드만 통과",
|
|
"classification": "등급 통제",
|
|
"variant": "security"
|
|
},
|
|
{
|
|
"id": "evidence-record",
|
|
"from": "normalizer",
|
|
"to": "scorer",
|
|
"label": "채점 입력 신호",
|
|
"classification": "주 경로",
|
|
"variant": "emphasis",
|
|
"labelDy": 36
|
|
},
|
|
{
|
|
"id": "fingerprint-match",
|
|
"from": "knowledge",
|
|
"to": "scorer",
|
|
"label": "지문 유사도 0.9+ → 80점",
|
|
"classification": "풀링 제외",
|
|
"labelDy": -20
|
|
},
|
|
{
|
|
"id": "score-band",
|
|
"from": "scorer",
|
|
"to": "payload",
|
|
"label": "점수 · 밴드 · 사유",
|
|
"classification": "주 경로",
|
|
"variant": "emphasis"
|
|
},
|
|
{
|
|
"id": "serialize",
|
|
"from": "payload",
|
|
"to": "sqlite",
|
|
"label": "payload JSON · host",
|
|
"classification": "주 경로",
|
|
"variant": "emphasis",
|
|
"labelDy": 36
|
|
},
|
|
{
|
|
"id": "reload-restore",
|
|
"from": "sqlite",
|
|
"to": "restore",
|
|
"label": "리로드 · 판정 시 복원",
|
|
"classification": "읽기 경로",
|
|
"labelDy": 36
|
|
},
|
|
{
|
|
"id": "roundtrip-invariant",
|
|
"from": "restore",
|
|
"to": "scorer",
|
|
"label": "원 점수 재현",
|
|
"classification": "불변식",
|
|
"variant": "emphasis"
|
|
},
|
|
{
|
|
"id": "bootstrap-read",
|
|
"from": "sqlite",
|
|
"to": "console",
|
|
"label": "bootstrap 조회",
|
|
"classification": "읽기 경로"
|
|
},
|
|
{
|
|
"id": "evidence-reading",
|
|
"from": "restore",
|
|
"to": "llm",
|
|
"label": "증거 판독 요청",
|
|
"classification": "읽기 경로"
|
|
}
|
|
],
|
|
"cards": [
|
|
{
|
|
"dot": "emerald",
|
|
"title": "주 경로",
|
|
"items": [
|
|
"외부 응답은 데이터 등급 검사를 통과한 필드만 Evidence 가 된다",
|
|
"RiskScorer v3 는 풀과 dedup 버킷을 제공자별로 나눈다 (presence 60 / entity 20)",
|
|
"점수 · 밴드 · 사유는 payload 로 직렬화되어 evidence 테이블에 남는다"
|
|
]
|
|
},
|
|
{
|
|
"dot": "rose",
|
|
"title": "라운드트립 불변식",
|
|
"items": [
|
|
"_evidence_payload 로 직렬화하고 _domain_evidence_from_ui 로 복원한다",
|
|
"복원된 증거를 다시 채점하면 원 점수가 재현되어야 한다",
|
|
"result_url → url 별칭이 0점을 45점으로 바꾼 사고가 있었다",
|
|
"host 는 저장 시 해석하고 복원 시 우선 반환한다 — API 이름으로 되돌아가지 않는다"
|
|
]
|
|
},
|
|
{
|
|
"dot": "orange",
|
|
"title": "소비 경로",
|
|
"items": [
|
|
"콘솔은 영속화된 payload 를 읽는다 — 호스트 칩은 20ch 로 잘리고 전체는 툴팁에 있다",
|
|
"LLM 은 복원된 증거 상위 12행만 본다 — 인용 없는 claim 은 폐기된다",
|
|
"지식DB 지문 매칭은 풀링 대상이 아니며, 라벨만으로는 닿지 않는 high 승격 경로다"
|
|
]
|
|
}
|
|
]
|
|
}
|