fix(p10-1a-1): apply code_lang + repo filters in lexical SQL and filter_chunks (dogfood) #144
Reference in New Issue
Block a user
Delete Branch "fix/p10-1a-1-code-lang-repo-filter-sql"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
요약
--code-lang LANG/--repo NAMECLI filter 가 lexical + vector retriever SQL 에서 무시되어 모든 doc (markdown / pdf / image 포함) 이 결과에 섞여 반환되던 production bug. p10-1A-1 (PR #139) 머지부터 잠복 — 1A-2 / 1B 회차에서도 발견 못 함 (회귀 테스트는 SearchFilters 필드 유무만 검증, SQL 적용은 미검증). p10-1B dogfooding (httpx + zod + lodash clone) 으로 표면화.진단
--code-lang/--repoparse 정상,SearchFilters { code_lang: Vec<String>, repo: Vec<String> }에 set 됨.SearchFilters(kebab-core): 두 필드 1A-1 추가됨.kebab-search/src/lexical.rs:filters.code_lang/filters.repo를 SQL WHERE 절에 반영 안 함.kebab-store-sqlite/src/filters.rs(vector 가 post-filter 로 사용): 동일 누락.Fix
두 retriever 의 SQL 에 동일 IN-list filter 추가:
documents.metadata_json의 JSON path 는 Task 9 의code_lang_breakdown쿼리와 동일 source-of-truth 사용. media filter (1A-1 도 추가했던) 와 동일 패턴.회귀 테스트
4건 추가 (모두 신규):
kebab-search/tests/lexical.rs::lexical_filter_by_code_langkebab-search/tests/lexical.rs::lexical_filter_by_repokebab-store-sqlite::filters::tests::filter_chunks_code_lang_keeps_matching_langkebab-store-sqlite::filters::tests::filter_chunks_repo_keeps_matching_repo검증
per-crate 테스트 + dogfooding 재실행:
Dogfood (httpx + zod + lodash clone):
search 'AsyncClient' --code-lang python→Citation::Code { lang: "python", symbol: "httpx.tests.client.test_auth.test_auth_invalid_type" },repo: "httpx",code_lang: "python". (이전: markdown hit 만 반환.)search 'ZodObject' --code-lang typescript→symbol: "zod/packages/zod/src/v4/classic/schemas.ZodObject",repo: "zod". design §3.4 path 형식 그대로.search '...' --repo zod→ repo filter 도 정확히 동작.범위
crates/kebab-search/src/lexical.rs: SQL block 2개 추가crates/kebab-store-sqlite/src/filters.rs: SQL block 2개 추가 + 1 test helpercrates/kebab-search/tests/lexical.rs: insert helper refactor + 2 새 테스트버전
bug fix only →
0.8.0유지 (patch bump 트리거 아님; user-visible surface 변경 없음 — 이미 advertised flag 의 실제 동작 복원).🤖 Generated with Claude Code
회차 1 — 로직 정확, 테스트 4건 전부 통과, 신규 dep 없음. APPROVE.
SQL 수정이 두 곳(lexical.rs + filters.rs) 모두 올바르게 적용되었습니다. json_extract 경로('
.code_lang', '.repo')가 1A-2 PR #140의 code_lang_breakdown 쿼리와 정확히 일치하여 스키마 드리프트 없음. IN-list placeholder 방식이 media 필터 패턴과 동일하게 구현되어 일관성 있습니다. 빈 Vec → 필터 미적용(all-pass) 컨벤션도 올바르게 유지.NULL 처리도 올바릅니다: metadata_json에 code_lang 키가 없는 구형 문서는 json_extract → NULL, NULL IN (...) → NULL(false)로 평가되어 코드 필터 적용 시 제외됨 — '--code-lang python' 요청에서 마크다운 문서가 섞이지 않아야 한다는 사양과 일치.
테스트 헬퍼 insert_doc_full_with_metadata(lexical) + seed_committed_with_metadata(filters)가 각각 독립적인 TempDir을 사용하여 테스트 간 상태 공유 없음. 회귀 위험 없이 머지 가능합니다.
칭찬:
media필터 블록 직후,ingested_after직전에 배치한 위치 선택이 기존 컨벤션과 일관성 있습니다. 두 파일(lexical.rs + filters.rs) 모두 동일 순서를 유지해 향후 필터 추가 시 기준점이 명확합니다.칭찬:
insert_doc_full→insert_doc_full_with_metadata델리게이트 분리 패턴이 깔끔합니다. 기존 호출부를 건드리지 않고 메타데이터 파라미터를 추가한 후 기존 함수가"{}"로 위임하는 구조 — 하위 호환 확장의 좋은 예.insert_code_doc헬퍼:MediaType::Markdown을 하드코딩하고 있는데, 코드 문서를 삽입하는 헬퍼치고는MediaType::Code(또는Codevariant가 있다면) 쪽이 더 자기 서술적입니다. 기능상 버그는 아니지만, 이후 media-type 별 필터 테스트가 붙을 경우 헷갈릴 수 있어 nit으로 남깁니다.칭찬:
seed_committed_with_metadata가 asset → document → chunk → embedding_record → commit 전 단계를 모두 밟아 실제filter_chunks입력 조건을 재현하는 방식이 탄탄합니다. 이후ingested_after,media등 다른 필터 테스트를 추가할 때도 이 헬퍼를 재사용할 수 있는 범용성이 좋습니다.