This commit is contained in:
LASTA_DEV01\lasta
2026-05-19 20:31:52 +09:00
parent 00407e7a08
commit e260e5f218
104 changed files with 12898 additions and 1709 deletions

View File

@@ -0,0 +1,95 @@
# ontology_platform 엔진 경계 분석
작성일: 2026-05-19
## 1. 작업 범위
이번 계획의 대상은 `ontology_platform` 하나다. `crawler_platform`은 별도 이전 작업 산출물로 보고, 이 계획의 유지/확장/수정 판단에 포함하지 않는다.
## 2. 현재 구조 판단
`ontology_platform`은 이미 단일 엔진이 아니라 여러 계층이 얹힌 상태다.
| 영역 | 현재 위치 | 판단 |
|---|---|---|
| OntoCast Base | `vendored/ontocast` | 유지. RDF/GraphUpdate/LangGraph/ToolBox의 핵심 엔진 |
| Platform API | `ont_platform/api/main.py`, `phase*_app.py` | 확장. 단, phase별 앱 초안은 통합 게이트로 정리 필요 |
| Config Gate | `ont_platform/config.py` | 유지/확장. Phase와 storage backend를 막는 좋은 경계 |
| Web Extraction | `core/extractors/web_extractor.py` | 확장. Trafilatura adapter로 명확화 필요 |
| Crawl4AI Adapter | `core/crawler/crawl4ai_adapter.py` | 확장. optional dependency와 profile policy 필요 |
| Validation | `core/validation/*` | 확장. lightweight validator와 Guardrails facade 분리 필요 |
| Candidate Storage | `storage/models.py` | 유지/확장. Review Queue 계약으로 승격 가능 |
| Graph/GraphRAG | `core/graph/*` | 재분류. canonical이 아니라 Neo4j projection/search 계층 |
| Enterprise Drafts | `auth`, `audit`, `billing`, `realtime` | 보류/정리. 운영 phase 이전까지 core flow와 분리 |
## 3. 유지해야 할 것
- `vendored/ontocast/ontocast/onto/sparql_models.py``GraphUpdate` 계약.
- `vendored/ontocast/ontocast/stategraph/`의 기본 workflow.
- `vendored/ontocast/ontocast/tool/agg/`, `tool/triple_manager/`, `toolbox.py`.
- `ont_platform/config.py`의 Phase gate 원칙.
- `PHASE0_ACCEPTANCE_GATE.md`에 기록된 Phase 0 검증 방식.
## 4. 확장해야 할 것
- URL/HTML 입력은 OntoCast core를 바꾸기보다 platform API/adapter에서 변환해 넘긴다.
- 수집 결과는 `SourceDocument``EvidenceSpan`으로 보존한다.
- LLM 산출물은 바로 canonical graph에 반영하지 않고 candidate/review 상태로 저장한다.
- Neo4j 기능은 canonical write path가 아니라 projection, search, GraphRAG 용도로 제한한다.
- 운영 기능(auth/audit/billing/realtime)은 core pipeline 안정화 이후 붙인다.
## 5. 수정해야 할 것
- Phase 0 앱 시작 시 Trafilatura/Crawl4AI/Guardrails/Neo4j 등 미래 phase 의존성이 강제 import되지 않도록 정리한다.
- `phase5_app.py`, `phase6_app.py`, `phase7_app.py`, `phase8_app.py` 같은 실험 앱은 production entrypoint가 아니라 draft app으로 명시한다.
- `core/extraction/lightweight_extractor.py`와 OntoCast extraction의 책임을 분리한다.
- `core/graph`의 알고리즘은 Neo4j projection 이후에만 동작하도록 dependency boundary를 둔다.
## 6. 금지할 것
- OntoCast를 폐기하고 새 extraction engine을 만드는 것.
- Firecrawl 또는 OpenDeepResearcher 코드를 dependency/source로 추가하는 것.
- Neo4j를 canonical truth store로 삼는 것.
- evidence 없는 candidate를 approved graph로 commit하는 것.
- Acceptance Gate 없이 다음 통합 phase를 진행하는 것.
## 7. `ont_platform` 모듈 책임 매트릭스
이 표는 `ontology_platform/ont_platform`의 현재 파일 트리를 기준으로 한 1차 책임 분류다. 이후 작업은 이 분류를 기준으로 Base를 보호하고, adapter와 draft 코드를 단계적으로 활성화한다.
| 모듈 | 책임 분류 | 유지/확장/수정 판단 | 메모 |
|---|---|---|---|
| `config.py` | Base / Gate | 유지 후 확장 | Phase enum, filesystem storage gate, vendored OntoCast import 경로를 관리한다. |
| `api/main.py` | Base API | 유지 후 수정 | production entrypoint다. 미래 phase router가 강제 import되지 않도록 점검이 필요하다. |
| `api/deps.py` | Base API | 유지 | OntoCast ToolBox/AppContext 초기화 책임. |
| `api/db_deps.py` | Operations draft | 보류 | Postgres/SQLAlchemy 계층은 metadata DB 활성화 phase에서 검토한다. |
| `api/routes/extraction.py` | Adapter route / Draft | 수정 필요 | `web_extractor.py`를 통해 Trafilatura를 직접 import하므로 Phase 0 gate와 충돌 가능성이 있다. |
| `api/phase0_app.py` | Draft app | 보류 | 실험/단계별 smoke app으로 분류한다. production app과 분리한다. |
| `api/phase5_app.py` | Draft app | 보류 | GraphRAG 실험 API. `sentence_transformers` import가 있어 phase guard 필요. |
| `api/phase6_app.py` | Draft app | 보류 | RAG/graph API 초안. production entrypoint에 직접 연결하지 않는다. |
| `api/phase7_app.py` | Draft app | 보류 | LLM integration 초안. Phase 7 전에는 optional 영역이다. |
| `api/phase8_app.py` | Operations draft | 보류 | auth/audit/billing/realtime 통합 초안. core pipeline 안정화 이후 활성화한다. |
| `core/extractors/web_extractor.py` | Adapter | 확장 | Trafilatura adapter다. Phase 1부터 활성화한다. |
| `core/crawler/crawl4ai_adapter.py` | Adapter | 확장 | Crawl4AI adapter다. Phase 3 이전에는 강제 import 금지. |
| `core/extraction/lightweight_extractor.py` | Draft extractor | 정리 필요 | 빠른 JSON 후보 추출 MVP다. OntoCast canonical extraction과 책임을 분리한다. |
| `core/extraction/schemas.py` | Draft contract | 확장 | candidate/result schema 계약으로 승격 가능하다. |
| `core/validation/models.py` | Validation contract | 확장 | Pydantic validation model의 중심 후보. |
| `core/validation/validators.py` | Validation adapter | 확장 | lightweight validator. Guardrails facade와 분리한다. |
| `core/validation/guards.py` | Validation adapter | 확장 | Guardrails facade 책임으로 둔다. |
| `core/validation/ontocast_validator.py` | Adapter bridge | 확장 | OntoCast output과 validation contract를 잇는 위치다. |
| `core/graph/*` | Projection/Search adapter | 재분류 | Neo4j projection 이후 분석/search 계층이다. canonical write path가 아니다. |
| `core/projection/__init__.py` | Projection placeholder | 확장 | RDF to Neo4j projection adapter를 둘 위치다. |
| `storage/models.py` | Candidate / Metadata storage | 유지 후 확장 | SourceDocument, EvidenceSpan, CandidateEntity, CandidateRelation, ExtractionJob의 출발점. |
| `storage/init_db.py` | Metadata storage | 확장 | metadata DB 초기화 책임. Phase 2 이후 review storage와 연결한다. |
| `llm/llm_integration.py` | LLM adapter draft | 보류 | OntoCast LLM wrapper/Guardrails integration 전까지 직접 연결하지 않는다. |
| `workflow/__init__.py` | Workflow placeholder | 확장 | Knowledge Agent 패턴 차용 phase에서 LangGraph maintenance loop를 둘 위치다. |
| `auth/*` | Operations draft | 보류 | Phase 6 이후 운영 기능으로 분리한다. |
| `audit/*` | Operations draft | 확장 후보 | review decision, destructive proposal, billing events 기록에 사용 가능하다. |
| `billing/*` | Operations draft | 보류 | BudgetTracker와 별개로 운영 비용 계층에서 검토한다. |
| `realtime/*` | Operations draft | 보류 | WebSocket/progress broadcast는 job orchestration 안정화 뒤 연결한다. |
## 8. 즉시 확인된 다음 작업
- `api/main.py` -> `api.routes` -> `api/routes/extraction.py` -> `core/extractors/web_extractor.py` 경로가 Phase 1 dependency인 Trafilatura를 강제 import하던 문제는 lazy phase route gate로 정리했다.
- `core/crawler/crawl4ai_adapter.py`, `core/graph/neo4j_adapter.py`, `core/graph/entity_resolver.py`는 Phase 0 production entrypoint에서 직접 import되면 안 된다.
- 다음 작업은 Phase 1에서 Trafilatura adapter를 정식 활성화하는 것이다. Phase 0 기준 unit/integration 검증은 `PHASE0_ACCEPTANCE_GATE.md`의 명령을 따른다.

View File

@@ -0,0 +1,45 @@
# Phase 0. 엔진 경계 감사 및 Phase Gate 복구
## 목적
현재 `ontology_platform`에 누적된 phase별 초안 코드를 폐기하지 않고, 각 모듈의 책임을 명확히 분류한다. 먼저 Base 엔진인 OntoCast와 platform wrapper가 깨지지 않는 상태를 복구한다.
## 유지
- `vendored/ontocast`의 state, ontology, RDF, ToolBox, triple manager 구조.
- `ont_platform/config.py``Phase` enum과 filesystem-first storage gate.
- `ont_platform/api/main.py`의 FastAPI entrypoint.
- 기존 `tests/unit`, `tests/integration`, `tests/e2e` 구조.
## 확장
- Phase gate helper를 추가해 미래 phase 기능을 optional로 로딩한다.
- App startup health가 어떤 phase 기능이 활성화되었는지 보여주도록 metadata를 보강한다.
- `docs/phases/PHASE0_ACCEPTANCE_GATE.md`에 현재 검증 상태를 갱신할 기준을 둔다.
## 수정
- `main.py`가 아직 활성화되지 않은 dependency를 직접 import하면 lazy import 또는 phase guard로 감싼다.
- `phase*_app.py`는 실험 앱으로 분류하고 production app과 혼동되지 않게 문서화한다.
- `pyproject.toml`에서 주석 처리된 dependency와 실제 import 상태가 충돌하지 않는지 점검한다.
## 수정 금지
- `vendored/ontocast/ontocast/onto/sparql_models.py`
- `vendored/ontocast/ontocast/stategraph/`
- `vendored/ontocast/ontocast/toolbox.py`
## 상세 작업
1. `ont_platform` 하위 모듈을 Base, Adapter, Draft, Operations로 분류한다.
2. `api/main.py` import graph를 점검하고 optional dependency가 강제 로딩되는 지점을 찾는다.
3. Phase 0 기준으로 `pytest tests/unit tests/integration -v`가 통과하는 것을 기본 검증으로 둔다.
4. E2E는 LLM/로컬 Ollama 준비가 필요한 항목으로 별도 표기한다.
5. `PHASE0_ACCEPTANCE_GATE.md`에 검증 일자와 남은 Gate를 업데이트할 형식을 유지한다.
## 완료 기준
- Phase 0 실행에 Trafilatura/Crawl4AI/Guardrails/Neo4j 설치가 필수가 아니다.
- Unit/integration test 범위가 명확하다.
- production entrypoint와 draft phase app의 책임이 문서로 구분된다.

View File

@@ -0,0 +1,39 @@
# Phase 1. Trafilatura 기반 URL/HTML 입력 정렬
## 목적
URL 또는 HTML 입력을 OntoCast가 이해할 수 있는 document/content 형태로 변환한다. OntoCast core를 직접 확장하기보다 platform adapter에서 웹 본문, 메타데이터, fingerprint, evidence span을 준비한다.
## 유지
- OntoCast의 document conversion workflow.
- `core/extractors/web_extractor.py`의 adapter 방향.
- `storage/models.py``SourceDocument`, `EvidenceSpan` 모델.
## 확장
- Trafilatura dependency 활성화 시점과 fallback policy.
- URL/HTML 입력 API.
- fingerprint 기반 dedup cache.
- 한국어 HTML fixture 기반 검증.
## 수정
- `web_extractor.py`가 Trafilatura 2.x API에 맞는지 확인한다.
- `api/routes/extraction.py`가 Phase 1 활성화 전 앱 시작을 방해하지 않도록 guard를 둔다.
- `SourceDocument.content_hash`, `fingerprint`, metadata 저장 경로를 명확히 연결한다.
## 상세 작업
1. `pyproject.toml`에서 Phase 1 dependency 활성화 조건을 정리한다.
2. `ExtractedWebContent`의 필드를 `SourceDocument` 저장 필드와 1:1로 매핑한다.
3. URL 입력은 `POST /process/url` 또는 `POST /api/v1/extract/url` 중 하나로 통합한다.
4. raw HTML, extracted text, metadata, evidence span이 서로 추적 가능하도록 저장 계약을 만든다.
5. 같은 본문을 가진 HTML fixture 2개로 dedup test를 작성한다.
## 완료 기준
- URL/HTML 입력이 OntoCast 처리 전 단계에서 정제 문서로 변환된다.
- source URL, title, language, content hash, fingerprint가 보존된다.
- Phase 0 test가 회귀 없이 통과한다.

View File

@@ -0,0 +1,39 @@
# Phase 2. Candidate Storage 및 Review 책임 경계
## 목적
AI 또는 lightweight extractor가 만든 결과를 바로 graph에 반영하지 않고 candidate로 저장한다. 사람이 승인하거나 정책이 자동 승인한 항목만 canonical graph로 넘어갈 수 있게 한다.
## 유지
- `storage/models.py``CandidateEntity`, `CandidateRelation`, `ReviewStatus`.
- OntoCast의 canonical RDF/GraphUpdate 개념.
- evidence/provenance 보존 원칙.
## 확장
- Candidate 저장 repository.
- Review API.
- Review decision audit trail.
- Candidate to GraphUpdate promotion 규칙.
## 수정
- `core/extraction/lightweight_extractor.py` 결과와 OntoCast 결과를 같은 candidate contract로 정규화한다.
- `ReviewStatus.PENDING`, `APPROVED`, `AUTO_APPROVED`, `REJECTED` 상태 전이 규칙을 명시한다.
- evidence 없는 candidate는 approved 상태로 전이되지 않도록 validation을 둔다.
## 상세 작업
1. `CandidateEntity``CandidateRelation`에 필요한 최소 repository를 만든다.
2. `EvidenceSpan`과 candidate의 `evidence_ids` 참조 무결성을 검사한다.
3. Review API를 설계한다: list, detail, approve, reject, bulk approve.
4. 승인된 candidate만 OntoCast/Fuseki commit 대상이 되도록 promotion service를 둔다.
5. 자동 승인 정책은 confidence, source_trust, validation_passed 조건을 모두 만족할 때만 허용한다.
## 완료 기준
- extraction 결과가 candidate로 저장된다.
- 승인/반려 상태 변경 이력이 남는다.
- evidence 없는 항목은 graph commit 대상이 아니다.

View File

@@ -0,0 +1,39 @@
# Phase 3. Crawl4AI 수집 계층 및 Job Orchestration
## 목적
정적 URL 1건 처리를 넘어 동적 페이지, deep crawl, sitemap/seed 기반 수집을 지원한다. Crawl4AI는 수집 adapter로만 사용하고, 본문 정제와 candidate 생성은 Trafilatura/OntoCast 흐름으로 넘긴다.
## 유지
- `core/crawler/crawl4ai_adapter.py`의 adapter 방향.
- `PlatformSettings.robots_policy`.
- `storage.models.ExtractionJob` 또는 이에 상응하는 job metadata.
## 확장
- Crawl profile: `fast_static`, `dynamic_page`, `full_capture`, `structured_extract`, `deep_discovery`.
- Job queue와 progress reporting.
- SourceDocument batch import.
- browser pool recycle/stress test 기준.
## 수정
- Crawl4AI import는 Phase 3 dependency가 활성화된 경우에만 일어난다.
- 동적 페이지 수집 결과도 Trafilatura 후처리 또는 equivalent content normalization을 거친다.
- robots policy와 cache policy는 hard-code하지 않고 settings로 분리한다.
## 상세 작업
1. `Crawl4AIAdapter`의 profile selection 정책을 설정 기반으로 만든다.
2. seed URL, sitemap, same-domain, max pages, max depth 입력 모델을 정의한다.
3. job start/status/cancel API를 설계한다.
4. job progress는 polling API를 먼저 만들고, WebSocket은 안정화 뒤 붙인다.
5. 수집된 각 page는 `SourceDocument`로 저장되고 Phase 1 ingestion을 통과한다.
## 완료 기준
- 동적 페이지 수집과 static fallback 경로가 분리된다.
- 50페이지 이하 deep crawl smoke가 안정적으로 종료된다.
- 수집 결과가 candidate review 흐름으로 이어진다.

View File

@@ -0,0 +1,39 @@
# Phase 4. Guardrails Validation Gate
## 목적
LLM이 만든 ontology/facts 후보가 schema를 위반한 채로 저장되는 것을 막는다. Guardrails는 검증 라이브러리로 사용하며, platform 쪽 facade를 통해 OntoCast 출력에 연결한다.
## 유지
- `core/validation/models.py`의 Pydantic extraction model 방향.
- `core/validation/validators.py`의 lightweight validator.
- OntoCast renderer/critic loop.
## 확장
- Guardrails facade.
- on_fail 정책: fix, reask, filter, refrain.
- ValidationIssue 저장 모델 또는 candidate metadata.
- validation result를 review decision에 반영하는 정책.
## 수정
- Guardrails Hub/telemetry는 사용하지 않는다.
- OntoCast `tool/llm.py`를 직접 대규모 수정하기보다 wrapper/facade 주입을 먼저 검토한다.
- validator 실패가 무한 reask로 이어지지 않도록 제한을 둔다.
## 상세 작업
1. `OntologyExtractionResult`, `OntologyEntity`, `OntologyRelation` 모델을 확정한다.
2. entity id format, duplicate entity id, relation endpoint exists, confidence range validator를 작성한다.
3. schema violation fixture를 만들어 lightweight validator와 Guardrails validator의 결과를 비교한다.
4. validation 실패 결과를 candidate metadata 또는 별도 issue table로 남긴다.
5. approved promotion 전에 validation_passed를 필수 조건으로 둔다.
## 완료 기준
- confidence > 1 같은 잘못된 결과가 자동 fix 또는 reject된다.
- 존재하지 않는 entity를 참조하는 relation이 approved graph로 들어가지 않는다.
- validation 실패 사유가 review 화면/API에서 추적 가능하다.

View File

@@ -0,0 +1,39 @@
# Phase 5. Neo4j Projection 및 GraphRAG 검색
## 목적
Fuseki/RDF를 canonical truth로 유지하고, Neo4j는 projection, graph search, GraphRAG, Text2Cypher 전용으로 사용한다. 양쪽에 동시에 쓰는 구조를 만들지 않는다.
## 유지
- OntoCast GraphUpdate/RDF canonical model.
- `core/graph`의 resolver, pattern, analytics 모듈은 projection 이후 분석 도구로 유지.
- Neo4j GraphRAG는 library/adapter로만 접근한다.
## 확장
- `core/projection/rdf_to_neo4j.py`.
- Neo4j sync job.
- vector/hybrid/Text2Cypher/GraphRAG API.
- search result provenance.
## 수정
- `core/graph`가 canonical write path처럼 보이지 않도록 이름과 문서 책임을 정리한다.
- Text2Cypher는 read-only, allowlist, timeout, result limit을 강제한다.
- Neo4j dependency는 Phase 5 활성화 전 import되지 않도록 guard를 둔다.
## 상세 작업
1. RDF subject/predicate/object를 Neo4j node/relationship으로 변환하는 projection contract를 만든다.
2. Document/Chunk/Entity lexical graph와 entity graph를 분리한다.
3. projection sync 상태를 저장한다: last_sync_at, source_graph_hash, error.
4. Vector/Hybrid search 결과가 source document/evidence span으로 돌아갈 수 있게 provenance를 연결한다.
5. Text2Cypher query sanitizer와 read-only guard를 작성한다.
## 완료 기준
- canonical RDF commit 이후 Neo4j projection이 동기화된다.
- GraphRAG 답변 또는 search result에서 evidence/source URL을 확인할 수 있다.
- write/delete Cypher가 차단된다.

View File

@@ -0,0 +1,41 @@
# Phase 6. Maintenance Loop 및 운영 기능 정리
## 목적
Knowledge Agent는 코드가 아니라 workflow pattern과 prompt만 차용한다. OntoCast 기반 graph를 분석하고, 공백을 찾고, 새 source를 제안하고, 문제를 고치는 maintenance loop를 platform 기능으로 추가한다.
## 유지
- OntoCast LangGraph workflow.
- `auth`, `audit`, `billing`, `realtime` 초안 모듈은 운영 기능 후보로 유지.
- `audit/logger.py`와 review 이력은 destructive action 추적에 사용한다.
## 확장
- Analyst, Researcher, Curator, Auditor, Fixer, Advisor 역할.
- maintenance run API.
- human approval gate.
- cost/budget and audit reporting.
## 수정
- Knowledge Agent 원본 코드는 가져오지 않는다.
- Fixer는 graph 변경을 직접 실행하지 않고 proposal/candidate로 만든다.
- realtime/billing/auth는 core pipeline 안정화 뒤 활성화한다.
## 상세 작업
1. maintenance workflow state model을 정의한다.
2. Analyst는 graph gap, low confidence, missing evidence, duplicate candidate를 찾는다.
3. Researcher는 source discovery 계획만 만든다.
4. Curator는 source quality를 평가해 ingestion job을 제안한다.
5. Auditor는 schema/evidence/provenance issue를 만든다.
6. Fixer는 수정 proposal만 생성하고 사람 승인을 기다린다.
7. Advisor는 반복 이슈와 비용/품질 추세를 보고한다.
## 완료 기준
- maintenance loop가 graph를 직접 파괴적으로 수정하지 않는다.
- 모든 fix proposal은 review gate를 통과해야 한다.
- audit log와 budget summary가 함께 남는다.

