"이 도구가 실제 업무에 도움이 되는가"를 6축으로 조사하고 축마다 결론을 반증시켰다(docs/reviews/2026-08-08-utility-assessment.md). 결론은 "검색·기록 노동은 줄여주나 심사 건수는 못 줄인다"이고, 그 과정에서 실행으로 확정된 P0 결함 4건을 여기서 고친다. 판별력 붕괴(P1)는 별도 작업이다. 폴더 정리가 판정 기록을 지웠다 (sqlite_store.py) _prune_missing_submission_files 가 원본 파일이 없는 submission 행을 판정 여부와 무관하게 delete 했고, foreign_keys=on 이라 evidence 가 cascade 로 함께 사라졌다. 심사 끝난 이미지를 아카이브로 옮기는 평범한 운영 행위가 승인/반려를 DB 와 내보내기 양쪽에서 지운다. 실증: rejected 판정 후 export 1행 -> 파일 제거 -> submissions 0행 / evidence 0행 / export 0행. 판정된 케이스는 파일이 없어도 보존하고 assetMissing 마커를 남긴다. 마커가 필요한 이유는 이 스윕이 매 리로드마다 돌기 때문이다 — 표시 없이 보존만 하면 같은 감사 이벤트가 리로드마다 쌓여 500행 캡을 먹는다. 비상 차단 스위치가 아무것도 막지 않았다 (store_enrichment.py) emergency_disable_external_providers 는 DB 의 enabled/operatorDisabled 만 쓰는데 자동 보강 경로가 그 플래그를 아예 읽지 않았다. 게이트가 걸린 곳은 수동 검색뿐이라, 버튼을 눌러도 폴더 리로드·업로드·rerun-enrichment 가 그대로 Naver/Google 로 나갔다. 스텁 어댑터 대조실험에서 CONTROL 5회 / 차단 후 5회로 완전히 동일했다. _external_calls_blocked(provider_id) 를 신설해 자동 외부 호출 5개 경로에 배선했다: auto naver, auto CSE, rerun Vision, 얼굴 크롭 웹탐지, 시드 배치 (후자는 ExternalApiPolicy(disabled=True) 로 전환). enabled 가 아니라 operatorDisabled 를 본다. enabled 는 연결성/헬스에도 반응하므로 운영자가 멈추라고 한 적 없는 트래픽까지 죽인다. 얼굴 크롭은 생체 파생물을 전송하므로 상위 게이트에 의존하지 않고 독립 게이트를 건다. 생체 크롭이 보존기간을 넘겨 살아남았다 (store_backup.py) 스냅샷이 face-crops 를 통째로 담는데 프루닝은 나이가 아니라 개수 10개 기준이라, 90일에 파기됐어야 할 크롭이 암호화 없는 zip 안에 남았다. 복구는 더 나빴다 — copyfileobj 로 새로 쓰므로 mtime 이 리셋되고, purge 가 mtime 을 보므로 파기 대상이 복구 직후부터 다시 90일을 살았다. 스냅샷에서 제외하고, 복구 시에도 레거시 아카이브의 크롭을 건너뛴다. 크롭은 원본에서 재분석으로 재생성되므로 손실 비용이 없다. 오프라인 설치 문서가 계약 위반 모델을 지목했다 (offline-install.md) qwen2.5:0.5b-instruct 반입을 지시했는데, 같은 리포가 이 모델을 55.7초 + 프롬프트 형식 예시 반향(출력 계약 위반)으로 기록해 두고 기본값을 7b 로 고정해 뒀다. 문서대로 반입하면 타깃에서 요약이 조용히 죽는다. 모델명을 정정하고, 반입물 목록에 없던 ollama 바이너리와 GPU 전제를 추가했으며, "env 를 비우면 LLM 없이 돈다"는 서술을 실측으로 정정했다 — 실제로는 127.0.0.1:11434 로 폴백해 provider 가 enabled=True 로 보고된다. 회귀 테스트 3건 추가. pytest 565 passed(착수 전 562), 린트 클린.
14 lines
6.9 KiB
Markdown
14 lines
6.9 KiB
Markdown
# Project INDEX
|
|
|
|
- 2026-08-08 · 기능 실효성 평가(6축 조사 + 축별 적대적 반증, 에이전트 12) 후 P0 4종 수정 — 결론은 **"검색·기록 노동은 줄여주나 심사 건수는 못 줄인다"**(신호조합 224개 전수 시 high 77.7%·low 3.6%, 지배 동인은 match 스택이 아니라 **web entity 누적** — 이미지 매칭 0건이어도 entity 3개면 100/high, 웹에 없는 오리지널도 66/medium). 실수정: **폴더 정리가 판정 기록을 지우던 경로 차단**(판정 완료 가드 + `assetMissing` 1회 마킹; 실증으로 export 1행→0행 확인됨), **비상 차단 스위치 실배선**(`_external_calls_blocked` 신설 → 자동 Naver/CSE/Vision/얼굴크롭 5개 경로; 이전엔 눌러도 외부 호출 5회 동일), **생체 크롭의 보존기간 초과 생존 차단**(스냅샷 제외 + 레거시 아카이브 복구 스킵 — 복구가 mtime을 리셋해 90일을 재시작시켰음), **오프라인 설치 문서의 계약 위반 모델 정정**(0.5b→7b + ollama 바이너리·GPU 전제·거짓 disable 서술). DB 6건은 첫 커밋보다 2주 앞선 구빌드 스냅샷이라 검증 코퍼스가 아님을 확인. **pytest 565 passed**(착수 전 562), 린트 클린 → [docs/reviews/2026-08-08-utility-assessment.md](reviews/2026-08-08-utility-assessment.md)
|
|
|
|
- 2026-08-08 · 프로젝트 분석 후 인프라·구조·보안 정비 — **원격 백업 복구**(20커밋이 로컬에만 있었음: `main` 2 + 작업브랜치 18 → Forgejo push), **단일 verify 게이트 신설**(`verify.ps1` + `pytest.ini` + `ruff.toml`, ruff 0.12.0 dev 핀; 린트 18건 정리), **`app.js` 5,428줄 → `app-*.js` 15개 분할**(순수 라인범위 추출로 바이트 단위 라운드트립 검증, 로드 순서를 정적 테스트로 고정), **보안 2종 실수정**(SSRF DNS-rebinding TOCTOU — 단일 DNS 해석 후 그 답변으로만 연결하는 `_guarded_create_connection`; 실패 인증 스로틀 — 자격증명 제시 실패만 10회/60초, `429`+`Retry-After`), 7/11 체크리스트 재확인(6건은 이미 수정돼 있던 낡은 항목, Batch 8 은 Batch 6 과 중복이라 정리), `CLAUDE.md`·`docs/PROJECT_MAP.md` 신설. E2E 플레이크(업로드 대기 10초 → `UPLOAD_ANALYSIS_TIMEOUT_MS` 30초) 해소. **pytest 562 passed**(착수 전 533/1 failed), 린트 클린. 실렌더 확인: 큐·케이스 심사 정상 렌더, 스크립트 15개 전부 200, 새로고침 후 콘솔 메시지 0
|
|
|
|
- 2026-07-24 · 멀티에이전트 프로젝트 점검(에이전트 109, 적대적 검증 포함) — pytest 377/379, 런타임 스모크 9/9 통과, 신규 CONFIRMED 43건(HIGH 7) + 7/11 체크리스트 중 3건 실수정 확인 + 기능 제안 상위 5 선정 → [docs/reviews/2026-07-24-project-review.md](reviews/2026-07-24-project-review.md)
|
|
- 2026-07-26 · 운영자 콘솔 실렌더 검증 + 결함 5종 수정 (`d20e6d6`) — 서버 기동 불가(cp949에서 em-dash `UnicodeEncodeError`로 프로세스 사망, 납품 환경 치명) · 요약이 모델이 못 본 78건을 "연결 근거"로 주장(B단계가 절반만 막았음) · `grounded/droppedClaims` 미영속화 · app.js가 서버 그룹 분류를 자체 매핑으로 덮어씀 · 기본 모델이 클라이언트/배선에서 불일치(미설치 모델 지목). 실렌더 확인: 출처 표기 그룹 자체 섹션 렌더, `[E1,E2...]` 인용 2단 요약, `sourceIds` 78→10, qwen2.5:7b 6.0초. **pytest 534 passed**
|
|
- 2026-07-25 · C단계: 출처 신호 2종 (`5a9fcc0`) — EXIF/IPTC 권리 표기 추출(화이트리스트 6필드, GPS·시리얼·Make/Model 미판독) + 방송캡처 포렌식(레터박스·자막밴드·프레임크기, 독립 카테고리 2개 이상). 하나의 `EvidenceSource.PROVENANCE`·하나의 GUI 그룹으로 배관 12곳 비용 1회 지불. **둘 다 0점 라벨**(캘리브레이션 전). 실측: 실제 이미지 6장에서 캡처 오탐 0·권리메타 히트 0(정밀도 확인, 가치는 이 코퍼스에서 미입증). XMP/C2PA는 `defusedxml` 미반입으로 제외. **pytest 531 passed**
|
|
- 2026-07-25 · 실모델 프로브로 형식 예시 반향 결함 발견·차단 (`6bbaaf6`) — qwen2.5:0.5b가 프롬프트의 형식 예시를 그대로 출력하며 실제 라벨 12개를 전부 인용해 집합 포함 검사를 통과. 가짜 transport 테스트로는 불가능한 발견. 기본 모델을 실측으로 `qwen2.5:7b` 확정(0.5b 55.7s 계약위반 / 7b 8.8s 준수 / qwen3:8b 35.7s 준수)
|
|
- 2026-07-25 · B단계: LLM을 요약기에서 증거 판독기로 (`6be263a`) — 입력 화이트리스트 9필드+상위 12건 상한(`promotion_reason` 제외), `format=json` 구조화 인용 + 라벨 집합 포함 검사로 미인용 claim 폐기, 기본 모델 0.5B→3B 및 `num_ctx`/`num_predict`/`keep_alive`/`timeout` 노출, 시드 LLM 호출을 `_write_lock` 밖으로(시드당 20건 상한). 잠금 이동이 만든 provider 커버리지 회귀(요약 존재하는데 `not_run` 보고)를 나레이션 후 재계산으로 수정. **pytest 515 passed**
|
|
- 2026-07-25 · 실사용 투입 전 T0 4종 + 임베딩 정책 개정 구현 — (T0-1) `initialRiskScore`/`initialRiskBand`/`scorerVersion` 각인, (T0-2) YuNet 얼굴검출 교체 + 인물 등급(identifiable/background) 도입 및 라운드트립 보존, (T0-3) 판정 시점 피처 스냅샷(라벨 순환 차단), (T0-4) 모델·프롬프트 버전 + `latency_ms` 스탬프. Scene Embedding Policy 신설로 임베딩 금지 범위를 생체 식별로 축소(얼굴 임베딩 금지는 landmark·descriptor 추가로 강화). YuNet 가중치는 `models/`(gitignore) + `offline-install.md`에 sha256 반입 절차. **pytest 502 passed**(착수 전 463). 실측: 6장 기준 검출 378ms(YuNet) vs 654ms(Haar), 2장에서 등급 판정이 갈림
|
|
- 2026-07-25 · AI 기능 확장 브레인스토밍(에이전트 14: 5렌즈 발산 30건 → 적대적 실현가능성 검증 6건 REFUTED → 심사 3인 채점) — 1위 「LLM 예산·계측·입력 경계」 7.90(만장일치). 검증 중 실측으로 확인: 판정 라벨 0건·`operatorStatus` 292행 전부 None·밴드 high 4/medium 2/low 0(4건 100점 포화)·`_perceptual_hash`는 pHash가 아닌 8x8 평균해시. 문서의 WAL 미설정 주장은 검증 결과 오류로 정정(이미 적용됨) → [docs/brainstorms/2026-07-25-ai-capability-expansion-brainstorm.md](brainstorms/2026-07-25-ai-capability-expansion-brainstorm.md)
|
|
- 2026-07-24 · 위 점검의 전체 remediation + 신규 기능 5종 구현 — HIGH 7·MEDIUM 15·LOW 21 및 F1~F5(키보드 심사·일괄 판정/메모 프리셋·지문 중복 인덱스·판정 내보내기·백업 복구) 완료. cv2 환경 드리프트 복구(OpenCV 5.0.0 제거). **pytest 457 passed**(착수 전 377/2 failed), 실서버 스모크 및 백업 복구 왕복 검증. GUI 스펙의 "일괄 승인/반려 금지(v1)" 제약은 가드레일 조건부로 개정 이력 남기고 해제 → [docs/reviews/2026-07-24-implementation-checklist.md](reviews/2026-07-24-implementation-checklist.md)
|