사용자 요청 — 사용자가 누적된 ad-hoc 도그푸딩 데이터를 /build/cache/
dogfood/ 한 곳에 collection 한 후, 도그푸딩의 필요 시점을 추론해
CLAUDE.md 에 정책 section 추가.
신규 section `## Dogfood trigger` (사이 Release 와 Naming):
- 도그푸딩이 필요한 시점 (6 trigger 분류: schema/migration, wire
schema/CLI, search/RAG, performance, language/locale, file/asset).
- Release-level: bump commit 이전에 evidence 명시 필수.
- 도그푸딩 데이터 보관소: /build/cache/dogfood/ 의 디렉토리 구조 +
README.md cross-link + /tmp/kebab-* 신규 사용 금지.
- 도그푸딩 결과 기록: HOTFIXES dated entry + release notes draft 의
4-단락 풀어쓰기 + DOGFOOD.md scenario catalog cascade.
실 작업:
- /build/cache/tmp/v0.20.1-* 5 디렉토리, /tmp/dogfood-* 2 디렉토리,
관련 log file 모두 /build/cache/dogfood/ 로 mv. config.toml 의
hard-coded path 자동 sed-replace.
- /build/cache/dogfood/README.md 신규 — 디렉토리 구조 + 신규 시나리오
시작 절차 + V007 시뮬레이션 패턴 + 정리 정책.
기대 효과: 도그푸딩 evidence 의 git-tracked HOTFIXES + draft release
notes 외에도 raw data 가 한 곳에서 자유롭게 재사용 가능. 새 release
의 도그푸딩이 이전 KB 위에서 incremental 확인 가능.
Spec: docs/superpowers/specs/2026-05-28-v0.20.x-korean-morphological-tokenizer-spec.md §9 (도그푸딩 evidence cascade)
Plan: post-implementation infrastructure
사용자 실제 /home/altair823/KnowledgeBase/ (1781 markdown / 9050 chunk)
를 v0.20.1+N-gram supplement 포함 binary 로 backfill 재실행:
- Backfill duration: 26.6초 (9050 chunk, OnceLock 캐시 + 1000-row
batch transaction). ~3 ms/chunk amortized.
- '한국' query: V007 의 0 hit → V009 + N-gram 의 10 hit (Bug #8
functional closure 실측 검증).
- '한국어' query: 5 → 10 hit (morpheme + N-gram 동시 매칭).
- 영어 whole-token: 'token'/'pipeline'/'config' = 10 hit each
(V009 회귀 측면 정상).
Snippet evidence: KB 의 testdata/coding-md-corpus/*/...md 의
"문서를 한국어로 다시 정리하기" 패턴이 ko-dic 분해 + N-gram window
로 '한국' query 매칭 demonstrate.
기타 한국어 (서울, 지하철, 대한민국 등) 0 hit 는 KB corpus 의
단어 자체 부재 — data limitation, V009 implementation limitation X.
Test data 위치:
- /home/altair823/KnowledgeBase/ (사용자 실제 KB, 1781 markdown)
- /build/cache/tmp/v0.20.1-dogfood/kb/ (ingested SQLite + LanceDB)
- /build/cache/tmp/v0.20.1-dogfood2/corpus/ (한국어 wiki fixture)
- /build/cache/tmp/v0.20.1-v007strict/corpus/no-space.md (whitespace-less)
- /build/cache/tmp/v0.20.1-ngram/corpus/extra.md (대한민국, 한국정부, 주민등록번호)
Spec: docs/superpowers/specs/2026-05-28-v0.20.x-korean-morphological-tokenizer-spec.md §9 + Appendix B
Plan: docs/superpowers/plans/2026-05-28-v0.20.x-korean-morphological-tokenizer-plan.md (dogfood evidence final)
#4 (사용자 요청): spec §6.2 의 Option β (sub-token 추가 emit) 를
v0.21.x P9 follow-up 에서 v0.20.1 implementation 으로 promote.
dogfood 의 ko-dic compound noun limitation (`대한민국`, `한국정부`,
`주민등록번호` 등 단일 token 정책) 해소.
Implementation (`crates/kebab-chunk/src/lib.rs::tokenize_korean_morphological`):
- 신규 helper `is_hangul()` — 한글 음절 (U+AC00..D7A3) + 자모
(U+1100..11FF, U+3130..318F) 판정.
- lindera output 의 각 morpheme 에 대해, 한글만 + 길이 ≥ 3 인 경우
sliding window 2-gram 추가 emit. `[한국정부, 한국, 국정, 정부]`
형태로 token list expand.
- 영어 / 숫자 / 혼합 token 은 supplement X (false positive 회피).
Tests (`crates/kebab-chunk/tests/tokenize_korean.rs`):
- `tokenize_korean_morphological_emits_2gram_for_long_morpheme`: 5 probe
fixture 중 supplement 발화 case 확인 (실측 `서울특별시` →
`[서울, 특별시, 특별, 별시]`, `대한민국` → `[대한민국, 대한,
한민, 민국]`).
- `tokenize_korean_morphological_no_2gram_for_english`: Rust optimization
fixture 에서 영어 substring (`Rus`, `ust`, `imi`) emit 없음 보장.
Dogfood evidence (`tasks/HOTFIXES.md` 2026-05-28 entry 보강):
- '대한', '한민', '민국' query 모두 hit (대한민국 의 sliding window).
- '특별', '주민', '등록' 같은 sub-token query hit.
- 영어 'tokenizer' query 는 corpus 부재로 0 hit (supplement X).
- Trade-off: DB size +20-30% (Korean-heavy), false positive 작은 risk.
Spec: docs/superpowers/specs/2026-05-28-v0.20.x-korean-morphological-tokenizer-spec.md §6.2 (Option β promote)
Plan: docs/superpowers/plans/2026-05-28-v0.20.x-korean-morphological-tokenizer-plan.md (post-implementation enhancement)
V009 한국어 morphological tokenizer 의 dogfood 검증 결과를 HOTFIXES
2026-05-28 entry 에 보강. 14 scenario 의 hit count + ko-dic 의
compound noun 분해 evidence (서울특별시 → [서울, 특별시]) + Option α
acceptance 의 known limitation 명시.
Reference corpus: DOGFOOD.md §2.1bis 의 korea-overview.md +
korea-compound.md (10 KB 합계, 2 markdown). KB ingest + 14 query
검증 모두 expected.
사용자 KnowledgeBase 같은 영어/code 중심 KB 에서 한국어 lexical
0-hit 가 정상임을 reference fixture evidence 와 분리해 사용자
오인 방지.
Spec: docs/superpowers/specs/2026-05-28-v0.20.x-korean-morphological-tokenizer-spec.md §9
Plan: docs/superpowers/plans/2026-05-28-v0.20.x-korean-morphological-tokenizer-plan.md (S11 + dogfood evidence)
opus PR-level final review (Approved with notes) 의 4 minor finding
mechanical 정정:
1. README.md — `kebab search` row 의 영어 substring 매칭 표현이
V007 시절 그대로였음. V009 의 whole-token 회귀 (substring → V002
동작) 를 정직히 명시 + vector/hybrid mode 권장 안내.
2. tasks/HOTFIXES.md — 2026-05-28 entry 의 file path 정정. lexical.rs
는 lindera 호출자가 아니라 build_match_string 의 MIN_QUERY_CHARS
3→2 갱신만; lindera helper 의 실제 owner 는 kebab-chunk/src/lib.rs.
ingest.rs 는 본 PR scope 외, eager backfill hook 위치는 kebab-app/
src/app.rs::App::open_with_config.
3. docs/wire-schema/v1/search_response.schema.json — `hint` field
description 이 V007 trigram 3-char minimum 시절 advisory 시그니처
그대로. v0.20.1 에서 helper retired + always-omit 사실 명시
(forward-compat 차원에서 field 만 schema 에 보존).
4. integrations/claude-code/kebab/SKILL.md — `hint` field 설명의
self-contradiction ("present only with trigram in edge cases" vs
"Korean 2-char now supported") 해소. retired + reuse 가능 명시.
PR-level reviewer recommendation: "Merge as-is — block 사유 아님 (모든
finding minor)". 본 commit 은 reviewer 의 옵션 1 (별 docs hotfix
commit) 채택.
Spec: docs/superpowers/specs/2026-05-28-v0.20.x-korean-morphological-tokenizer-spec.md
Plan: docs/superpowers/plans/2026-05-28-v0.20.x-korean-morphological-tokenizer-plan.md (PR-level finding follow-up)
S3 의 Chunk struct 갱신 (kebab-core 의 tokenized_korean_text:
Option<String> field 추가) 가 모든 chunk snapshot JSON 의 serde
serialize 결과를 변경시킴. 10 snapshot fixture (9 AST chunker +
markdown long-section) 의 baseline 을 V009 형태로 regenerate.
각 snapshot 의 변경 = chunk JSON 마다 `"tokenized_korean_text":
null` field 추가 (대부분의 fixture 가 영어 코드라 lindera 의 None
fallback). 동작 변경 없음 — serde representation 의 cascade만.
Spec: docs/superpowers/specs/2026-05-28-v0.20.x-korean-morphological-tokenizer-spec.md §6.2
Plan: docs/superpowers/plans/2026-05-28-v0.20.x-korean-morphological-tokenizer-plan.md (S3 follow-up via S11 sanity)
V009 morphological tokenizer 작업 (S3 chunk + S4 backfill + S5
short_query_hint 제거 + S7 신규 tests) 의 형식 정리. 동작 변경 없음.
Spec: docs/superpowers/specs/2026-05-28-v0.20.x-korean-morphological-tokenizer-spec.md
Plan: docs/superpowers/plans/2026-05-28-v0.20.x-korean-morphological-tokenizer-plan.md (S11)
CLAUDE.md §Release / binary version bump 의 두 트리거 모두 hit:
- 사용자 도그푸딩 필요 (Bug #8 한국어 2자 query 해소 — '한국', '서울',
'지하철' 검색 검증).
- frozen design contract 변경 (§5.5 chunks_fts 의 unicode61 + CASE
expression triggers + tokenized_korean_text column).
V009 + lindera ko-dic 형태소 분석기 통합 외에도 v0.20.x 의 logging
round 2 enhancement (PR #190) 가 같은 v0.20.x 시리즈에 포함되어
v0.20.1 patch release 시점에 함께 cut.
Build verification: ./target/release/kebab --version → kebab 0.20.1.
Spec: docs/superpowers/specs/2026-05-28-v0.20.x-korean-morphological-tokenizer-spec.md §12.1
Plan: docs/superpowers/plans/2026-05-28-v0.20.x-korean-morphological-tokenizer-plan.md (S10)
V009 한국어 morphological tokenizer 의 사용자 visible surface 변경 +
release notes scope 를 5 docs 에 cascade.
- README.md: kebab search 명령 row 에 한국어 2자 query 지원 명시.
- integrations/claude-code/kebab/SKILL.md: V007 3-char hint 제거 +
V009 2자 한국어 query 지원 1줄.
- HANDOFF.md: C task status 완료 flip + v0.20.1 release notes scope
에 본 변경 추가 + 머지 후 발견 summary 행.
- docs/ARCHITECTURE.md: embedding upgrade (e5-small → e5-large),
lindera-ko-dic FTS5 한국어 지원, version notes 추가.
- tasks/HOTFIXES.md: 2026-05-28 entry — Bug #8 V009 해소, lindera-ko-dic
실제 crate name (spec deviation), cargo-deny deferred, Path A
영어 substring 회귀 명시.
Spec: tasks/p9/p9-9-v0.20.x-korean-morphological-tokenizer-spec.md §7.4
Plan: docs/superpowers/plans/2026-05-28-v0.20.x-korean-morphological-tokenizer-plan.md
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
신규 4 test 추가:
- crates/kebab-store-sqlite/tests/fts.rs:
- fts_v009_korean_morphological_2char_query_hits: tokenized_korean_text
column 이 채워진 chunk 의 '한국' 2-char query hit.
- fts_v009_english_whole_token_only: V007 trigram substring 매칭
회귀 (Path A) — 'token' query 가 'tokenizer' chunk 에서 0-hit.
- crates/kebab-app/tests/search_korean.rs:
- korean_morphological_2char_query_lexical_mode: end-to-end
한국어 wiki fixture ingest → '한국' / '서울' query hit.
- korean_morphological_mixed_english_korean_query: 'Rust' English
whole-token + '최적화' Korean morpheme hit.
crates/kebab-search/src/lexical.rs:
- build_match_string() 의 MIN_TRIGRAM_CHARS(3) → MIN_QUERY_CHARS(2).
V009 unicode61 은 최소 token 길이 제한 없어 2자 한국어 morpheme
query 가 통과되어야 함. 1자 단독은 여전히 필터.
- 관련 unit test 2개 V009 동작으로 갱신.
fixture text 는 lindera ko-dic 의 실제 segmentation 동작에 의존
(spec Appendix B prior-knowledge 예측). 실측 시 fixture 조정 가능.
Spec: docs/superpowers/specs/2026-05-28-v0.20.x-korean-morphological-tokenizer-spec.md §9.1, §9.2
Plan: docs/superpowers/plans/2026-05-28-v0.20.x-korean-morphological-tokenizer-plan.md (S7)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
V009 의 FTS5 tokenizer 가 trigram → unicode61 + 한국어 형태소 분해
column 로 갱신됨. lexical_index_version 의 format 에
`fts5-v009-korean-morphological` suffix 추가하여 V007 baseline 과
구별. eval runner 의 config_snapshot 및 search cache 무효화에
자동 picks up.
기존 format: lex:{chunker_version}
신규 format: lex:{chunker_version}:fts5-v009-korean-morphological
Wire schema shape 변경 없음 (SearchHit.index_version 의 string
content 만 변화). lexical_index_version_is_returned_unchanged test
는 IndexVersion 의 임의 string 을 사용해 unchanged.
Spec: docs/superpowers/specs/2026-05-28-v0.20.x-korean-morphological-tokenizer-spec.md §11.1, §11.3
Plan: docs/superpowers/plans/2026-05-28-v0.20.x-korean-morphological-tokenizer-plan.md (S6)
V009 unicode61 + 형태소 tokenizer 환경에서 2-char 한국어 query 가
hit 가능해졌으므로 V007 시기의 "3자 이상 권장" hint 가 obsolete.
SearchResponse.hint field 는 wire schema 보존 위해 struct 에 유지 +
항상 None.
- kebab-app/src/app.rs: short_query_hint 함수 + doc-comment 삭제.
2 호출 site 가 hint = None 으로 정리.
- kebab-app/src/lib.rs: re-export 에서 short_query_hint 제거.
- kebab-tui/{app.rs,search.rs,run.rs}: short_query_hint field + 4
호출 cascade 제거.
- kebab-cli/tests/wire_search_response.rs:
search_plain_emits_short_query_hint_to_stderr test 삭제.
search_json_emits_hint_field_for_short_query →
search_json_hint_absent_for_short_query_v009 으로 교체
(hint 항상 None 검증).
- kebab-search/src/lexical.rs::build_match_string: V007 의 trigram
multi-token OR-combine 분기는 V009 환경에서 redundant 하나 보존
(future 확장성) — doc-comment 1 줄 추가.
Wire schema shape 변경 없음 (search_response.schema.json:33 의 hint
field 보존, struct 에 None 으로 항상 셋팅).
Spec: docs/superpowers/specs/2026-05-28-v0.20.x-korean-morphological-tokenizer-spec.md §7.2, §7.3, §11.3
Plan: docs/superpowers/plans/2026-05-28-v0.20.x-korean-morphological-tokenizer-plan.md (S5)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
V007 → V009 업그레이드 시 기존 chunks 의 tokenized_korean_text 가
NULL — 첫 App::open_with_config 호출 시 자동으로 lindera ko-dic
으로 분해 후 UPDATE. chunks_au trigger 가 chunks_fts 를 자동 재-index.
사용자 재-ingest 불필요.
- crates/kebab-store-sqlite/src/store.rs:
backfill_tokenized_korean_text(progress_cb, tokenize) API. 1000 row 마다
commit + progress 콜백. idempotent (IS NULL 필터로 partial
completion 재실행 안전). tokenizer 를 파라미터로 받아 §8 dep 경계 유지.
- crates/kebab-app/src/app.rs::open_with_config: run_migrations 직후
backfill 호출. 실패 시 warn log 만 (App open 은 성공 — vector/hybrid
mode 계속 가능). 500 row 마다 info log progress.
- crates/kebab-store-sqlite/tests/fts.rs:
backfill_tokenized_korean_text_populates_nullable_rows 단위 test
(idempotency 포함).
- clippy pre-existing 오류 수정 (redundant_closure, map_unwrap_or,
cast_lossless, uninlined_format_args — kebab-app/ingest_log.rs,
pdf_ocr_apply.rs, app.rs, tests/ocr_inspect_smoke.rs).
Spec: docs/superpowers/specs/2026-05-28-v0.20.x-korean-morphological-tokenizer-spec.md §8.1, §8.2
Plan: docs/superpowers/plans/2026-05-28-v0.20.x-korean-morphological-tokenizer-plan.md (S4)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
V004 seeds corpus_revision=0, V009 migration bumps to 1 (spec §5.2 —
LRU cache invalidation). Test previously asserted fresh store = 0;
now reads post-migration baseline dynamically and verifies that the
ingest commit increments past it.
Spec: docs/superpowers/specs/2026-05-28-v0.20.x-korean-morphological-tokenizer-spec.md §5.2
Plan: docs/superpowers/plans/2026-05-28-v0.20.x-korean-morphological-tokenizer-plan.md (S3 follow-up)
V007 trigram tokenizer 의 substring 매칭을 검증하던 3 test 는 V009
unicode61 으로 의도된 회귀 (spec §3 Non-Goals Path A) 가 발생하므로
obsolete:
- fts_trigram_korean_3char_substring_hits: '발생한' → '발생한다' hit
은 trigram 의 substring 매칭이라 V009 의 whole-token 매칭에서 fail.
- fts_trigram_korean_short_query_zero_hit_pinned: 2-char Korean
query 의 0-hit 동작은 V009 의 형태소 column 으로 해소되므로 이 핀
자체가 obsolete (S7 이 신규 2-char hit test 로 대체).
- fts_trigram_english_substring_hits: 'token' → 'tokenizer' hit 은
V009 unicode61 의 whole-token only 에서 fail.
신규 추가:
- fts_v009_unicode61_space_separated_korean_token_hits: V009 unicode61
의 whole-token 매칭 sanity (token '충돌은' hit, substring '발생한'
0-hit). S7 이 추가할 morphological 검증 test 와 별개의 baseline.
S7 (plan §2 Step 7) 가 v009_korean_morphological_2char_query_hits +
v009_english_whole_token_only 를 추가하여 회귀 + 신규 동작 모두 핀할
예정.
Spec: docs/superpowers/specs/2026-05-28-v0.20.x-korean-morphological-tokenizer-spec.md §3, §9.2
Plan: docs/superpowers/plans/2026-05-28-v0.20.x-korean-morphological-tokenizer-plan.md (S3 follow-up)
S3 spec compliance reviewer (sonnet) 가 2 blocker 발견:
1. crates/kebab-store-sqlite/src/documents.rs: get_chunk SELECT 가
tokenized_korean_text column 을 미조회 → DB 의 값이 read 시 유실.
SELECT column list + row → Chunk 변환 시 row.get 인덱스 추가.
ChunkRow struct + chunk_row_from_sql + get_chunk Chunk 생성 cascade.
2. crates/kebab-chunk/src/code_*_ast_v1.rs (9 file): make_chunk 가
tokenized_korean_text: None 하드코딩 → 한국어 주석을 가진 코드
파일이 FTS hit 안 됨. tier2_shared 와 동일 패턴으로
tokenize_korean_morphological(text) 호출 cascade.
이 commit 은 S3 의 rework — amend 아닌 별 commit (S3 boundary
유지). spec §6.2 invariant ("모든 chunker 가 chunk emit 직전에
tokenize 호출") 충족.
Spec: docs/superpowers/specs/2026-05-28-v0.20.x-korean-morphological-tokenizer-spec.md §6.2
Plan: docs/superpowers/plans/2026-05-28-v0.20.x-korean-morphological-tokenizer-plan.md (S3 rework)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
V009 의 tokenized_korean_text column 에 들어갈 morpheme sequence
를 lindera ko-dic 으로 분해. chunk builder pipeline 의 chunk 생성
직후 시점에서 호출 → chunk struct 의 field 에 pre-fill → store
의 put_chunks 가 단일 transaction 안에서 INSERT.
- crates/kebab-core/src/chunk.rs: Chunk struct 에
tokenized_korean_text: Option<String> field 추가 (#[serde(default)]).
- crates/kebab-chunk/src/lib.rs: tokenize_korean_morphological()
helper + OnceLock 캐싱 + fallback (None) 정책.
- crates/kebab-chunk/Cargo.toml: lindera features = ["embed-ko-dic"]
추가 (DictionaryKind::KoDic 활성화에 필요).
- 모든 chunker (tier2_shared, md_heading_v1, pdf_page_v1, 9개
code AST v1): Chunk 리터럴에 tokenized_korean_text pre-fill.
- crates/kebab-store-sqlite/src/documents.rs::put_chunks: INSERT
SQL column list + placeholder + binding 갱신 (12번째 column).
- crates/kebab-chunk/tests/tokenize_korean.rs: 단위 테스트 2개.
lindera 3.0.7 API 정정: load_dictionary_from_kind →
load_embedded_dictionary, Token.text → Token.surface.
Spec: docs/superpowers/specs/2026-05-28-v0.20.x-korean-morphological-tokenizer-spec.md §6.2
Plan: docs/superpowers/plans/2026-05-28-v0.20.x-korean-morphological-tokenizer-plan.md (S3)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
V007 trigram tokenizer 의 한국어 2자 query 0-hit 한계 (Bug #8) 해소를
위한 V009 migration 추가. unicode61 tokenizer 로 환원 + 한국어 형태소
분해 결과를 별 column `tokenized_korean_text` 에 pre-fill 하는 방식.
- migrations/V009__fts_korean_morphological.sql 신규: column ADD,
chunks_fts DROP+재정의, 3 trigger CASE expression, backfill INSERT,
corpus_revision bump.
- design §5.5 갱신: trigram → unicode61 + 형태소 column. CASE
expression trigger 본문.
- crates/kebab-store-sqlite/tests/fts.rs: V007 verbatim test 를
V009 source-of-truth 로 rename. v009_bumps_corpus_revision unit
test 추가.
- store.rs: clippy bool_to_int_with_if + cast_lossless 기존 경고 수정
(pdf_ocr_events 관련 코드, S1 작업 중 발견).
영어 substring 매칭은 V002 (whole-token only) 로 회귀 — spec §3
Non-Goals + 후속 release notes (v0.20.1) 에서 정직히 기술.
Spec: docs/superpowers/specs/2026-05-28-v0.20.x-korean-morphological-tokenizer-spec.md
Plan: docs/superpowers/plans/2026-05-28-v0.20.x-korean-morphological-tokenizer-plan.md (S1)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>