docs: codex 기능 검토 원문 보존 + 검증 결과·채택 순위 기록
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BStHFrjQj2VypecSG9ex1V
This commit is contained in:
parent
29534f441a
commit
30772e93cf
2 changed files with 76 additions and 0 deletions
|
|
@ -1,5 +1,7 @@
|
|||
# Project INDEX
|
||||
|
||||
- 2026-09-23 · **codex 기능 검토** (`docs/reviews/2026-09-23-codex-feature-review.md`, 읽기 전용 샌드박스). 검증: F1 보류→주의 후보→재제출 시 80/high **CONFIRMED**(`internal_analyzer.py` 가 watchlist 도 knowledge_entry_id 로 내고 스코어러는 entry_status 를 안 본다) · F4 반려(메모)→승인(무메모) 시 내보내기 메모가 이전 반려 메모 **CONFIRMED**(`_latest_decision_memo` 가 마지막 비어있지 않은 메모를 고른다) · F2 '미사용' 버튼이 오탐과 구분 없이 점수 제거 **PLAUSIBLE**(UI 는 사용/미사용 2버튼, 서버 상태는 4종) · F6 파일명 stem 충돌 CONFIRMED(기존 문서화 한계) · 통계 분모 0 → 0% 표시 CONFIRMED(기존 부채). 채택 순위: ① 보류 사유 분리 + 주의 후보의 80점 자동 승격 차단 ② 판정 정정 일관성(메모·파생 기준) ③ 투입 충돌 감지 ④ 인용/무관/오탐 분리 ⑤ 검색 완결성 표시. 미채택: 출처별 신뢰도 자동 학습(codex 도 보류 권고), 지원자 통지 연동(L, 외부 시스템).
|
||||
|
||||
- 2026-09-23 · **심사 가이드 다이어그램** — `docs/diagrams/review-guide.html` (archify workflow v2, 5번째 다이어그램). 문서의 6단계를 3레인(읽기·근거 확인 / 판정 / 기준 DB 에 남는 것)으로: 한 줄 요약 → 점수 구성 → 증거 열기 → 근거 표시 → 판정 → 다음 미심사, 분기는 미수행 하한(→ 보류 후 재분석)과 판정 뒤 DB(주의 후보 자동 · 클리어 기준 등록 수동). 첫 안은 4레인·3항목 카드로 1440×900 에서 127px 넘쳐 레인 병합·제목 한 줄·카드 2항목으로 압축(노드 폭 148 로 종횡비 1.52 충족). validate 9/9 showcase · visual-check 4뷰포트 containment pass · manifest 5종. rebuild 스크립트·manifest 갱신기에 등록, PROJECT_MAP 표 추가.
|
||||
- 2026-09-23 · **심사 가이드 v2** — `docs/operations/review-guide.md`. 기존 `operator-review-workflow` 다이어그램은 시스템 흐름(폴더→분석→채점)이라 "어떻게 심사하고 무엇을 보는가"에 답하지 못했다. 운영자 관점으로 다시 썼다: 한 건 심사 6단계(한 줄 읽기 → 점수 구성 → 동일→부분→페이지 순 증거 → 사용/무관/오탐 표시 → A/H/R → N), 한 줄 요약의 신호 9종과 판정 무게(라벨은 권리와 무관, 미수행은 안전 아님), 승인/보류/반려 기준과 **뒤에 일어나는 일**(보류·반려 → 주의 후보, 승인은 DB 에 안 남으니 `클리어 기준 등록` 별도), 반려 사유 프리셋, 키보드, 일괄 처리, 헷갈리는 것 5개, 종료 루틴(내보내기·통계·임계 재검토). 콘솔 라벨은 실제 index.html 문자열로 대조.
|
||||
|
||||
|
|
|
|||
74
docs/reviews/2026-09-23-codex-feature-review.md
Normal file
74
docs/reviews/2026-09-23-codex-feature-review.md
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
# 2026-09-23 codex 기능 검토 (원문)
|
||||
|
||||
> `codex exec --sandbox read-only` (codex-cli 0.154.0). 프롬프트: 하루 50~100건 운영 가정, 병목 · 없는 기능 · 점수 오도 시나리오 · 기준 DB 오염 · 상위 5개. 파일 링크의 절대 경로는 작성 당시 로컬 경로다. 검증 결과와 채택 여부는 INDEX 의 같은 날짜 항목 참조.
|
||||
|
||||
가장 큰 문제는 **검색·심사·권리 확인의 미완료 상태가 위험 점수와 기준 DB에 섞이고, 판정을 바꾼 뒤에도 과거 판단의 영향이 남는 것**입니다. 하루 50~100건에서는 검색 자체보다 보류 재처리와 잘못 남은 판정 근거를 정리하는 일이 병목이 될 가능성이 큽니다.
|
||||
|
||||
지정 문서·화면 구조와 관련 구현을 읽었습니다. 점수 시나리오와 메모 조회는 합성 입력으로 실행 확인했습니다. 파일·DB는 수정하지 않았으며, 처리 시간과 발생 빈도는 실사용 측정이 아닌 추정입니다.
|
||||
|
||||
**1. 시간을 잡아먹거나 실수를 유발하는 지점**
|
||||
|
||||
| 발견 | 운영에 미치는 영향 | 파일·줄 근거 |
|
||||
|---|---|---|
|
||||
| **F1. 검색 장애로 보류한 사진이 다음에는 ‘등록 권리 대상’이 된다.** 보류·반려 모두 활성 주의 후보를 만들고, 주의 후보도 유사도 0.9 이상이면 80점을 받는다. | “확인하지 못함”이 “위험하다고 확인함”처럼 재사용된다. 장애 때문에 보류한 정상 이미지가 재제출될 때 high로 올라가 반복 심사를 유발할 수 있다. | [sqlite_store.py:798](src/rights_filter/server/sqlite_store.py:798), [store_operations.py:167](src/rights_filter/server/store_operations.py:167), [internal_analyzer.py:53](src/rights_filter/analysis/internal_analyzer.py:53), [risk_scoring.py:190](src/rights_filter/analysis/risk_scoring.py:190) |
|
||||
| **F2. ‘미사용’ 버튼의 뜻과 실제 효과가 다르다.** 행 버튼은 사용/미사용 두 개이고, 미사용을 `false_positive`로 전송한다. | “다른 증거를 대표 근거로 골랐으니 이것은 인용하지 않겠다”는 조작이 오탐 판정과 점수 제거로 이어진다. 가이드는 무관/오탐을 구분하지만 화면에서는 구분이 사라진다. | [app-render-evidence.js:336](web/operator-gui/app-render-evidence.js:336), [app-format.js:506](web/operator-gui/app-format.js:506), [risk_scoring.py:160](src/rights_filter/analysis/risk_scoring.py:160) |
|
||||
| **F3. 보류가 작업 목록에서 사실상 완료처럼 빠진다.** 다음 이동은 미심사만 찾고, 백로그도 미심사만 센다. | 보류 필터는 있지만 담당자·다음 확인일·보류 사유별 후속 작업이 없다. 검색 복구나 자료 보완 후 돌아올 건을 운영자가 별도로 기억해야 한다. 누락 위험은 **추정**이다. | [app-keyboard-batch.js:67](web/operator-gui/app-keyboard-batch.js:67), [store_workflow.py:220](src/rights_filter/server/store_workflow.py:220), [index.html:182](web/operator-gui/index.html:182) |
|
||||
| **F4. 판정 변경은 가능하지만, 변경을 완결하는 기능이 부족하다.** 승인으로 바꿔도 이전 주의 후보를 정리하지 않고 최신 스냅샷을 덮어쓴다. | 오조작이나 소명 후 승인 변경 시 기준 DB까지 사람이 찾아 정리해야 한다. 특히 **반려→메모 없는 승인**에서 이전 반려 메모가 조회되는 동작을 재현했다. 지원자용 내보내기도 이 메모를 사용한다. | [sqlite_store.py:790](src/rights_filter/server/sqlite_store.py:790), [store_workflow.py:328](src/rights_filter/server/store_workflow.py:328), [store_workflow.py:380](src/rights_filter/server/store_workflow.py:380) |
|
||||
| **F5. 일괄 재분석의 대상 선정·복구가 수작업이다.** 브라우저가 선택 건을 순차 호출하며, 한 요청이 실패하면 반복을 중단한다. | “어제 한도 때문에 빠진 네이버만”, “기준 변경에 영향받은 건만” 처리하기 어렵다. 실패 후 남은 대상도 다시 골라야 한다. 장당 최대 5콜이면 문서상의 네이버 한도 100은 20장에 소진될 수 있어, 50~100건 운영에서 반복될 가능성이 높다. | [app-submissions.js:9](web/operator-gui/app-submissions.js:9), [store_operations.py:295](src/rights_filter/server/store_operations.py:295), [calibration-corpus.md:36](docs/operations/calibration-corpus.md:36) |
|
||||
| **F6. 폴더 투입에서 서로 다른 제출이 같은 건으로 합쳐질 수 있다.** 제출 ID가 파일명 stem이다. | `지원자A/photo.jpg`, `지원자B/photo.png` 같은 입력을 내용 중복과 무관하게 충돌시킨다. 일부 건이 심사되지 않은 채 “다 처리했다”고 생각할 수 있다. 흔한 파일명에서의 발생 빈도는 **추정**, 충돌 한계 자체는 코드에 명시되어 있다. | [image_store.py:93](src/rights_filter/server/image_store.py:93), [calibration-corpus.md:63](docs/operations/calibration-corpus.md:63) |
|
||||
|
||||
**2. 추가할 가치가 명확한 기능**
|
||||
|
||||
중복 그룹·선례 승계, 일괄 판정, 선택 재분석, 판정 CSV는 이미 있습니다. 아래는 그 기능들이 아직 해결하지 못하는 부분입니다. 크기는 기존 구조를 활용하는 기준으로 S=국소 변경, M=화면·저장·워크플로 연결, L=여러 수명주기 또는 외부 시스템 연동입니다.
|
||||
|
||||
| 필요한 기능 | 왜 유용한가 / 없으면 생기는 일 | 크기 | 근거 |
|
||||
|---|---|---|---|
|
||||
| **보류 사유·담당자·기한·재개 조건을 가진 후속 심사함** | 검색 장애, 라이선스 확인, 지원자 자료 대기를 구분한다. 지금은 모두 보류로 묶여 미심사 백로그 밖에서 정체된다. | M | F1·F3. [review-guide.md:44](docs/operations/review-guide.md:44) |
|
||||
| **판정 취소·재개·정정 이력과 파생 기준의 동시 정리** | 실수한 판정 복구와 소명 처리를 한 작업으로 끝낸다. 없으면 현재 승인과 과거 반려 근거가 공존한다. 판정별 메모·증거·스냅샷을 보존해야 한다. | M | F4. [sqlite_store.py:776](src/rights_filter/server/sqlite_store.py:776) |
|
||||
| **조건별 재분석 작업 목록과 중단 후 재개** | 실패 제공자·미수행 사유·분석일·기준 변경으로 대상을 고르고 필요한 단계만 수행한다. 없으면 정상 분석도 반복하고 실패분을 재선택한다. | M | F5. [store_operations.py:298](src/rights_filter/server/store_operations.py:298) |
|
||||
| **권리 증빙과 적용 범위 기록** | 라이선스 문서, 허용 제출자·용도·기간, 초상 동의 확인을 케이스 및 클리어 기준에 연결한다. 없으면 “이 사진이 승인된 적 있음”과 “이번 사용도 허용됨”을 구분하기 어렵다. | M | 클리어 등록은 지문·메모·원 제출 중심이다. [store_operations.py:236](src/rights_filter/server/store_operations.py:236) |
|
||||
| **선례 승계 전 적용 조건 비교** | 같은 이미지라도 신청자·용도·계약 상태가 다르면 재검토하도록 한다. 현재 승계 가능 여부는 선례 판정의 일치만 본다. 권한이 다른 재제출에 승인 선례가 전파될 가능성은 **추정**이다. | M | [app-selectors.js:319](web/operator-gui/app-selectors.js:319), [app-navigation.js:455](web/operator-gui/app-navigation.js:455) |
|
||||
| **투입 전 대사 화면과 안정적인 제출 ID** | 발견 파일 수·신규 건수·내용 중복·ID 충돌·지원하지 않는 파일을 따로 보여준다. 없으면 파일 정리 실수가 심사 누락으로 바뀐다. | M | F6. [image_store.py:105](src/rights_filter/server/image_store.py:105) |
|
||||
| **판정 시점 기준의 케이스 리포트** | 당시 점수·사용 증거·메모·판정자·버전을 묶어 재현한다. 현재 내부 CSV는 현재 점수와 현재 사용 표시를 읽으므로 나중에 다시 내보내면 설명이 달라질 수 있다. | M | [store_workflow.py:339](src/rights_filter/server/store_workflow.py:339), [sqlite_store.py:802](src/rights_filter/server/sqlite_store.py:802) |
|
||||
| **지원자 통지 인계·수신 확인 상태** | 폐쇄망에서는 우선 승인된 파일 교환 방식으로 인계 ID·수신 여부·정정 통지를 관리할 수 있다. 현재 ‘승인 대기/반려 예정’과 CSV만으로는 실제 전달 완료 여부를 알 수 없다. 중복·누락 통지는 **추정**이다. | M, 직접 연동 L | [sqlite_store.py:794](src/rights_filter/server/sqlite_store.py:794), [store_workflow.py:267](src/rights_filter/server/store_workflow.py:267) |
|
||||
|
||||
검색 캐시는 “전혀 없음”으로 판정하지 않습니다. 현재 **케이스별 쿼리 중복 실행 방지**가 있습니다. 보완할 것은 유효기간·강제 갱신·다른 중복 제출 간 재사용입니다. 성공했던 오래된 쿼리는 계속 생략되므로 ‘재분석’과 ‘최신 검색’이 다를 수 있습니다. 규모 M입니다. [store_enrichment.py:711](src/rights_filter/server/store_enrichment.py:711), [store_serialization.py:647](src/rights_filter/server/store_serialization.py:647)
|
||||
|
||||
**3. 점수·밴드가 판단을 오도하는 구체적 시나리오**
|
||||
|
||||
아래 점수는 각각 **표에 적힌 증거만 있고, 라벨 신뢰도는 1.0**인 합성 입력으로 실행 확인했습니다. 라이선스 유무와 이용 상황은 시나리오 가정입니다.
|
||||
|
||||
| 시나리오 | 증거 조합 → 실제 점수 | 잘못된 우선순위 또는 해석 |
|
||||
|---|---|---|
|
||||
| **권리 확인된 인물 사진이 먼저 올라온다.** | 신뢰 등록되지 않은 사이트의 완전일치 40 + 식별 가능 인물 30 + 라벨 10 → **80/high** | 해당 용도의 라이선스·동의가 확인되었다고 가정해도 점수에 반영되지 않는다. 다음 행보다 먼저 심사한다. |
|
||||
| **무단 사용된 비인물 작품이 뒤로 밀린다.** | 등록 DB에 없는 그림의 완전일치 40 + 라벨 10 → **50/medium** | 사용 허락이 없다고 가정한 명확한 사본도 인물이 없어서 앞의 허가된 사진보다 낮다. ‘권리 확인 필요성’과 ‘얼굴 존재’가 섞인다. |
|
||||
| **검색 장애 보류가 강한 위험 선례가 된다.** | 장애로 보류되어 만들어진 주의 후보와 유사도 1.0 → **80/high** | 새 권리 증거가 전혀 없어도 이전의 확인 불가 상태만으로 high다. |
|
||||
| **클리어 기준이 있어도 고위험으로 남는다.** | 클리어 일치 0 + 외부 완전일치 40 + 인물 30 + 라벨 10 → **80/high** | 동일 용도로 유효하게 클리어된 자산이라고 가정해도 가점이 없을 뿐 기존 위험 점수는 그대로다. 운영자는 ‘클리어 이력’과 high를 다시 해석해야 한다. |
|
||||
| **폐쇄망에서 미검색이 저위험처럼 보인다.** | `EXTERNAL_SKIPPED`, 사유 `disabled`, 다른 신호 없음 → **0/low** | 이 설정은 의도된 예외지만, 검색을 하지 않은 사진이 검색 완료 후 증거가 없는 사진과 같은 low에 들어간다. ‘low=확인 완료’로 읽으면 위험하다. |
|
||||
| **계약처 도메인의 모든 이미지가 같은 취급을 받는다.** | 유일한 완전일치 출처가 신뢰 등록 호스트 → **0/low** | 계약이 일부 자산에만 적용되거나 만료되었다고 가정하면, 해당 사진의 사용 권한은 미확인인데 웹 증거가 제외된다. |
|
||||
|
||||
배점·클리어 처리 근거: [risk_scoring.py:49](src/rights_filter/analysis/risk_scoring.py:49), [risk_scoring.py:165](src/rights_filter/analysis/risk_scoring.py:165). 미수행 예외: [risk_scoring.py:278](src/rights_filter/analysis/risk_scoring.py:278). 신뢰 호스트 제외: [risk_scoring.py:125](src/rights_filter/analysis/risk_scoring.py:125), [risk_scoring.py:218](src/rights_filter/analysis/risk_scoring.py:218).
|
||||
|
||||
여기에 **검증되지 않은 정확성 인상**이 더해집니다. 통계는 판정 당시가 아닌 현재 밴드를 사용하고, 분모가 0이면 비율 0.0을 반환합니다. 화면도 숫자를 유지하고 색만 중립으로 바꿉니다. 따라서 ‘미탐 0%’는 실제 성능 근거가 아닐 수 있습니다. [store_workflow.py:214](src/rights_filter/server/store_workflow.py:214), [store_workflow.py:398](src/rights_filter/server/store_workflow.py:398), [app-stats.js:75](web/operator-gui/app-stats.js:75)
|
||||
|
||||
**4. 기준 DB의 오염·노후화 경로와 빠진 절차**
|
||||
|
||||
| 경로 | 빠진 운영 절차 |
|
||||
|---|---|
|
||||
| **주의 후보의 자기 강화.** 검색 미완료 보류와 실제 반려가 같은 유형으로 쌓이고 같은 80점 축에 들어간다. F1의 확인된 동작이다. | 보류 사유를 구조화하고, ‘검색 대기’는 권리 위험 기준에서 분리해야 한다. 후보의 확정 승격에는 별도의 확인 근거가 필요하다. |
|
||||
| **정정 후 반대 기준이 공존.** 반려→승인은 기존 주의 후보를 정리하지 않고, 클리어는 별도 ID로 등록된다. 클리어·주의 후보가 동시에 활성일 수 있다. | 원 판정 변경 시 파생 기준의 유지·철회 여부를 함께 결정하고, 동일 이미지에 반대 기준이 있으면 조정 대상으로 올려야 한다. [store_operations.py:155](src/rights_filter/server/store_operations.py:155), [store_operations.py:229](src/rights_filter/server/store_operations.py:229) |
|
||||
| **제외한 후보의 재생성·확정 후보의 상태 후퇴.** 같은 원 제출을 다시 보류/반려하면 기존 내용을 읽은 뒤 `active=True`, `entryStatus=watchlist`로 덮어쓴다. | 재판정 때 기존 제외·확정 결정을 존중하고, 이를 바꾸려면 변경 사유를 남겨야 한다. [store_operations.py:155](src/rights_filter/server/store_operations.py:155) |
|
||||
| **클리어·신뢰 출처의 만료와 범위 상실.** 현재 클리어는 지문 중심이고 신뢰 출처는 활성 도메인 목록이다. 하위 도메인도 포함한다. | 책임자·증빙·허용 범위·만료일·정기 재확인일이 필요하다. 계약 갱신·종료 때 영향받는 케이스 목록을 만들어야 한다. [store_operations.py:236](src/rights_filter/server/store_operations.py:236), [store_search_candidates.py:721](src/rights_filter/server/store_search_candidates.py:721) |
|
||||
| **기준을 철회해도 기존 케이스의 증거가 남는다.** 비활성화는 기준 항목을 갱신하고, 재점수는 저장된 증거를 다시 계산한다. 기존 지문 증거에서 현재 기준의 활성 상태를 재확인하는 경로는 해당 함수에 없다. | 기준 변경의 영향 대상을 찾아 과거 증거를 무효화·갱신하고, 처리 완료 여부를 확인하는 절차가 필요하다. [store_operations.py:100](src/rights_filter/server/store_operations.py:100), [store_search_candidates.py:744](src/rights_filter/server/store_search_candidates.py:744) |
|
||||
|
||||
출처별 신뢰도 **자동 학습은 지금 우선순위가 낮습니다**. 현재 ‘미사용’이 오탐으로 저장되고, 운영자 판정도 점수를 먼저 본 상태에서 만들어집니다. 이 기록을 그대로 학습하면 기존 점수와 조작 습관을 강화할 가능성이 있습니다. 먼저 상태 의미를 바로잡고, 출처별 오탐·무관·권리 확인 결과를 분리 집계하는 편이 낫습니다. 이 순환 문제는 구현 주석에도 명시되어 있습니다. [store_workflow.py:43](src/rights_filter/server/store_workflow.py:43)
|
||||
|
||||
**5. 지금 착수할 상위 5개**
|
||||
|
||||
| 순위 | 착수할 일 | 선정 근거와 완료 기준 |
|
||||
|---|---|---|
|
||||
| **1** | **보류 사유 분리 + 주의 후보의 80점 자동 승격 차단** | 확인 불가가 강한 위험 선례로 누적되는 F1을 먼저 끊어야 한다. 검색 대기 보류는 권리 기준과 분리하고, 복구 후 재심사함으로 돌아오게 한다. **완료 기준:** 장애 보류 사진의 재제출이 그 보류만으로 high가 되지 않는다. |
|
||||
| **2** | **판정 정정의 일관성 확보** | F4는 실제 내보내기 내용까지 모순시킨다. 최신 판정 메모 조회를 우선 수정하고, 판정별 기록 보존·재개·파생 기준 정리를 연결한다. **완료 기준:** 반려→승인 후 화면·기준 DB·내보내기가 같은 결론과 사유를 가리킨다. |
|
||||
| **3** | **투입 충돌 감지와 건수 대사** | F6은 큐에 제대로 나타나지 않아 운영자가 심사로 발견하기 어렵다. 먼저 충돌을 명시적으로 차단·보고하고, 안정적 ID로 확장한다. **완료 기준:** 동일 파일명 두 장이 서로 다른 제출로 보존되거나 명확한 오류 목록에 나온다. |
|
||||
| **4** | **증거 인용 여부와 무관·오탐 상태 분리** | F2는 매일 반복되는 조작이며 점수와 향후 평가 데이터까지 바꾼다. ‘판정에 인용하지 않음’은 점수를 유지하고, 무관·오탐만 별도 사유로 제외한다. **완료 기준:** 대표 증거 하나를 선택하는 작업이 다른 유효 증거의 점수를 지우지 않는다. |
|
||||
| **5** | **검색 완결성 표시 + 실제 판정 기반 캘리브레이션** | low가 미검색과 섞이고, 현재 코퍼스는 medium/low를 검증할 수 없다. 검색 상태를 밴드와 별도로 명시하고 분모 0은 ‘측정 불가’로 표시한다. 자사 원본·라이선스 자산·비인물 작품을 보강해 판정 시점 스냅샷으로 평가한다. **완료 기준:** 배포 설정별 검색 공백과 밴드별 실제 판정 결과를 구분해 볼 수 있다. [calibration-corpus.md:19](docs/operations/calibration-corpus.md:19), [calibration-corpus.md:101](docs/operations/calibration-corpus.md:101) |
|
||||
Loading…
Reference in a new issue