리뷰에서 나온 지적 중 실제로 고칠 값이 있는 4건 반영.
1) 압축 트리거를 인메모리 카운터 -> Lance 테이블 version 으로
`upserts_since_compact: AtomicU64` 는 store 인스턴스 수명 동안만 살아
있는데, `kebab ingest-file` 과 MCP `ingest_file`/`ingest_stdin` 은 호출마다
새 App(따라서 새 store)을 연다. 한 번에 수만 건 넣는 ingest 에서만 512 에
닿고, 한 건씩 넣는 경로에서는 카운터가 매번 0 으로 되돌아가 압축이 영영
안 돌았다 — PR 이 잡겠다던 fragment 누적이 그 경로에 그대로 남는 셈.
Lance 의 `table.version()` 은 테이블에 저장돼 프로세스를 넘어 단조 증가
하므로 그걸 기준으로 바꿨다. 부수적으로 struct 에서 카운터 필드와
AtomicU64 import 가 사라졌다.
2) `--fail-under` -> `--max-drop`
관용적으로 `--fail-under 0.9` 는 "지표가 0.9 미만이면 실패" 로 읽히는데
실제 의미는 "0.9 이상 떨어지면 실패" 였다. 그대로 두면 CI 에 하한이라고
믿고 적은 값이 아무것도 안 막는다 — recall 0.95 -> 0.10 붕괴도 낙폭
0.85 < 0.9 라 통과. 새로 노출되는 표면이라 지금이 바꿀 수 있는 시점이다.
음수·nan 은 시작 시점에 거부한다(그대로 두면 게이트가 무력화됨).
3) `chrono` 직접 의존 제거
lancedb 가 `chrono::Duration` 을 이미 re-export 한다
(lancedb-0.23.1/src/table.rs:85). 앞 커밋이 Cargo.toml 에 적은
"lancedb 는 chrono 를 re-export 하지 않는다" 는 사실이 아니었다.
4) 안전성 근거 주석 정정 + 측정치 통일
`delete_unverified: true` 의 근거를 "kebab ingest 는 단일 동기 프로세스"
라고 단언했으나, 이 리포는 `kebab mcp` 를 preferred 통합 표면으로 배포하고
그 서버는 ingest 까지 노출한다. 락도 없다. 단언 대신 전제와 그 전제가
코드로 강제되지 않는다는 사실, 그리고 이 플래그 없이는 신규 색인에서
아무것도 회수되지 않는다는 trade-off 를 그대로 적었다.
압축 소요는 사본 측정치(102초) 대신 실 테이블 측정치(153초)로 통일.
`is_multiple_of` 는 MSRV(1.85) 보다 높은 1.87 안정화라 `%` 로 대체.
검증: 워크스페이스 186 결과 전부 통과 · 실패 0. `--max-drop` 3경로 실증
(통과 exit 0 / 잘못된 값 exit 2 / 회귀 exit 1). 회귀 경로에서 "측정 불가"
가드가 실제 run 쌍으로 발동하는 것도 확인.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017c9JwQq8ZkGvYjpKXMiDhF