Skip to content

v3.2.10 — /recall 결함 sweep (NEXT-36)

Choose a tag to compare

@etinpres etinpres released this 26 May 13:06
· 121 commits to master since this release

Summary

/recall 스킬 (memory_search.py + search.py + recall_cli.py) 에 대한 systematic-debugging 4-phase + codex 독립 검증 sweep. 2 fix + 4 false alarm confirm + 7 회귀 가드 + 1 cosmetic 정정. 2 연속 라운드 0 critical/medium 으로 수렴.

Critical Fix

memory_search._vec_top_k — mat ↔ meta 인덱스 미스매치

  • 증상: memories_vec 에 invalid embedding row (빈 bytes, dim mismatch) 1건만 있어도:
    • results = [(meta[i][0], ...) for ..., i in enumerate(idx_sorted)]IndexError 또는 잘못된 path 반환
    • raw_map 의 cosine 값을 잘못된 path 에 매핑 (cross-contamination, p2 cosine 0.775 → 0.0 게이트 차단, p3 cosine 0.884 → 0.775)
  • root cause: mat[i] = arr (row 인덱스) 와 meta.append(...) (valid 만) 의 인덱스 정합 깨짐. 같은 모듈의 search.vec_candidatesvalid 카운터 + mat[:valid] 안전 패턴이었으나 한 함수만 fix 누락
  • fix: valid 카운터 + mat[:valid] 패턴으로 교체. 두 모듈 안전 패턴 통일
  • silent 이유: 운영 DB invalid row 0건. 인덱서가 partial write 1회만 일으키면 recall_memory 의 outer except Exception 가드가 잡아 빈 결과 반환 → 사용자는 검색 0건으로만 보고 결함 모름

Medium Fix

_resolve_wikilink — ORDER BY path 추가

  • 증상: 다중 후보 시 SQLite 반환 순서 미보장 → 같은 wikilink 가 호출마다 다른 메모리로 resolve
  • fix: path LIKE ? 쿼리에 ORDER BY path 추가 (lexicographic 안정 결정성)

False Alarm 분류 (의도된 동작 confirm)

항목 분류
M1: 무의미 query ("1234") 5건 통과 /recall 명시 호출의 user-driven sift 정책 (score_threshold=0.0, raw_cosine_min=0.32) 일치
M3: gemma_rerank fallback 정렬 RRF rank 기준 첫 K 가 합리적, 게이트 후 절대-상대 분리 정책
L1: fts_escape 두 모듈 중복 8/8 sample 동등성 confirm. DRY 통합 비용 > 효용. skew 회귀 가드만 추가
L2: recall_cli.py top_k 옵션 없음 spec(recall.md) 의도, 명시 호출은 user-driven sift

회귀 가드 7건 (tests/test_memory_search.py)

  • TestVecTopKInvalidRowRegression × 4 (empty / bad-dim / all-invalid / all-valid backwards compat)
  • TestFtsEscapeParity × 1 (search.fts_escape vs memory_search._fts_escape 12 sample 동등성)
  • TestResolveWikilinkDeterminism × 2 (lex order + 20회 반복 안정성)

검증

  • pytest 422 → 429 passed (회귀 0)
  • 운영 본 ~/.claude/scripts/mindvault/memory_search.py md5 동기화
  • 실 query verify — 한국어/영문 query + sessions search + Gemma summary 모두 정상
  • Round 2 자체 sweep → 0 critical/medium
  • codex:codex-rescue 독립 검증 → 0 critical/medium (1 cosmetic 주석 정정만)
  • Round 3 자체 sweep (alias race / raw_cosine_map 사용 / import 순환) → 0 new
  • 2 연속 라운드 0건 close 수렴 기준 (feedback-systematic-debugging-code-review) 충족

Files changed

  • src/memory_search.py (+19/-4)
  • tests/test_memory_search.py (+170)

누적

결함 99건.