Skip to content

feat: OKF bundle 어댑터 추가 (export/import, kind별 폴더 라우팅)#242

Merged
seyoung4503 merged 5 commits into
CausalInferenceLab:masterfrom
thrcle:feat/okf-bundle-adapter
Jul 19, 2026
Merged

feat: OKF bundle 어댑터 추가 (export/import, kind별 폴더 라우팅)#242
seyoung4503 merged 5 commits into
CausalInferenceLab:masterfrom
thrcle:feat/okf-bundle-adapter

Conversation

@thrcle

@thrcle thrcle commented Jul 18, 2026

Copy link
Copy Markdown
Collaborator

#️⃣ Issue Number

없음

📝 요약(Summary)

한 줄 요약: 비즈니스 용어를 사람이 읽을 수 있는 마크다운 파일로 내보내고 불러오는 저장 레이어를 추가합니다.

해결하려는 문제

현재 등록된 비즈니스 용어는 SQLite KV에 JSON 문자열로만 존재합니다. 팀 간 공유나 변경 이력 추적이 불가능하고, 용어가 어떻게 쌓여 있는지 사람이 직접 확인할 방법이 없습니다.

이번 변경으로 달라지는 것

Google Cloud가 발표한 OKF(Open Knowledge Format) 스펙을 따라 용어를 .md 파일로 저장하는 어댑터를 추가합니다.

export 하면 아래 구조로 파일이 생성됩니다:

bundle/
├── guild/
│   ├── metrics/활성고객.md
│   ├── tables/orders.md
│   └── rules/환불제외.md
└── channel:마케팅/
    └── metrics/활성고객.md     ← 팀별 override 분리 저장

각 파일은 OKF 스펙의 YAML frontmatter + markdown body 형식입니다. 예시:

type: Metric
title: 활성고객
description: "30일 내 로그인한 users"
tags: [growth]
layer: guild
entity: ''
inferred: false

KV 캐시는 그대로 유지되며, 런타임 동작에는 변화가 없습니다. 이 어댑터는 export/import 시에만 호출됩니다.

다음 PR과의 관계

PR3(ingest_doc 확인 루프)에서 사용자가 Discord에서 후보를 승인하면 이 어댑터를 통해 .md 파일로 저장됩니다.

💬 To Reviewers

이 PR은 총 4개로 구성된 시리즈의 두 번째입니다. PR1 머지 후 순차 머지 부탁드립니다.

PR1 (FedEntry kind 필드) → PR2 (이 PR) → PR3 (ingest_doc 확인 루프) → PR4 (disambiguation 개선)

  • PyYAML을 의존성에 추가했습니다. 프로젝트 방향과 맞는지 확인 부탁드립니다.
  • OKF type 필드와 내부 kind 필드 매핑(metricMetric) 방식이 적절한지 의견 주시면 감사합니다.

PR Checklist

  • 변경 사항에 대한 테스트 또는 검증 완료 (신규 테스트 9개: 직렬화 단위, 폴더 구조, round-trip)
  • 로컬에서 정상 동작 확인 (133 passed)
  • 관련 문서 업데이트 완료

thrcle and others added 5 commits July 18, 2026 15:08
비즈니스 용어를 Metric/Table/Rule/Dimension으로 분류할 수 있도록
FedEntry에 kind, applies_to, tags 필드를 추가한다.

- FedEntry: kind, applies_to, tags 필드 추가 (기존 JSON 하위호환)
- term_custom tool spec: 세 파라미터 노출
- _fmt_entry: kind 배지 표시 (`metric` 등)
- 신규 테스트 3개: round-trip, 하위호환, kind 배지 렌더링

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Pre-commit black check (--all-files) was consistently failing on master
and all PR branches. This commit formats all Python files to make CI green.
No logic changes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Google OKF 스펙을 따라 KV 용어를 .md 파일로 내보내고
불러오는 OkfBundle 어댑터를 추가한다.

- adapters/storage/okf_bundle.py 신규: export/import, kind별 폴더 라우팅
- pyproject.toml: PyYAML 의존성 추가
- 신규 테스트 9개: 직렬화 단위, 폴더 구조, round-trip

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@seyoung4503

Copy link
Copy Markdown
Collaborator

머지 가능합니다. 신규 테스트 9개 통과.

OkfBundle을 부르는 곳이 아직 테스트뿐이라(src/ 안에서는 import 없음) 이 PR 단독으로는 실행 경로가 없습니다.

확인한 것:

  • 한글 용어·파일명 왕복 정상 (활성_사용자.md 포함)
  • kind 폴더 라우팅 대칭 — export capitalize() / import .lower(), 미지 타입은 misc/로 폴백
  • 번들 폴더가 없어도 크래시 없이 0건 반환
  • yaml.safe_load 사용 — 역직렬화 취약점 없음
  • PyYAML>=6.0 의존성 정상 추가 (로컬은 uv sync 필요)

#243 머지 전에 아래 두 가지는 꼭 처리 부탁드립니다. #243이 confirm_ingest.py:133에서 이 export를 호출하면서 사용자 문서로부터 도달 가능한 경로가 됩니다.

1. 파일 경로 검증 없음 (:113-116, :109-111)

용어명을 파일명으로 바꿀 때 공백과 :만 치환하고 /, ..는 통과시킵니다. 재현했습니다:

번들에 title: ../../../ESCAPED 인 항목 → import → export
→ 대상 폴더보다 두 단계 위에 파일 생성됨

번들은 사용자가 주는 파일이라 이름을 통제할 수 없습니다. 안전한 문자만 남기고, 쓰기 직전에 path.resolve().is_relative_to(self.base_dir.resolve()) 확인이 필요합니다.

2. 정의에 ---가 있으면 조용히 사라집니다 (:152)

text.index("---", 3)이 줄 단위가 아니라 글자 단위 검색입니다. 본문에 마크다운 구분선이 있으면 frontmatter가 중간에서 잘려 safe_load가 실패하고, _md_to_entryNone을 반환해 :96-98에서 건너뜁니다. 에러도 카운트도 없어서 export는 성공했는데 import하면 없어집니다.

수정: 줄머리 \n--- 매칭 또는 text.split("\n---\n", 2)

후속 PR로 챙겨주시면 좋을 것

  • 깨진 파일 하나가 import 전체를 중단시킵니다 (:148, read_texttry 밖). docstring은 "파싱 실패 시 None 반환"인데 실제로는 예외가 밖으로 나갑니다
  • "Active User""active user"가 같은 파일로 덮어써집니다 (:115)
  • export가 삭제된 용어의 .md를 지우지 않아서, 지운 용어가 다시 import하면 되살아납니다
  • _RESERVEDindex.md를 건너뛰는데 정작 만드는 코드가 없습니다

전체 스택 리뷰는 #244에 있습니다.

@seyoung4503 seyoung4503 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 감사합니다

@seyoung4503
seyoung4503 merged commit 49735ef into CausalInferenceLab:master Jul 19, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants