Files
jarca-ledger-mcp/docs/discovery/dcy-014_20260708_import-provenance-sensitive-data-policy.md
T

261 lines
20 KiB
Markdown

# 0. 문서 상태
이 문서의 현재 상태와 식별 정보를 기록한다. 문서 추적과 승인 흐름에 필요한 최소 메타데이터를 적는다.
- 상태: confirmed
- 문서 ID: dcy-014_20260708_import-provenance-sensitive-data-policy
- 이슈명: Import provenance 및 민감자료 저장 정책 정리
- 작성 시각(KST): 2026-07-08 10:48 KST
- 마지막 갱신 시각(KST): 2026-07-08 11:26 KST
- 대체됨: 없음
- 후속 Discovery 참조: 없음
- 생성된 REQ 참조: `REQ-021`
# 1. 계획 상태 요약
- 연계 문서 현황:
- GitHub Project 4 `Jarca` Todo: `Import provenance 및 민감자료 저장 정책 정리`
- 선행 Discovery: `dcy-002` 운영 안전 백업/복구/검증 DB 정책, `dcy-006` CI fixture 안전 정책, `dcy-011` import pipeline 분리, `dcy-012` review decision payload 최소화, `dcy-013` Docker network MCP 배포
- 관련 baseline 문서: `docs/data-model.md`, `docs/project-structure.md`, `docs/runtime-flows.md`
- 다음 REQ 번호: `REQ-021`
- 해석:
- Jarca Ledger는 PDF/XLSX/CSV import와 rollback/audit을 이미 제공하지만, source file path, raw payload, parser metadata, row-level provenance, 민감자료 최소보관 정책이 하나의 표준으로 정리되어 있지 않다.
- finance agent와 network MCP 소비자가 늘어나는 상태에서 import lineage와 민감정보 경계를 명확히 정의하지 않으면 운영 DB, test fixture, logs, Streamlit/MCP 응답에 원본 금융 증빙이 과다 노출될 위험이 있다.
# 2. 요구사항 판정 결과
- 판정: 신규 후속 주기
- 근거
- 기존 dcy-011/REQ-016은 import pipeline의 application/infrastructure layering을 다뤘고, provenance schema·민감자료 저장 정책 자체를 요구사항으로 확정하지 않았다.
- dcy-012/REQ-020은 review decision `target_payload`에서 raw payload/password/token/secret/file path를 제거하는 국소 정책을 추가했지만, import 전반의 provenance·retention·MCP 노출 정책은 별도 Discovery로 다루는 것이 책임 경계가 명확하다.
# 3. 문제점의 요약
- 현재 상태
- `transactions`에는 `source`, `import_batch_id`, `external_id`, `dedupe_key`, `raw_summary`, `raw_payload`, `counterparty`, `branch` 등 import evidence 성격의 필드가 존재한다.
- `import_batches`는 `source`, `filename`, `imported_at`, `row_count`, `status`, `memo`를 저장하며, 일부 import path는 `memo` JSON 안에 `source_hash`, parser metadata, validation, parsed row count를 저장한다.
- `imports_service.py`는 KB Bank PDF, Toss Bank PDF, Toss Securities PDF, SeoulPay XLSX, CSV import에서 source hash, parser preview, validation, duplicate check, rollback을 처리한다.
- `docs/data-model.md`는 import evidence field 보존과 raw payload의 민감성, password runtime-only 원칙을 언급하지만, row-level provenance 최소 필드·filename masking/hash·retention·MCP/Streamlit 노출 정책은 아직 확정되지 않았다.
- `docs/runtime-flows.md`는 import preview/import flow를 설명하지만, source file 처리·row index 추적·raw evidence storage boundary·agent-facing response boundary는 구체화되어 있지 않다.
- 기대 상태
- import provenance는 rollback/audit/dedupe/reconciliation에 필요한 최소 필드로 표준화된다.
- 원본 파일명, 전체 파일 경로, PDF text, raw payload, 계좌/카드 식별자, 비밀번호, token/secret류는 DB/repo/log/MCP 응답에서 최소보관·마스킹·해시화 원칙을 따른다.
- 운영 DB와 synthetic/validation fixture의 민감자료 경계가 명확해지고, CI/AppTest/HTTP smoke가 실데이터를 참조하지 않는다는 기존 dcy-006 원칙과 연결된다.
- finance agent가 MCP를 통해 provenance를 읽을 때 필요한 audit metadata만 받고 원본 금융 증빙은 받지 않는다.
- 이해관계자
- 주인님/운영자 — 실제 가계 금융 원본자료와 운영 DB의 소유자
- finance agent — Jarca Ledger MCP를 소비하는 agent, raw evidence 대신 안전한 lineage metadata가 필요하다.
- 가웨인/dev-butler — 데이터 모델, import interface, MCP/Streamlit 노출 경계를 설계·검증하는 기술 책임자
- 향후 QC/감사 작업자 — rollback/audit/reconciliation 근거를 검증하되 원본 민감자료에 과도하게 접근하지 않아야 한다.
- 주요 사용자 시나리오
- 운영자가 KB/Toss/SeoulPay/CSV 파일을 preview/import할 때, 시스템은 거래 row가 어느 source/parser/batch에서 왔는지 추적 가능한 metadata를 남긴다.
- 운영자가 duplicate, rollback, reconciliation 문제를 조사할 때, 원본 파일 전체나 raw payload 없이도 batch/source hash/row reference로 원인을 좁힐 수 있다.
- finance agent가 MCP로 거래·import 상태를 조회할 때, 민감한 file path/password/raw text는 응답에 포함되지 않는다.
- 개발자가 test fixture/CI를 만들 때, 실제 금융 원본이나 raw payload를 repo에 커밋하지 않는 기준을 따른다.
# 4. 이번에 정의할 변경
- Import provenance 표준: source kind, parser name/version, source hash, masked filename, source row/page reference, import batch, dedupe key, validation summary 등 최소 audit metadata를 정의한다.
- 민감자료 저장/노출 정책: raw payload, raw summary, source filename/path, account/card identifiers, passwords, tokens/secrets, PDF text/XLSX row 원문에 대한 DB/repo/log/MCP/Streamlit boundary를 정의한다.
- 데이터 모델 및 runtime flow 반영 기준: `docs/data-model.md`, `docs/project-structure.md`, `docs/runtime-flows.md`에 import provenance와 sensitive-data policy가 traceable하게 반영되어야 한다.
## 영향 범위
- 코드 영향:
- `jarca_ledger_mcp/application/imports_service.py`
- `jarca_ledger_mcp/infrastructure/parsers/*`
- `jarca_ledger_mcp/infrastructure/sqlite/schema.py`, `migrations.py`
- `jarca_ledger_mcp/adapters/mcp/server.py`, `tool_contracts.py`
- Streamlit import/operations gateway가 provenance를 표시하는 경우 해당 gateway/page
- 데이터 영향:
- `transactions.source`, `external_id`, `dedupe_key`, `raw_summary`, `raw_payload`, `import_batch_id`
- `import_batches.filename`, `memo`
- 신규 또는 변경 가능성이 있는 provenance table/JSON schema
- 문서 영향:
- `docs/data-model.md`
- `docs/project-structure.md`
- `docs/runtime-flows.md`
- import/backup/safety 관련 runbook 또는 StagePilot REQ/BAT 문서
# 5. 요구사항 목록
## 기능 요구사항
- FR-1: 각 import source는 source kind, parser identity, source hash, import batch id, row/page reference, dedupe key, validation summary를 포함하는 표준 provenance envelope를 가져야 한다.
- FR-2: DB에 저장되는 filename/path 정책은 원본 전체 경로 저장을 피하고, 필요 시 masked basename 또는 hash를 사용해야 한다.
- FR-3: raw payload와 raw summary는 audit 필요성과 민감도에 따라 보존/축소/마스킹/미저장 중 하나로 분류되어야 하며, source별 기본값을 가져야 한다.
- FR-4: MCP/Streamlit read surface는 agent/operator에게 필요한 provenance metadata를 제공하되 password, token/secret, 전체 파일 경로, 원본 PDF text, 불필요한 raw payload를 노출하지 않아야 한다.
- FR-5: rollback/duplicate/reconciliation workflow는 새 provenance 정책으로도 기존 operational safety와 auditability를 잃지 않아야 한다.
- FR-6: baseline docs는 import provenance와 sensitive-data policy를 데이터 모델, runtime flow, repository structure의 공통 기준으로 반영해야 한다.
## 비기능 요구사항
- NFR-1 (privacy by minimization): 운영 DB·repo fixture·logs·MCP responses는 목적 달성에 필요한 최소 금융 증빙만 보존하거나 노출해야 한다.
- NFR-2 (auditability): 민감자료를 줄이더라도 import batch, transaction, rollback, duplicate 판단의 재현 가능한 lineage는 유지되어야 한다.
- NFR-3 (backward compatibility): 기존 운영 DB의 import rows는 additive migration 또는 compatibility adapter로 읽을 수 있어야 하며, destructive rewrite는 별도 승인 없이는 금지한다.
- NFR-4 (test safety): CI/AppTest/HTTP smoke fixtures는 synthetic/temp DB만 사용하고 실제 원본 파일명·계좌 식별자·raw payload를 포함하지 않아야 한다.
## 정책 결정 결과
### raw_payload `minimize`의 의미
`minimize`는 raw evidence를 전부 삭제한다는 뜻이 아니라, **원본 문서/row 덤프를 저장하지 않고 재현성에 필요한 정규화된 최소 provenance만 저장**한다는 뜻이다.
- 저장 허용:
- source kind: `kb_bank_pdf`, `toss_bank_pdf`, `toss_securities_pdf`, `seoulpay_xlsx`, `csv_generic`
- parser name/version 또는 parser identity
- `source_hash`와 필요 시 짧은 prefix
- import batch id
- source row/page/sheet reference: page number, sheet name, row index, section/action code 등 원본 위치를 좁힐 수 있는 값
- normalized transaction evidence: date/time, amount, direction/type, masked account hint, normalized merchant/counterparty, validation summary
- duplicate/rollback에 필요한 `external_id`, `dedupe_key`, validation result, parsed row count
- 저장 금지:
- password, token, secret
- 전체 파일 경로
- 원본 PDF text 전체
- XLSX/CSV row 전체 dump
- 계좌번호/카드번호 원문
- 불필요한 raw payload 전체 JSON
- source별 예외:
- source별 parser가 audit에 꼭 필요한 작은 필드를 갖는 경우 REQ-021에서 allowlist로 명시한다.
- allowlist 밖 key는 기본 저장하지 않거나 masking한다.
### filename/path 정책
- `import_batches.filename`에는 전체 path를 저장하지 않는다.
- 운영자 표시에는 `masked-basename`을 사용하고, 실제 동일성/추적성은 `source_hash`로 판정한다.
- 예: `/volume1/private/국민은행_고진환_2026년06월.pdf` → `국민은행_***_2026년06월.pdf` + `source_hash`.
### MCP provenance 노출 정책
- `minimal`: agent 기본값. `source`, `import_batch_id`, `external_id`, `dedupe_key`, `source_hash_prefix` 정도만 제공한다.
- `operator-summary`: 운영자 화면/도구용. masked filename, parser identity, row/page/sheet reference, validation summary를 포함할 수 있다.
- `debug-gated`: 명시 debug gate가 있을 때만 parser diagnostics를 제공한다. raw 원문·password·전체 path는 여전히 제외한다.
### 기존 운영 DB sanitization 분리
- 기존 운영 DB의 raw payload/file path 정리는 REQ-021에 섞지 않는다.
- 별도 GitHub Project Todo `기존 운영 DB import evidence sanitization preview 및 정리`로 분리했다.
- 해당 후속 작업은 scan → preview report → backup → explicit approval → narrow migration → verification 순서로만 진행한다.
### finance agent privacy boundary 및 destructive migration 원칙
- finance agent는 raw financial evidence를 소비하지 않고 normalized provenance metadata만 소비한다.
- destructive migration은 preview/backup/명시 승인 없이는 금지한다.
### 코드 기준 import source matrix
| Source | 현재 코드 기준 저장/응답 항목 | 민감 위험 | REQ-021 권고 저장/노출 |
|---|---|---|---|
| KB Bank PDF | `source_hash`, `page_count`, `metadata`, `validation`, `parsed_row_count`, `parsed["file_path"]`, `transactions.raw_payload`, `raw_summary`, `branch`, `balance_after`, `external_id`, `dedupe_key` | file path, holder/account metadata, PDF-derived raw payload, branch/balance detail | masked filename + source_hash, page/row reference, parser identity, validation summary, minimized payload allowlist |
| Toss Bank PDF | `source_hash`, `page_count`, `metadata`, `validation`, `parsed_row_count`, `parsed["file_path"]`, action/counterparty/balance/raw_summary/raw_payload, `external_id`, `dedupe_key` | file path, account masked metadata, counterparty/action raw text, balance detail | masked filename + source_hash, action category, row/page reference, normalized counterparty, minimized payload allowlist |
| Toss Securities PDF | `source_hash`, `page_count`, `metadata`, `validation`, `parsed_row_count`, `parsed["file_path"]`, section/action/code/name/quantity/unit_price/fee/tax/balance/raw_payload | securities detail and counterparty/security raw text, file path, account metadata | masked filename + source_hash, section/action/code where needed, normalized security/counterparty summary, numeric details only when audit-required |
| SeoulPay XLSX | `source_hash`, `sheet_name`, `metadata`, `validation`, `parsed_row_count`, `parsed["file_path"]`, transaction kind/payment kind/no/merchant id/channel/raw_payload | XLSX file path, merchant id, transaction no, raw row payload | masked filename + source_hash, sheet name, row index/reference, payment kind/category summary, minimized merchant/transaction reference |
| CSV preview | `filename=str(path)`, raw preview rows from `csv.DictReader` | arbitrary user columns may include sensitive data; preview currently can echo raw CSV rows | preview output should mask/limit columns by allowlist; import policy should require source profile and sensitive-column filtering |
## 범위 경계
- In Scope
- import provenance field policy와 민감자료 저장/노출 정책 정의
- source별 provenance default와 raw evidence classification
- additive schema 또는 JSON envelope 변경 필요성 판단
- MCP/Streamlit response boundary 정의
- baseline docs 갱신 요구 정의
- Out of Scope
- 외부 보안감사나 법무 검토 자체
- 실운영 DB의 대량 destructive migration
- 파일 암호화 vault 또는 장기 보존 시스템 구축
- 외부 공개 API auth/TLS 설계 — dcy-013의 network MCP 내부망 전제와 별도
# 6. 리스크/가정 목록
## 리스크
- R-1 (High): raw payload/file path를 계속 저장하면 운영 DB, backup, debug log, MCP response를 통해 실제 금융 원본자료가 과다 노출될 수 있다.
- 완화 방안: source별 저장 허용 필드와 금지 필드를 명시하고, 민감 key filtering 및 fixture/log scan을 검증 기준에 포함한다.
- R-2 (High): 민감자료를 과도하게 제거하면 duplicate 판단, rollback, reconciliation, audit 재현성이 약해질 수 있다.
- 완화 방안: raw evidence 대신 source hash, row/page reference, parser version, normalized dedupe inputs를 provenance envelope에 남긴다.
- R-3 (Medium): 기존 운영 DB에는 이미 `raw_payload`와 `import_batches.filename/memo`가 있어 새로운 정책과 충돌할 수 있다.
- 완화 방안: backward-compatible read policy와 optional sanitization/migration plan을 REQ에서 분리해 정의한다.
- R-4 (Medium): finance agent가 필요 이상 상세한 provenance를 MCP로 받으면 privacy boundary가 agent prompt/log로 확장된다.
- 완화 방안: agent-facing default response와 operator/debug response를 분리한다.
## 가정
- A-1: Jarca Ledger는 운영 DB를 source of truth로 유지하되, 원본 PDF/XLSX/CSV 파일 자체를 repo에 보관하지 않는다.
- A-2: import source별 parser는 원본에서 normalized transaction rows와 validation summary를 만들 수 있다.
- A-3: rollback과 duplicate check는 full raw document가 아니라 stable hash/dedupe/provenance metadata로 충분히 수행 가능하다.
- A-4: 운영자가 정말 원본 증빙을 확인해야 할 때는 DB/MCP가 아니라 별도 로컬 파일 보관 위치에서 직접 확인한다.
## 오픈 질문
- Q-1: `transactions.raw_payload`의 장기 정책은 source별 유지/축소/마스킹/미저장 중 무엇이어야 하는가?
- 상태: Answered — 기본 정책은 `minimize`다. raw 원문 전체를 저장하지 않고, rollback/dedupe/audit에 필요한 normalized 최소 필드만 보존한다.
- Q-2: `import_batches.filename`은 전체 경로, basename, masked basename, hash 중 무엇을 저장해야 하는가?
- 상태: Answered — `masked-basename + source_hash`를 사용한다. 전체 경로는 저장하지 않는다.
- Q-3: MCP default response에서 provenance detail을 어느 수준까지 노출할 것인가?
- 상태: Answered — 기본은 `minimal`, 운영자용은 `operator-summary`, debug 상세는 별도 gate로 분리한다.
- Q-4: 기존 운영 DB에 이미 저장된 raw payload/file path를 정리하는 migration을 이번 범위에 포함할 것인가, 별도 follow-up으로 둘 것인가?
- 상태: Answered — 이번 REQ에서는 정책/신규 동작을 정의하고, 기존 운영 DB sanitization은 별도 GitHub Project Todo/후속 SDLC로 분리한다.
# 7. 초기 성공 기준
- S-1: import provenance policy가 source별 최소 필드, 금지 필드, 저장 위치(DB/log/repo/MCP/Streamlit)를 표로 정의한다.
- S-2: REQ-021은 기존 import 기능의 backward compatibility를 유지하면서 additive schema/API 변경 여부를 명확히 한다.
- S-3: sensitive-data test 또는 static scan 기준이 정의되어 raw payload/password/token/secret/file path가 fixture/log/MCP response에 불필요하게 남지 않음을 검증할 수 있다.
- S-4: rollback, duplicate check, audit investigation이 raw document 없이도 source hash/import batch/row reference/dedupe metadata로 설명 가능하다.
- S-5: `docs/data-model.md`, `docs/project-structure.md`, `docs/runtime-flows.md`가 새로운 provenance/sensitive-data policy를 반영한다.
## 측정 방식 및 데이터 출처
- S-1: Discovery/REQ policy table, source-by-source classification matrix
- S-2: REQ acceptance criteria와 additive migration design
- S-3: pytest/static scan/contract smoke evidence
- S-4: synthetic import fixture를 사용한 duplicate/rollback/audit smoke
- S-5: baseline docs diff와 StagePilot doctor traceability
# 8. REQ로 넘기기 전 확인 체크
- [x] source별 raw evidence 보존 정책 결정 — `raw_payload=minimize`
- [x] filename/path 저장 정책 결정 — `masked-basename + source_hash`
- [x] MCP default/debug/operator response boundary 결정 — `minimal`/`operator-summary`/`debug-gated`
- [x] 기존 운영 DB sanitization을 이번 delivery에 포함할지 결정 — 별도 GitHub Project Todo로 분리
- [x] 관련 현재 코드와 baseline 문서 확인
- [x] baseline 문서 갱신 필요성 식별
# 9. 파일 처리 결과
- 처리 결과: 생성
- 생성 경로: `docs/discovery/dcy-014_20260708_import-provenance-sensitive-data-policy.md`
- 참조 문서:
- `docs/data-model.md`
- `docs/project-structure.md`
- `docs/runtime-flows.md`
- `docs/discovery/dcy-002_20260627_operational-safety-backup-restore-validation-db.md`
- `docs/discovery/dcy-006_20260630_pytest-apptest-smoke-ci-automation.md`
- `docs/discovery/dcy-011_20260703_backend-refactor-phase4-write-import-workflow-adapter-narrowing.md`
- `docs/discovery/dcy-012_20260703_review-queue-reconciliation-workbench-persistence.md`
- `jarca_ledger_mcp/application/imports_service.py`
- `jarca_ledger_mcp/infrastructure/sqlite/schema.py`
- `stage-pilot/templates/project-structure.md`
- `stage-pilot/templates/runtime-flows.md`
# 10. 사용자 결정 필요 항목 요약
## DECIDE
- 없음 — 사용자 결정 반영 완료.
## CONFIRM
- 없음 — finance agent privacy boundary 및 destructive migration 금지 원칙 확인 완료.
## DATA
- 없음 — import source matrix를 코드 기준으로 작성 완료.
# 11. Discovery Freeze
## 섹션 참조
- 범위: [# 5. 요구사항 목록 > 범위 경계](#5-요구사항-목록)
- 리스크/오픈 질문: [# 6. 리스크/가정 목록](#6-리스크가정-목록)
- 성공 기준: [# 7. 초기 성공 기준](#7-초기-성공-기준)
## Freeze 플래그
- Handoff Decision: confirmed
- Handoff Rationale: 사용자 결정으로 raw_payload minimize, masked-basename + source_hash, MCP minimal/operator-summary/debug-gated, 기존 DB sanitization 후속 분리, finance agent privacy boundary, destructive migration 금지 원칙이 확정되어 REQ-021 초안 작성으로 인계 가능하다.
- Ready for REQ Drafting: true
- Confirmed By: 고진환
- Confirmed At (KST): 2026-07-08 10:58 KST