View File

@@ -7,17 +7,20 @@
| # | Acceptance Gate 항목 | 상태 | 검증 방법 |
|---|---|---|---|
| 1 | 단일 PDF/JSON 입력 → ontology TTL + facts TTL이 filesystem에 생성됨 | ⚠️ **e2e 검증 대기** (로컬 LLM/API 키 필요) | `tests/e2e/test_phase0_full_pipeline.py` |
| 2 | `/health`, `/info`, `/process` (FastAPI) 정상 동작 | ✅ **통합 테스트 10/10 통과** (2026-05-14) | `tests/integration/test_api_smoke.py` |
| 2 | `/health`, `/info`, `/process` (FastAPI) 정상 동작 | ✅ **통합 테스트 11/11 통과** (2026-05-19) | `tests/integration/test_api_smoke.py` |
| 3 | BudgetTracker가 LLM call/triple count를 정확히 기록 | ⚠️ **e2e 검증 대기** (mock 검증은 통합 테스트로 통과) | e2e 테스트가 실제 검증 |
| 4 | LangGraph 워크플로우 (CONVERT→CHUNK→...→SERIALIZE) 전 노드 traceable | ✅ **OntoCast 원본 워크플로우 무수정 채택** | `vendored/ontocast/ontocast/stategraph/` 그대로 사용 |
추가로 **단위 테스트 16/16 통과** (test_convert_document 7, test_platform_config 5, test_select_ontology 4).
자동 검증 기준으로는 **unit + integration 27/27 통과**가 현재 Phase 0 기본선이다.
**현재 진척 (2026-05-14)**:
- Python 3.13.13 환경 + `pip install -e ".[dev]"` 완료
**현재 진척 (2026-05-19)**:
- Python 3.14.5 `.venv` 환경에서 unit + integration 27/27 통과
- `python-multipart`를 Phase 0 FastAPI multipart upload 필수 의존성으로 추가
- Phase 0 production app에서 Phase 1 Trafilatura route가 기본 mount되지 않도록 lazy phase route gate 적용
- `pip install -e ".[dev]"` 또는 동등한 의존성 설치 필요
- `pip install -e vendored/ontocast` 로 OntoCast 의존성 설치 완료
- 패키지 이름 충돌 수정: `platform/``ont_platform/` (Python 내장 `platform` 모듈과 충돌)
- 단위 + 통합 테스트 26/26 모두 통과
- **남은 작업**: e2e 테스트 (Acceptance Gate #1, #3) 실행 — 로컬 Ollama 또는 OpenAI 키 필요
## 다음 작업자가 실행할 검증 절차
@@ -45,7 +48,7 @@ Copy-Item .env.example .env
```powershell
# 단위 + 통합 테스트만 (LLM 호출 없음, 빠름)
pytest tests/unit tests/integration -v
.venv\Scripts\python.exe -m pytest tests/unit tests/integration -v
```
**기대 결과**: 모든 케이스 PASS.
@@ -53,7 +56,16 @@ pytest tests/unit tests/integration -v
- `tests/unit/test_select_ontology.py` (4 케이스) — Phase 0.2 검증
- `tests/unit/test_convert_document.py` (7 케이스) — Phase 0.3 검증
- `tests/unit/test_platform_config.py` (5 케이스) — Phase 0.5 검증
- `tests/integration/test_api_smoke.py` (10 케이스) — Phase 0.4 + 0.6 mock 검증
- `tests/integration/test_api_smoke.py` (11 케이스) — Phase 0.4 + 0.6 mock 검증, Phase 0 future dependency route gate 검증
Windows에서 `%TEMP%` 권한 문제 또는 `.pytest_cache` 쓰기 문제가 발생하면 아래처럼 pytest temp/cache 위치를 workspace 내부로 고정한다.
```powershell
$env:TMP=(Join-Path (Resolve-Path '.').Path 'pytest_tmp')
$env:TEMP=$env:TMP
New-Item -ItemType Directory -Force -Path $env:TMP | Out-Null
.venv\Scripts\python.exe -m pytest tests/unit tests/integration -v --basetemp "$env:TMP\basetemp" -o cache_dir="$env:TMP\cache"
```
### 3) End-to-end 검증 (Acceptance Gate #1, #3, #4)
@@ -116,4 +128,5 @@ curl -X POST http://localhost:8000/process `
|---|---|---|
| 2026-05-13 | (코드 작성: ontology-platform agent) | 코드 준비 완료. 실 환경 검증 보류. |
| 2026-05-14 | lasta + Claude | **unit 16/16, integration 10/10 통과** (Gate #2 ✅). 패키지 이름 충돌 수정 (`platform``ont_platform`). e2e는 LLM 필요로 대기. |
| 2026-05-19 | Codex | **unit 16/16, integration 11/11, 총 27/27 통과**. Phase 0 route gate 추가로 Trafilatura route는 PHASE>=1에서만 lazy mount. e2e는 LLM 필요로 대기. |
| ____-__-__ | ________________ | __________________________________ |

View File

@@ -0,0 +1,33 @@
# Phase 1 Acceptance Gate 결과
작성일: 2026-05-19
범위: Trafilatura 기반 URL/HTML 입력 정렬, SourceDocument/EvidenceSpan 계약, URL 입력 API, fixture 기반 dedup 검증.
## 결과 요약
| # | Acceptance Gate 항목 | 상태 | 검증 방법 |
|---|---|---|---|
| 1 | URL/HTML 입력이 정제 문서로 변환됨 | 통과 | `tests/unit/test_web_extractor.py` |
| 2 | source URL, title, language, content hash, fingerprint 보존 | 통과 | `test_extract_from_korean_html_preserves_document_contract` |
| 3 | `SourceDocument`, `EvidenceSpan`, Content metadata 경계 연결 | 통과 | `test_extracted_content_maps_to_source_document_and_evidence_spans`, `test_content_unit.py` |
| 4 | `/process/url`, `/api/v1/extract/url` URL 입력 API 제공 | 통과 | `tests/integration/test_url_ingest.py` |
| 5 | 같은 본문 중복 입력은 fingerprint 기반으로 skip | 통과 | `test_same_clean_body_gets_same_hash_and_fingerprint`, `test_process_url_skips_duplicate_payload_by_fingerprint` |
| 6 | Phase 0 회귀 없음 | 통과 | `python -m pytest tests/unit tests/integration -q` |
## 검증 이력
| 일자 | 검증자 | 결과 |
|---|---|---|
| 2026-05-19 | Codex | Phase 1 신규 테스트 7/7 통과. 전체 unit/integration 34/34 통과. |
## 구현 메모
- `ont_platform/core/extractors/web_extractor.py`는 Trafilatura 2.x `bare_extraction`을 사용하되, local HTML fixture에서 Trafilatura fingerprint가 비어 있는 경우 normalized text 기반 `sha1:` fingerprint를 생성한다.
- `ont_platform/storage/models.py`의 SQLAlchemy 예약어 충돌을 피하기 위해 DB 컬럼명은 `metadata`로 유지하고 Python attribute는 `metadata_`로 정리했다.
- `/process/url`, `/api/v1/process/url`, `/api/v1/extract/url`은 같은 Phase 1 응답 계약을 사용한다.
- OntoCast vendored core는 수정하지 않았다.
## 다음 Gate
Phase 2는 Candidate Storage 및 Review 책임 경계를 다룬다. 진행 전 `PHASE_INDEX.md`에서 Phase 2 항목만 명시적으로 선택해 작업한다.

View File

@@ -0,0 +1,35 @@
# Phase 2 Acceptance Gate 결과
작성일: 2026-05-19
범위: Candidate Storage 및 Review 책임 경계. Lightweight/OntoCast 후보 저장 경로, review 상태 전이, audit trail, evidence 기반 promotion gate.
## 결과 요약
| # | Acceptance Gate 항목 | 상태 | 검증 방법 |
|---|---|---|---|
| 1 | extraction 결과가 candidate로 저장됨 | 통과 | `tests/unit/test_candidate_repository.py` |
| 2 | lightweight와 OntoCast 저장 경로가 분리됨 | 통과 | `test_repository_saves_lightweight_candidates_with_evidence`, `test_repository_saves_ontocast_candidates_on_separate_source_path` |
| 3 | 승인/반려/자동승인 상태 변경 이력이 남음 | 통과 | `tests/unit/test_review_service.py` |
| 4 | evidence 없는 항목은 승인 및 graph commit 대상이 아님 | 통과 | `test_candidate_without_evidence_cannot_be_approved`, `test_promotion_plan_blocks_approved_candidate_without_evidence` |
| 5 | Review API가 ingest/list/detail/approve/reject/promote 흐름을 제공함 | 통과 | `tests/integration/test_review_api.py` |
| 6 | Phase 0-1 회귀 없음 | 통과 | `python -m pytest tests/unit tests/integration -q` |
## 검증 이력
| 일자 | 검증자 | 결과 |
|---|---|---|
| 2026-05-19 | Codex | Phase 2 신규 테스트 9/9 통과. 전체 unit/integration 43/43 통과. 변경 파일 대상 ruff 통과. |
## 구현 메모
- `CandidateEntity`, `CandidateRelation``source_type`, `created_by`, `validation_passed`, `promoted_at`을 추가해 review queue 계약을 명확히 했다.
- `ReviewDecision`으로 상태 변경 audit trail을 남긴다.
- `CandidateRepository.save_lightweight_result()``save_ontocast_result()`를 분리해 두 입력 경로가 같은 candidate contract로 정규화되되, 출처는 유지된다.
- `ReviewService``pending -> approved/rejected/auto_approved`, `approved/auto_approved -> rejected`만 허용한다.
- `CandidatePromotionService``approved` 또는 `auto_approved`이면서 evidence가 실제 존재하는 후보만 commit plan에 포함한다.
- OntoCast vendored core는 수정하지 않았다.
## 다음 Gate
Phase 3은 Crawl4AI 수집 계층 및 Job Orchestration이다. 진행 전 `PHASE_INDEX.md`에서 Phase 3 항목만 명시적으로 선택해 작업한다.

View File

@@ -0,0 +1,27 @@
# Phase 2 — Candidate Storage 및 Review 책임 경계
본 문서는 Phase 1 완료 후 다음 작업자가 Phase 2를 시작할 때 참고할 핸드오프 노트다. 자동으로 Phase 2를 진행하지 않는다.
## 시작 전 확인
- `PHASE_INDEX.md`에서 Phase 2 진행 요청이 명시되어 있는지 확인한다.
- `PHASE1_ACCEPTANCE_GATE.md`의 unit/integration 34/34 통과 상태를 기준선으로 삼는다.
- vendored OntoCast core는 계속 직접 수정하지 않는다.
## Phase 2 목표
추출 결과를 바로 확정 그래프로 보내지 않고, 사람이 검토할 수 있는 candidate/review queue 계약으로 분리한다. SourceDocument와 EvidenceSpan이 없는 후보는 확정 graph로 들어가지 못하게 한다.
## 작업 범위
1. `storage/models.py``CandidateEntity`, `CandidateRelation`을 review queue 계약으로 확정한다.
2. OntoCast 결과와 lightweight extraction 결과의 저장 경로를 분리한다.
3. `pending`, `approved`, `auto_approved`, `rejected` 상태 전이 규칙을 문서와 테스트로 고정한다.
4. evidence 없는 후보가 확정 graph로 승격되지 못하도록 validation boundary를 둔다.
## 권장 테스트
- 후보 생성 시 `document_id``evidence_ids`가 필수로 연결되는지 검증한다.
- 승인/반려/자동승인 상태 전이가 허용된 경로로만 움직이는지 검증한다.
- evidence 없는 entity/relation이 commit 단계에 도달하지 못하는지 검증한다.
- Phase 1 URL/HTML ingestion 테스트가 계속 통과하는지 회귀 검증한다.

View File

@@ -0,0 +1,28 @@
# Phase 3 — Crawl4AI 수집 계층 및 Job Orchestration
본 문서는 Phase 2 완료 후 다음 작업자가 Phase 3을 시작할 때 참고할 핸드오프 노트다. 자동으로 Phase 3을 진행하지 않는다.
## 시작 전 확인
- `PHASE_INDEX.md`에서 Phase 3 진행 요청이 명시되어 있는지 확인한다.
- `PHASE2_ACCEPTANCE_GATE.md`의 unit/integration 43/43 통과 상태를 기준선으로 삼는다.
- 수집 계층은 SourceDocument 생성 전 단계까지만 책임진다. Candidate 저장과 Review Queue는 Phase 2 계약을 사용한다.
- vendored OntoCast core는 계속 직접 수정하지 않는다.
## Phase 3 목표
정적 URL 1건 처리를 넘어 동적 페이지와 대량 수집을 job 단위로 관리한다. Crawl4AI는 acquisition adapter로 감싸고, 본문 정제는 Phase 1 Trafilatura adapter, 후보 저장은 Phase 2 Review Queue로 넘긴다.
## 작업 범위
1. `crawl4ai_adapter.py`를 동적/대량 수집 adapter로 제한한다.
2. crawler profile, robots policy, cache policy를 설정 기반으로 분리한다.
3. Job 상태 모델과 progress API/WebSocket 경계를 정리한다.
4. 수집 결과를 Trafilatura 후처리와 SourceDocument 저장으로 연결한다.
## 권장 테스트
- 정적 HTML/동적 페이지 profile이 같은 SourceDocument 계약으로 이어지는지 검증한다.
- robots/cache policy가 설정값에 따라 선택되는지 검증한다.
- job 상태가 pending/running/completed/failed로 전이되는지 검증한다.
- Phase 1 extraction 및 Phase 2 review queue 테스트가 계속 통과하는지 회귀 검증한다.

View File

@@ -0,0 +1,89 @@
# PHASE INDEX - ontology_platform engine-respect roadmap
?묒꽦?? 2026-05-19
踰붿쐞: `ontology_platform` ?꾩슜. `crawler_platform`?€ ?대쾲 ?묒뾽 踰붿쐞?먯꽌 ?쒖쇅?쒕떎.
湲곗? 臾몄꽌:
- `ontology_platform/docs/?듯빀?ㅺ퀎??md`
- `ontology_platform/README.md`
- `ontology_platform/docs/phases/PHASE0_ACCEPTANCE_GATE.md`
- `ontology_platform/docs/phases/PHASE1_NEXT_STEPS.md`
- `ontology_platform/docs/phases/PHASE1_ACCEPTANCE_GATE.md`
- `ontology_platform/docs/phases/PHASE2_ACCEPTANCE_GATE.md`
?듭떖 ?먯튃:
- OntoCast??Base ?붿쭊?쇰줈 議댁쨷?쒕떎.
- vendored OntoCast 肄붿뼱???듯빀?ㅺ퀎?쒓? ?덉슜??踰붿쐞 ?몄뿉???섏젙?섏? ?딅뒗??
- Trafilatura, Crawl4AI, Guardrails, Neo4j GraphRAG??吏곸젒 ?ш뎄?꾪븯吏€ ?딄퀬 ?뉗? adapter/facade濡?媛먯떬??
- Firecrawl, OpenDeepResearcher 肄붾뱶???ы븿?섏? ?딅뒗??
- Acceptance Gate瑜??듦낵?섍린 ???ㅼ쓬 ?듯빀?쇰줈 ?섏뼱媛€吏€ ?딅뒗??
---
PHASE 0. ?붿쭊 寃쎄퀎 媛먯궗 諛?Phase Gate 蹂듦뎄
FILE: ./26_05_19_engine_respect_plan/phase_00_001_engine_boundary_gate.md
1) ?꾩옱 `ont_platform` 紐⑤뱢??Base/Adapter/Draft/Excluded 梨낆엫?쇰줈 遺꾨쪟 [?꾨즺]
2) Phase 0?먯꽌 誘몃옒 Phase ?섏〈?깆씠 import?섏뼱 ???쒖옉??源⑥? ?딅룄濡?寃뚯씠???뺣━ [?꾨즺]
3) Phase 0 unit/integration 寃€利??덉감 怨좎젙 [?꾨즺]
4) `PHASE0_ACCEPTANCE_GATE.md` 媛깆떊 湲곗? ?뺣━ [?꾨즺]
---
PHASE 1. Trafilatura 湲곕컲 URL/HTML ?낅젰 ?뺣젹
FILE: ./26_05_19_engine_respect_plan/phase_01_001_trafilatura_ingestion.md
1) `web_extractor.py`瑜?Trafilatura adapter 梨낆엫?쇰줈 ?뺣━ [?꾨즺]
2) `SourceDocument`, `EvidenceSpan`, Content metadata ?€??寃쎄퀎 ?곌껐 [?꾨즺]
3) `/process/url` ?먮뒗 ?숇벑??URL ?낅젰 API ?ㅺ퀎 [?꾨즺]
4) ?쒓뎅??URL/HTML fixture 湲곕컲 異붿텧 ?뚯뒪?몄? dedup 湲곗? ?묒꽦 [?꾨즺]
---
PHASE 2. Candidate Storage 諛?Review 梨낆엫 寃쎄퀎
FILE: ./26_05_19_engine_respect_plan/phase_02_001_candidate_review_boundary.md
1) `storage/models.py`???꾨낫 紐⑤뜽???뺤떇 Review Queue 怨꾩빟?쇰줈 ?뺤젙 [?꾨즺]
2) OntoCast 寃곌낵?€ lightweight extraction 寃곌낵???€??寃쎈줈 遺꾨━ [?꾨즺]
3) ?뱀씤/諛섎젮/?먮룞?뱀씤 ?곹깭 ?꾩씠 洹쒖튃 ?뺤쓽 [?꾨즺]
4) evidence ?녿뒗 ?꾨낫媛€ ?뺤젙 graph濡??ㅼ뼱媛€吏€ 紐삵븯寃?李⑤떒 [?꾨즺]
---
PHASE 3. Crawl4AI ?섏쭛 怨꾩링 諛?Job Orchestration
FILE: ./26_05_19_engine_respect_plan/phase_03_001_crawl4ai_acquisition_jobs.md
1) `crawl4ai_adapter.py`瑜??숈쟻/?€???섏쭛 adapter濡??쒗븳 [?꾨즺]
2) crawler profile, robots policy, cache policy瑜??ㅼ젙 湲곕컲?쇰줈 遺꾨━ [?꾨즺]
3) Job ?곹깭 紐⑤뜽怨?progress API/WebSocket 寃쎄퀎 ?뺣━ [?꾨즺]
4) Trafilatura ?꾩쿂由ъ? SourceDocument ?€?μ쑝濡??곌껐 [?꾨즺]
---
PHASE 4. Guardrails Validation Gate
FILE: ./26_05_19_engine_respect_plan/phase_04_001_guardrails_validation_gate.md
1) `core/validation`??Pydantic lightweight?€ Guardrails facade濡?遺꾨━ [?꾨즺]
2) OntoCast LLM 異쒕젰 ?섑븨 吏€?먯쓣 vendored ?섏젙 ?놁씠 ?곗꽑 ?ㅺ퀎 [?꾨즺]
3) schema violation, endpoint missing, confidence range ?뚯뒪???묒꽦 [?꾨즺]
4) Guard ?ㅽ뙣 寃곌낵瑜?candidate/review issue濡??€??[?꾨즺]
---
PHASE 5. Neo4j Projection 諛?GraphRAG 寃€??FILE: ./26_05_19_engine_respect_plan/phase_05_001_neo4j_projection_graphrag.md
1) RDF/Fuseki瑜?canonical store, Neo4j瑜?projection/search store濡?怨좎젙 [?꾨즺]
2) `core/graph` 湲곗〈 紐⑤뱢??projection/search adapter 梨낆엫?쇰줈 ?щ텇瑜?[?꾨즺]
3) read-only Text2Cypher?€ vector/hybrid retriever API ?ㅺ퀎 [?꾨즺]
4) provenance媛€ search result源뚯? ?댁뼱吏€??寃€利?湲곗? ?묒꽦 [?꾨즺]
---
PHASE 6. Maintenance Loop 諛??댁쁺 湲곕뒫 ?뺣━
FILE: ./26_05_19_engine_respect_plan/phase_06_001_maintenance_loop_operations.md
1) Knowledge Agent??肄붾뱶媛€ ?꾨땲???꾨\?꾪듃/?뚰겕?뚮줈???⑦꽩留?李⑥슜 [?꾨즺]
2) Analyst/Researcher/Curator/Auditor/Fixer/Advisor 梨낆엫 ?뺤쓽 [?꾨즺]
3) `auth`, `audit`, `billing`, `realtime` 珥덉븞 紐⑤뱢???댁쁺 寃쎄퀎 ?뺣━ [?꾨즺]
4) destructive fix???щ엺 ?뱀씤 寃뚯씠?몃? 諛섎뱶???듦낵?섎룄濡??ㅺ퀎 [?꾨즺]