v3.8.2 — 전체 시스템 적대적 점검 (28개 결함 수정)
Summary
/goal "전체 시스템 점검 → 버그 수정 → 추가 발견 없을 때까지 반복" 으로 v3.8.1 코드베이스
전체(src 28모듈 + hooks + scripts)를 5라운드 적대적 워크플로(find → adversarial verify
→ runtime 재현)와 프로덕션 debug.log(30k줄) 텔레메트리 분석으로 점검했다. 747 테스트가
이미 그린이던 성숙한 코드에서 28개 실재 결함(데이터 유실 HIGH 1 포함)을 찾아 수정하고
각 수정에 회귀테스트를 붙였다(+29). 라운드별 발견 추세 11 → 13 → 2 → 3(HIGH 1) → 0 으로
수렴 확인. false positive 3건은 런타임으로 기각(예: raw sqlite3.connect 의 busy_timeout 은
Python 기본 5000ms 라 무해), 5건은 근거와 함께 defer.
테스트: 747 passed + 25 subtests → 776 passed + 41 subtests (회귀 0).
Fixed — HIGH (데이터 유실)
_collect_md_files중복 경로 미dedup → dedup-merge 자기삭제 영구 유실 (memory_indexer.py):
sources.json 에 DEFAULT 자동발견 슬롯을 add 하면 union 에 같은 dir 가 두 번 들어가 같은
.md가 두 번 방출 →dedup_cli._scan이 단일 파일을 자기 자신과 'name-dup' 으로 보고 →
cmd_merge가 canonical 을 overwrite 후 삭제(ok:True보고). resolved-path dedup 으로 단일
방출 보장(end-to-end 재현 확인).
Fixed — MED
- FTS5 예약어 누수 (
search.py/memory_search.py):AND/OR/NOT/NEAR포함 쿼리가
fts5: syntax error로 FTS 0건이 되던 회귀(운영 15건+). 토큰을 따옴표 phrase 로 감싸 리터럴
prefix 검색 강제. - 비-문자열 frontmatter 가 인덱서 run 전체 중단 (
memory_indexer.py):description: 2026
같은 YAML 비-str 값에.strip()→ AttributeError 가 per-file 가드 없는 루프를 뚫고 인덱싱
전체를 중단.str()강제. - 세션 인덱서: 임베드 장애 중 재인덱싱 시
sessions_vec영구 stale (indexer.py): 기존
세션 본문 변경 + 임베드 실패가 겹치면 FTS 는 새 본문, vec 는 옛 임베딩으로 고착(mtime skip +
backfillIS NULL둘 다 못 잡음). 실패 시 vec 행 삭제 → backfill 재충전. - extractor
finish_reason=length절단 → 빈 결과 영구 negative 캐시 (memory_extractor.py):
긴 응답이 max_tokens 에서 잘리면 non-empty 절단 문자열이 parse 0건 → 호출 성공 오인 → 고가치
세션 영구 추출 스킵. 절단을 호출 실패로 취급. - query_intent: 일시 장애를 7일 negative 센티넬로 캐시 (
query_intent.py): timeout/서버다운
(None)을 'Gemma 가 other 라 응답' 과 합쳐 캐시 → transient 장애가 해당 prompt 분류를 7일 배제.
호출 실패는 캐시하지 않고 재시도. - recall_cli "항상 exit 0" 계약 위반 (
recall_cli.py): numpy 없는 인터프리터(배포 /recall
컨텍스트)에서 lazy import ImportError 전파 → 비-0 종료. source 별 try/except 로 빈 결과 흡수. - contradiction_review 블록리스트 정규식이 공백 항목 미탐 (
contradiction_review_cli.py):
- some old memory같은 공백 포함 YAML 블록리스트를 못 잡아 mutation 거부 가드 우회 → 중복
inline 키로 YAML 손상.\S[^\r\n]*로 항목 전체 매칭. - memory_review 비원자 promote → 고아가 재시도 영구 차단 (
memory_review_cli.py): target
기록 후 INDEX append/src.unlink실패 시 target 이 남아 'target exists' 로 재시도 차단. 후속
실패 시 target+INDEX 대칭 롤백. - dedup_cli frontmatter raw 보간 (
dedup_cli.py): 멀티라인/비-str name·description·type 이
raw 보간되면 frontmatter 손상._serialize_fm_value단일라인 정규화.
Fixed — LOW (견고성·일관성)
- 모든 Gemma 호출자 5곳(search/memory_extractor/contradiction_detector/alias_generator/
query_intent) 비-문자열 content 가드 +UnicodeDecodeError흡수 — content-block 리스트
응답에.strip()/.splitlines()AttributeError, max_tokens 경계 멀티바이트 절단 시
UnicodeDecodeError 가 회수/추출 루프를 떨구던 동일 안티패턴을 전 호출자에 통일. - self_eval
turns_cacheimport 3곳 — src 가 sys.path[0] 가 아닌 컨텍스트에서 'No module
named turns_cache' 로 캐시 silent 사망(운영 9건/5-31). late-import 패턴 통일. reverify비-dict sidecar →.getAttributeError 로 scan 영구 skip. dict 가드(자가복구).memory_indexer._acquire_lock가 BlockingIOError 외 OSError 시 fd 누수. 대칭 처리.session_memory.cache_set결정적 tmp 이름 → 병렬 SessionStart interleave 손상. PID-tmp.memory_extractor._iter_balanced_arrays선행 불균형[에서 조기 종료로 유효 배열 유실.gemma_rerankLLM 중복 인덱스 미dedup → 동일 세션 중복 회수.backfill_cli--limit 0/음수 인자,provenance_backfill미존재 dir 등 CLI 입력 검증.alias_generatormeta-fail 진단 로그(원인 파일 추적 가능),memory_reviewprocedural 인덱스
링크 경로,deploy_drift_check경고 방향 중립화.
Method — 적대적 수렴 점검
- 5라운드 워크플로: finder 후보 → 독립 verifier 가 적대적 반증(코드 재확인 + 호출 도달성 +
테스트 커버 + runtime 재현). 라운드 간 수정 코드를 재투입해 fix-the-fix 도 검출(round4 가
round3 promote-rollback 비대칭 회귀 + dedup type 누락을 잡음). - 프로덕션 debug.log 텔레메트리로 이론이 아닌 실재 실패 우선 추적(FTS5 syntax error, import
실패, json parse fail, alias_sync failed). - 수렴 기준: 신규 confirmed 0 라운드. R5 = 0 → dry.
Deferred (근거와 함께 미수정 — 유지보수자 판단 영역)
query_intent'전에'시간접속사 오탐 → cosine 게이트 완화 오적용 (튜닝 — live hit rate
영향, query 분포 데이터 필요).alias_generator동시 generate lost-update (CLAUDE.md 가 유사 race 를 수용된 한계로 명시).self_evalrecall_utilization 시간 윈도우가 세션 경계 무시 (측정 정확도 — 침습적 + NEXT-37
baseline 영향, 재baseline 은 유지보수자 결정).- drift 백스톱이 '신규 미배포 모듈' 미탐 (구조적 — install.sh 하드코딩 배열).
- install.sh drift-hook settings 폐기 분기 (노출 ≈ 0).