Files
kebab/HANDOFF.md
altair823 2d68827cf5 refactor(core): 빈 re-export shim crate kebab-embed/kebab-llm → kebab-core 흡수
kebab-embed/kebab-llm 은 "새 type 없음"을 자처한 순수 re-export 셸이었다
(trait 은 이미 kebab-core 소유, mock + test helper 만 보유). "kebab-core
재구성 시 안정 surface" 라는 명분은 1인 RAG 엔 speculative YAGNI. 흡수:

- kebab-core 에 default-OFF `mock` feature + src/mock.rs (MockEmbedder,
  MockLanguageModel, assert_vector_shape/assert_unit_norm/assert_finish_chunk
  을 kebab_core:: → crate:: import 만 바꿔 verbatim 이동).
- production import 2곳(kebab-embed-local, kebab-llm-local) +
  test import 다수(search/rag/parse-image/embed-local) 를 kebab_core 로 repoint.
  mock 쓰는 crate 는 dev-dep 에 features=["mock"] (default 빌드 무영향).
- shim 자체 테스트: mock 동작 테스트는 kebab-core/tests/ 로 이동,
  reexports.rs(셸 재수출 테스트)는 폐기.
- crates/kebab-embed, crates/kebab-llm 삭제 + workspace member/deps 정리.
- ARCHITECTURE/HANDOFF/component README 의 crate 그래프·표·rationale 갱신
  (22 → 20 crates). llm-local 의 broken intra-doc link 2건도 정리.

trait surface·동작 불변 (test-only + import-rename). workspace build 는 mock
default-OFF 라 mock 코드 미컴파일. 적대적 검증 3렌즈(build-test-integrity +
behavior-identity[mock byte-identical] + dead-crate-completeness) 통과,
clippy --workspace -D warnings 클린.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Mc6W1fgsrbFKTsqA6P8La
2026-06-27 01:06:14 +00:00

51 KiB
Raw Blame History

HANDOFF — 진척도

새 conversation / 다른 사람이 이어받을 때 "지금 어디까지 됐고 다음에 뭘 할지" 의 단일 출처. 사용자 사용법은 README.md, 아키텍처는 docs/ARCHITECTURE.md, per-component 진행은 tasks/INDEX.md, 머지 후 발견된 버그는 tasks/HOTFIXES.md. 이 파일은 "phase 단위 진척" + "다음 task 후보" 만 담는다.

한 줄 요약

P0P5 + P6 + P7 + P9-1/2/3/4 (Library / Search / Ask / Inspect) + P10 전체 머지 완료 (현재 v0.18.0). kebab ingest 가 markdown / image / PDF / 소스코드 (Rust / Python / TS / JS / Go / Java / Kotlin / C / C++) / Tier 2 리소스 파일 (yaml/k8s / dockerfile / toml / json / xml / groovy / go-mod) + Tier 3 paragraph fallback (shell / 비-k8s YAML / AST 실패 케이스) 처리. kebab search / kebab ask 가 매체 가로질러 결과 + page / code citation 반환. kebab tui 가 4 패널 (Library + Search + Ask + Inspect) 제공. v0.17.0 cut (2026-05-24): 한국어 trigram FTS5 tokenizer (PR #159) + C typedef alias unit (PR #160) + code_lang_chunk_breakdown additive (PR #161). v0.17.1 cut (2026-05-25): 확장 도그푸딩 후 [models.llm] request_timeout_secs config 노브 (PR #162) + sudo 없이 ollama 설치 + kebab ask --stream UX 권장 docs (PR #163). v0.17.2 cut (2026-05-25): v0.17.1 post-dogfood polish — [image.ocr] request_timeout_secs 별 노브 (PR #164, v0.17.1 미진행 closure) + heading_path FTS5 column filter 로 text-only 매칭 + raw-mode escape hatch (PR #165, 2026-05-24 v0.17.0 trigram entry 의 JSON 노이즈 closure). v0.18.0 cut (2026-05-26): fb-41 multi-hop RAG + NLI verification ship (PR #176-180) — kebab ask --multi-hop 의 decompose → decide → synthesize loop + mDeBERTa-v3 XNLI ONNX post-synthesize entailment 검사. dogfood S7 caffeine hallucination 의 silent LLM-self-judge ceiling 해결 (nli_score 0.0035 graceful refuse). 추가 chore: workspace-wide cleanup + post-PR9 refactor (PR #181) — clippy::pedantic baseline + H1 config wiring + 9 new tests. 자세한 영향은 v0.17.0 release notes + v0.17.1 release notes + v0.17.2 release notes + v0.18.0 release notes. 구조적으로 남은 component 는 P9-5 (desktop tauri) 하나뿐, P8 (audio) 는 사용자 보류.

Phase 로드맵

Phase 내용 핵심 산출 crate 선행 상태
P0 Workspace 뼈대 + 도메인 계약 + ID recipe kebab-core, kebab-parse-types, kebab-config, kebab-app, kebab-cli 완료
P1 Markdown ingestion (walk → parse → chunk → SQLite) kebab-source-fs, kebab-parse-md, kebab-normalize, kebab-chunk, kebab-store-sqlite P0 완료
P2 SQLite FTS5 lexical 검색 + citation kebab-search (lexical) P1 완료
P3 Local embedding + LanceDB + hybrid (RRF) + kebab-app wiring kebab-embed, kebab-embed-local, kebab-store-vector, kebab-search P2 완료
P4 Local LLM + RAG + grounded answer kebab-llm, kebab-llm-local, kebab-rag P3 완료
P5 Golden query / regression eval kebab-eval P4 완료
P6 이미지 ingestion (OCR + caption) kebab-parse-image P5 완료 (4/4 component, OCR/caption Ollama-vision)
P7 PDF text + page citation + scanned OCR (v0.20.0 sub-item 1) kebab-parse-pdf + kebab-app::pdf_ocr_apply P5 + P6 완료 (3/3 component, page-level chunker + ingest wiring + post-extract OCR enrichment via qwen2.5vl:3b vision LLM)
P8 음성 transcription + timestamp citation kebab-parse-audio P5 ⏸ 보류 (whisper-rs 시스템 dep brainstorm 필요)
P9 desktop app kebab-desktop P5 ⏸ 보류 (TUI 제거됨 — CLI/MCP 로 UI 집약, P9-5 desktop 예정)
P10 code ingest framework kebab-parse-code P5 🟡 진행 중 — 1A-1 (wire schema + parse-code skeleton + filter flags), 1A-2 (Rust AST chunker, code-rust-ast-v1 — v0.7.0), 1B (Python/TS/JS AST chunkers — v0.8.0 이후), 1C-Go (Go AST chunker, code-go-ast-v1 — v0.12.0), 1C-JavaKotlin (Java + Kotlin AST chunkers, code-java-ast-v1 / code-kotlin-ast-v1 — v0.13.0), 2 (Tier 2 resource-aware: yaml/k8s + dockerfile + manifest, k8s-manifest-resource-v1 / dockerfile-file-v1 / manifest-file-v1 — v0.14.0), 3 (Tier 3 paragraph fallback: code-text-paragraph-v1 — v0.15.0), 1D (C + C++ AST chunkers, code-c-ast-v1 + code-cpp-ast-v1 — v0.16.0)

P0P5 직렬. P6P9 P5 이후 병렬 가능.

Component 카운트

총 33 component task — spec 시점 31 개 + 후속 wiring task 3 (P3-5 / P6-4 / P7-3) 가 머지 시점에 추가됨. v0.18.0 cut 시점에 fb-41 multi-hop RAG + NLI verification (PR-9 5 sub-PRs) 가 P9 추가 component 로 ship — kebab-nli 신규 crate (mDeBERTa-v3 XNLI ONNX verifier) + kebab-rag::ask_multi_hop (decompose/decide/synthesize loop + step 8.5 NLI hook). per-component 진행 + status 는 tasks/INDEX.md.

머지 후 발견된 버그 / 결정 (요약)

  • candle 임베딩 백엔드 제거 (2026-06-24, spine-phase0): provider = "candle" 제거 — fastembed(기본) + ollama 두 경로로 충분, candle 은 미사용. num_threads 필드는 TOML 하위호환 위해 유지(레거시, 무시). 상세: spine-cuts 계획.
  • config 마이그레이션 (2026-05-31, PR #198): kebab config migrate 추가 — 기존 config.toml 에 빠진 섹션을 주석과 함께 채우고 deprecated 정리(멱등·.bak·dry-run, 값/주석 보존). schema_version 1→2, init 도 섹션 주석 포함, doctor 에 config_migration 체크. 상세 HOTFIXES 동일 일자.

머지 후 발견된 모든 deviation / hotfix 의 dated 로그는 tasks/HOTFIXES.md. 본 요약은 "누군가가 인수받을 때 알아두면 시간을 많이 절약하는" 항목만:

  • 2026-06-27 ponytail-audit 정리 arc (over-engineering 제거) — 1인 RAG 가 과복잡해진 표면·구조를 감사 후 정리(능력 불변). (1) #219 죽은 search-cache scaffold 제거 — #214 spine 에서 LRU 캐시를 없앤 뒤 남은 App::search_uncached/search_uncached_with_config facade/search --no-cache·--explain 플래그/explain_default config/관련 주석. search() 는 byte-identical(본문 verbatim 이동), search_cache: false wire capability 만 유지. (2) #220 9개 동일 code AST chunker(code_*_ast_v1.rs) → 단일 CodeAstV1Chunker { version_label } + for_lang(lang) 통합 (3030줄). chunker 는 tree-sitter 미사용·lang 은 SourceSpan 데이터 → struct 차이는 VERSION_LABEL 문자열뿐. 라벨 verbatim 유지 → chunk_id byte-identical → 재인덱싱 0; 9개 골든 스냅샷이 expected 무수정 통과로 증명. (3) pure re-export shim 이던 kebab-embed/kebab-llm(trait 은 이미 kebab-core 소유, mock+test helper 만 보유)를 kebab-core 의 default-OFF mock feature 로 흡수 — 22 → 20 crates, trait surface·동작 불변(test-only + import-rename churn, dev-dep features=["mock"]). 후속(작은 tail): FusionPolicy 1-arm enum→inline, NliVerifier default-0 shim 제거, dual-YAML 통일. 자세한 내용: 각 PR(#219/#220/…) + docs/ARCHITECTURE.md.

  • 2026-06-24 md-heading-v2: 예산 초과 청크 일반 분할 — v0.30.0. markdown 청커가 v1 의 "블록 미분할" 한계를 일반화 — 거대 list/code/table/paragraph 가 한 청크로 임베더 ctx 를 초과하던 문제를, token_estimate > max_chunk_tokens(신규 config, byte/3, default 4000)인 청크만 줄(→UTF-8 char) 경계로 분할해 해소. 미분할 청크는 v1 과 byte-identical. 분할 조각 chunk_id 는 #seg{i} 접미사로 충돌 회피, max_chunk_tokens 는 v2 policy_hash 에 fold(공유 ChunkPolicy 미변경). chunker_version v1→v2 라 다음 plain ingest 에서 markdown 1회 자동 재청크(코드/PDF 무영향). 동기: strict 임베더(AMD Lemonade /api/embed)는 oversize 입력을 truncate 아닌 거부(500 too large) — ollama 가 조용히 truncate 하던 걸 청커가 애초에 안 만들도록. known limitation: 분할 조각 citation 은 블록 단위(sub-line 정밀 아님). 도그푸딩(실험 KB, arctic@Lemonade): v2 전 620 중 2 doc 임베드 실패 → v2 후 620/620·7114 청크 전부 ≤4000, "WiredTiger excessive memory" 질의에 거대 doc SERVER-22906 가 1위(0.977). 자세한 내용: tasks/HOTFIXES.md (2026-06-24), 설계 docs/superpowers/plans/2026-06-24-md-heading-v2-oversize-split.md.

  • 2026-06-21 provenance 출처 필터: [[workspace.sources]] 멀티소스 + --source/--source-type — v0.29.0. 혼합 출처 KB(위키+jira 등)에서 색인은 전부 하되 질의 시 출처로 좁히는 레버. config [[workspace.sources]](각 id/root/trust_level/source_type) + documents.source_id 컬럼(V014, additive, 재색인 0) + config v3→v4 migration(step_3_to_4, 단일 root→implicit default source, 멱등) + 검색 --source <id> / --source-type <type>(lexical+vector 두 site, OR). trust precedence = frontmatter > per-source 기본값 > Primary. 설계 근거: 전역 trust 곱셈가중(weighted-RRF)은 A/B 에서 반증(θ=0.85 만으로 incident MRR 0.918→0.340 절벽) — 필터가 see-saw 없는 올바른 레버. 도그푸딩(620 doc, jira400+wiki220): --source wiki concept 0.780→0.810, --source jira incident 0.918→0.975. follow-up: MCP search 필터 미노출 · kebab list source_id 미표시 · RAG provenance 라벨 미구현. 자세한 내용: tasks/HOTFIXES.md (2026-06-21).

  • 2026-06-04 PP-OCRv5 ONNX Rust 네이티브 OCR — v0.27.0. [image.ocr] engine = "paddle-onnx" 로 PP-OCRv5(검출+인식) ONNX 를 in-process(ort =2.0.0-rc.9) 실행 — Python 런타임/원격 호출 없이 큰 페이지 CPU <4초(Ollama vision ~50초 대비). default 는 여전히 "ollama-vision". 후처리(min-area rect/unclip)는 pure-Rust. 함정: unclip 은 corner 를 centroid 에서 방사 확장하면 안 되고 edge 별 polygon offset 이어야 함(방사 확장 시 wide/short 텍스트 박스 높이가 안 커져 글자 윗부분 잘림 → ㄷ→ㄴ, e2e CER 0.26). 수정 후 CER 0.005. 모델 ONNX 는 crates/kebab-parse-image/assets/paddleocr-onnx/(LFS). 자세한 내용: tasks/HOTFIXES.md (2026-06-04 PP-OCRv5 ONNX), spec/plan docs/superpowers/{specs,plans}/2026-06-04-rust-native-ocr-*.md.

  • 2026-06-03 ingest 설정 변경 자동 재색인 — v0.26.2. ingest 산출에 영향 주는 설정(청킹/이미지 OCR·caption/pdf.ocr/[ingest.code])을 변경하면 --force-reingest 없이 영향 자산만 자동 재색인. 그 설정들의 결정적 서명(ingest_config_signature)을 effective parser_version(skip 비교 + 저장 doc 필드 양쪽)에 폴딩 → 다음 ingest 비교가 mismatch. 비산출 설정(search/rag/ui/log + max_pixels/languages/timeout)은 제외(과도 무효화 회피), doc_id 는 base 로 안정 유지. 업그레이드 후 첫 ingest 는 전 자산 1회 재색인(저장된 상수 parser_version ≠ 새 composite; embedding 은 V012 캐시 히트). 결과 포맷·CLI·wire 불변(내부 skip 판정 정정). 자세한 내용: tasks/HOTFIXES.md (2026-06-03 ingest 설정 변경 자동 재색인), spec/plan docs/superpowers/{specs,plans}/2026-06-03-*invalidation*.md.

  • 2026-06-03 ingest 진행 로그 개선 — v0.26.1. 이미지/PDF + OCR/caption on 볼트 ingest 가 "멈춘 듯" 보이던 문제 해소: TTY 진행바에 현재 파일명 + 느린 phase(ocr/caption/embed)+모델명 + 경과초 (Ns) heartbeat, 종료 시 최장 소요 파일 top-5 요약. 신규 wire asset_phase{idx,total,phase,model} + asset_timings.ocr_ms/caption_ms(additive, ingest_progress.v1 유지, serde default 0). 이미지·PDF 경로도 asset_timings emit(이전 markdown 만). 기본 동작 불변. 자세한 내용: tasks/HOTFIXES.md (2026-06-03 ingest 진행 로그), spec/plan docs/superpowers/{specs,plans}/2026-06-03-ingest-log-improve-*.md.

  • 2026-06-03 arctic-embed-l-v2.0 임베더 통합 — v0.26.0. 별칭 제거 후 설명형 query recall 보강(측정 recall@10 130/132, e5 +7). 신규 kebab-embed-ollama(provider="ollama", /api/embed). config endpoint: Option<String> 추가. 기본 e5 유지(opt-in), arctic 전환은 embedding_version cascade → 재색인. 자세한 내용: tasks/HOTFIXES.md (2026-06-03 arctic), spec docs/superpowers/specs/2026-06-03-arctic-embedder-spec.md.

  • 2026-06-03 doc-side expansion(별칭) 기능 완전 제거 — v0.25.0. 아래 2026-05-31 항목의 색인-시 청크당 LLM 별칭 생성 + 별칭 검색 채널을 전부 제거(ROI 음수: cross-lingual 은 e5-large 단독으로 충분, 기여는 설명형 +2 그룹뿐인데 대가가 청크당 색인-시 LLM). Chunk.aliases/expansion.rs/IngestExpansionCfg/alias lexical arm/expansion_progress wire kind 제거, 신규 마이그레이션 V013chunk_aliases_fts+chunks.aliases DROP. 별칭 default-off 였어 사용자 체감 0, 기존 KB 도 재색인 불요(잔존 별칭 벡터는 strip_alias_suffix graceful 매핑/reset 정리). AssetTimings.expansion_ms 는 wire 호환 위해 값 0 으로 유지. 자세한 내용: tasks/HOTFIXES.md (2026-06-03), spec docs/superpowers/specs/2026-06-03-remove-doc-expansion-spec.md.

  • 2026-05-31 Phase 2 doc-side expansion 별칭(개별 dense 벡터) + 파생물 캐시(V012) — v0.21.0 cut. 색인 시 LLM 이 청크별 별칭("같은 의미 다른 표현")을 생성, 줄별 개별 dense 벡터(sentinel {chunk}#alias#N)로 색인 (묶음 1벡터는 평균화 희석으로 회귀 → 폐기) + boilerplate 청크 skip. [ingest.expansion] default off. 측정(나무위키 ~1000 문서 CS corpus): 변형 일관성 14/18 → 16/18, spread 0.222→0.111, 대조군 false-positive 별칭 무죄. 비용 병목(별칭 18문서 2.5h)은 **파생물 캐시(V012, 청크 내용 해시 키)**로 해소 — 정답 3개 cold 1879s → warm 13s ≈ 145배, embedding+별칭 LLM 캐싱, version_key cascade 정합. search/ask 가 kebab.sqlite+lancedb 만으로 동작 → 외부 서버 색인 후 DB 만 복사하는 이식 워크플로 가능. 결정/known limitation: grounded/refusal 판정이 부분 인용을 grounded 로 오분류(정직한 거부가 false-positive 로 집계) — 별도 개선 후보. stack·svm 설명형 2개 잔존. 자세한 내용: tasks/HOTFIXES.md (2026-05-31), 측정: docs/superpowers/handoffs/2026-05-31-namu-wiki-alias-cache-study.md.

  • 2026-05-29 v0.20.2 dogfood findings + 검색 품질 baseline — 8-finding 라운드 완료. (1) Ask 응답언어: rag-v3 default (질문 언어 = 답변 언어). (2) eval --config facade 패치 로 dogfood KB 직접 eval 가능. (3) 검색 품질 baseline — hybrid hit@3=1.0 / MRR=0.833, lexical hit@3=1.0 / MRR=0.7 (golden 10 query). O-2 known limitation: 소형 모델(gemma4:e4b) refusal 메시지의 query 언어 불일치 가능 — 판정은 정상, 표시 문구만 해당. 자세한 내용: tasks/HOTFIXES.md (2026-05-29).

  • v0.20 sub-item 1 (scanned PDF OCR via qwen2.5vl:3b): post-extract enrichment pattern (kebab-app::pdf_ocr_apply, H-1 resolution), DCTDecode-only v1 scope (FlateDecode/CCITTFax page 는 warning + skip), parser_version "pdf-text-v1" 보존 + force-reingest UX 명문 (H-4).

  • 2026-05-26 kebab-normalize + kebab-parse-types 흡수 (24 → 22 crates, design §3.7b 재작성) — v0.19.0 cut. 4 parser 중 markdown 한 갈래만 lift 를 경유하는 reality 가 design §3.7b 의 fan-in ≥ 2 가정과 diverge → thin layer (kebab-parse-types) + kebab-normalize 두 crate 가 kebab-parse-md 로 흡수. 5 사용 type + 3 forward-declared struct 모두 kebab-parse-md::{types,normalize} module 의 pub re-export 로 보존. wire / surface impact = 0 (CLI / TUI / MCP / --json / config / XDG / parser_version 모두 unchanged). 자세한 내용: tasks/HOTFIXES.md (2026-05-26 design deviation entry).

  • 2026-05-26 v0.18.0 fb-41 multi-hop RAG + NLI verification ship (PR #176-180) + post-PR9 cleanup (PR #181) — pre-v0.18.0 dogfood (/build/cache/dogfood-v018/, 33 assets / 205 chunks, gemma3:4b CPU only / 16 GB RAM) 에서 발견된 S7 caffeine hallucination 의 root cause = LLM-self-judge ceiling (synthesize 가 chunks 와 무관한 Adam optimizer gradient 식을 silent emit, self-judge 가 reject 못함). 학계 표준 (Self-RAG, CRAG, Auto-GDA, MedTrust-RAG) 결론 = deterministic post-synthesis verification. mDeBERTa-v3 XNLI ONNX (280 MB, Xenova HF) 가 (packed_chunks, answer) entailment 검사 — [rag] nli_threshold > 0 (default 0.0 = disabled, production 권장 0.5) 일 때 활성. dogfood retest 측정 — S7 PR-8 baseline grounded=true + Adam hallucination → PR-9 nli_verification_failed, nli_score 0.0035. wire additive minor — answer.v1.verification field + refusal_reasonnli_verification_failed / nli_model_unavailable 추가, pre-v0.18 reader 무영향. 5 sub-PR 시퀀스 + cleanup PR (clippy::pedantic baseline + 의도적 30+ allow + H1 [models.nli].model config wiring + 9 new tests). post-refactor retest = PR-9d byte-identical (deterministic 확인). 자세한 내용: tasks/HOTFIXES.md (2026-05-25 fb-41 PR-9 closure entry + S3 follow-up).

  • 2026-05-25 v0.17.2 post-v0.17.1 polish (PR #164 + #165) — v0.17.1 의 두 follow-up closure. (1) [image.ocr] request_timeout_secs 별 노브 — crates/kebab-parse-image/src/ocr.rs::REQUEST_TIMEOUT hard 300s 제거, LLM 쪽 패턴 (PR #162) 을 OCR 어댑터에 동일 적용. 사용자 결정으로 별 노브 분리 (OCR vs LLM 의 cold start 패턴이 달라 독립 조절). v0.17.1 미진행 항목 closure. (2) chunks_ftsheading_path 컬럼이 JSON 표기 + path 세그먼트 까지 trigram 색인 → query false positive 가능 문제 closure. lexical.rs::build_match_string 가 non-raw 분기 결과를 text : (<expr>) 로 wrap — heading 색인 V007 verbatim 유지, 매칭만 text 한정. 사용자가 명시 heading 검색 하려면 raw mode 'heading_path : <token>' escape hatch (SKILL.md 갱신). 둘 다 additive (옛 config 호환) / re-ingest 불필요. 자세한 내용: tasks/HOTFIXES.md (2026-05-25 v0.17.2 두 entry).

  • 2026-05-25 v0.17.1 post-dogfood (PR #162 + #163) — 확장 도그푸딩 (16 GB CPU only, gemma4:e4b 시도) 에서 발견된 두 follow-up 한 묶음. (1) crates/kebab-llm-local/src/ollama.rs::REQUEST_TIMEOUT hard 300s → [models.llm] request_timeout_secs config + env override (additive, default 300, =0 은 disable 아닌 "즉시 timeout" 이라 doc 명시). (2) README + SMOKE 에 sudo / systemd 없이 ollama 설치 + ≤4B Q4 권장 모델 + kebab ask --stream UX 권장 docs. additive only — 옛 config / wire 호환. 자세한 내용: tasks/HOTFIXES.md (2026-05-25).

  • 2026-05-24 v0.17.0 PR-C code_lang_chunk_breakdown additive (closure of 2026-05-22 LOW)schema.v1.stats 에 chunk 수 집계 신규 키. 기존 code_lang_breakdown (doc count) 와 sister. 또 기존 두 필드 JSON schema description 의 "chunk count" 오기재 → "doc count" 로 정정. wire additive — schema_version bump 불필요. 자세한 내용: tasks/HOTFIXES.md (2026-05-24 PR-C).

  • 2026-05-24 v0.17.0 PR-B C typedef alias unit (closure of 2026-05-21)kebab-parse-code::c::extract_blockstype_definition 분기로 inner anonymous struct/enum/union → declarator 의 typedef alias 이름으로 synthetic unit 방출. PARSER_VERSION code-c-v1code-c-v2 bump + 같은-asset/다른-doc_id 케이스용 purge_workspace_path_for_parser_bump cascade (stale_chunk_ids_for_workspace_path_except_doc_id + purge_document_at_workspace_path_except_doc_id helper 신규). 사용자 작업 불필요 (다음 ingest 가 자동 재처리). 자세한 내용: tasks/HOTFIXES.md (2026-05-24 PR-B).

  • 2026-05-24 v0.17.0 PR-A 한국어 trigram tokenizer 채택 (closure of 2026-05-22 한국어 lexical)chunks_fts 가 FTS5 unicode61trigram 으로 V007 migration (자동 backfill, re-ingest 불필요). lexical.rs::build_match_string trigram-aware 재설계 — multi-token 한국어 query (해시 충돌) 가 whole-phrase 후보로 hit, 한영 혼합 (Rust 충돌은) 도 OR-combined. 2자 이하 query 는 0-hit + CLI/TUI/wire hint 안내. 영어 lexical 도 substring 매칭으로 바뀜 (recall ↑ / 단어 경계 ↓). kebab.sqlite 크기 ~2-5배 증가 (trigram index). 자세한 내용: tasks/HOTFIXES.md (2026-05-24).

  • 2026-05-22 P10 종합 도그푸딩 round 2 (한국어 lexical 검색 한계)kebab search --mode lexical 의 한국어 query 가 FTS5 unicode61 토크나이저에서 거의 0 hit (어절 단위 토큰화 → 부분 매칭 불가). 기본 hybrid 모드는 multilingual-e5-small vector 가 carry 해 한국어 검색 정상. closure: 위 2026-05-24 v0.17.0 entry.

  • 2026-05-20 P10-1B (Rust 1A symbol path 비일관 + expression-level 함수 미방출) — (a) Rust code-rust-ast-v1 은 file-scope nesting 만 (workspace path prefix 없음), 1B 의 Python/TypeScript/JavaScript 는 workspace 경로 → module path prefix 사용 (비일관 수용, retrofit = chunker_version bump + reindex 필요, 사용자 명시 요청까지 보류); (b) TS/JS 의 const foo = () => {...} 같은 expression-level 함수는 <top-level> glue 로 처리됨 (declaration-level 단위만 1B 1차 범위). 자세한 내용: tasks/HOTFIXES.md (2026-05-20) 두 항목.

  • 2026-05-19 P10-1A-2 (code_rust_ast_v1.rs + SourceType)AST_CHUNK_MAX_LINES 상수가 IngestCodeCfg.ast_chunk_max_lines 를 읽지 않고 모듈 상수 200 고정 (Chunker trait 이 per-medium config 미노출); SourceType::Code variant 부재로 code 파일이 SourceType::Note 로 분류됨 — 두 항목 모두 tasks/HOTFIXES.md (2026-05-19) 에 기록.

  • 2026-05-07 fb-26 (progress.rs)Aborted unconditional writeln (TTY duplicate) + Completed TTY no summary fixed; KEBAB_PROGRESS=plain env + quiet suppression added

  • 2026-05-07 fb-28 (main.rs)--readonly (KEBAB_READONLY) blocks Ingest/IngestFile/IngestStdin/Reset; --quiet suppresses progress stderr; error.v1 code: "readonly_mode"

  • 2026-05-07 macOS XDG path collision (config 사라지는 버그)dirs crate 가 macOS 에서 config_dir()data_dir() 둘 다 ~/Library/Application Support/ 반환 → reset --data-only 가 config 파일까지 삭제. Fix: ~/.config, ~/.local/share, ~/.cache 직접 사용. 새 경로: config ~/.config/kebab/, data ~/.local/share/kebab/, cache ~/.cache/kebab/. Config::load(None) 이 macOS legacy path 에서 자동 마이그레이션. 자세한 내용: tasks/HOTFIXES.md.

  • 2026-05-07 P9 post-도그푸딩 (p9-fb-31)kebab ingest-file <path> + kebab ingest-stdin --title <T> 두 신규 subcommand + MCP tool ingest_file / ingest_stdin (4 → 6 tool). agent 가 fetch 한 web markdown / 외부 file 을 KB 에 즉시 저장. workspace 외부 file 은 <workspace.root>/_external/<blake3-12>.<ext> 로 copy (deterministic 명명 → idempotent). _external/ 디렉토리 첫 생성 시 .kebabignore 자동 append (walk 무한 루프 방지). stdin 은 markdown 전용 + flag (--title, --source-uri) → frontmatter 자동 prepend. .kebabignore 매치 시 stderr warn 후 진행 (explicit ingest = bypass intent). fb-30 의 v1 read-only MCP 정책 변경 — 첫 mutation tool 도입. spec: tasks/p9/p9-fb-31-single-file-stdin-ingest.md. design: docs/superpowers/specs/2026-05-07-p9-fb-31-single-file-stdin-ingest-design.md.

  • 2026-05-07 P9 post-도그푸딩 (p9-fb-30)kebab mcp 신규 subcommand + new crate kebab-mcp (lib only) — stdio JSON-RPC server. 4 read-only tool (search / ask / schema / doctor) 가 kebab-app facade 위에 build. rmcp 1.6 SDK 채택, manual tools/list + tools/call dispatch (rmcp 의 #[tool_router] 매크로 대신). error_classify 모듈을 kebab-clikebab-app::error_wire 로 promotion (UI crate 끼리 import 회피, facade 룰 준수). ErrorV1schema_version: String 필드 추가 — kebab-mcp 의 직접 serialize 경로에서도 wire 정합. KebabAppState(Config, Option<PathBuf>) carry — doctor tool 의 path-aware behavior 위해. ask + search arm 의 tokio::task::spawn_blocking wrap — OllamaLanguageModel 의 reqwest blocking client 가 async 안에서 panic 회피. capability flag mcp_server falsetrue. agent integration MVP 완성 — Claude Code / Cursor / OpenAI Agents 등 host-agnostic 사용 가능. spec: tasks/p9/p9-fb-30-mcp-server.md. design: docs/superpowers/specs/2026-05-07-p9-fb-30-mcp-server-design.md.

  • P3-5 / P4-3 --config 누락kebab-cli--config <path> 를 honor 하려면 kebab_app::*_with_config companion 을 호출해야 함. 두 번 같은 모양으로 회귀했음.

  • P6-2 OCR 기본 엔진 — spec literal 의 Tesseract 가 시스템 dep 부담으로 거부됨, Ollama vision LM 으로 대체. OcrEngine trait 그대로라 future swap 가능.

  • P6-3 captionGenerateRequest.images 필드를 kebab-core::LanguageModel trait 에 신설. 기존 caller 모두 images: Vec::new() 로 마이그레이션.

  • P7-2 chunk_id 충돌 — pdf-page-v1 가 한 페이지 여러 chunk 분할 → 같은 block_ids 충돌. per-chunk policy_hash#c{char_start} 변형 으로 회피.

  • P7-3 storage UNIQUE bugassets.workspace_path UNIQUE + upsert_asset_rowON CONFLICT(asset_id) gap 으로 byte 변경 re-ingest 실패. purge_orphan_at_workspace_path helper 추가, follow-up PR 으로 vector store orphan cleanup 까지 닫음 (VectorStore::delete_by_chunk_ids).

  • P9-1 ratatui 0.28 — spec literal 의 render_library<B: Backend> generic 이 ratatui 0.28 의 backend-agnostic Frame 과 어긋나 있어 제거. 테스트 seam App::populate_library_for_testing (#[doc(hidden)]) 추가.

  • P9-2 jump_to_citation workspace_root — spec literal 의 jump_to_citation(citation, editor_env) 가 workspace_root 인자 누락. citation.path 가 workspace 상대라 editor 호출 시 절대 경로 필요 → workspace_root: &Path 인자 추가. 동일하게 render_search<B: Backend> generic 도 P9-1 과 같은 사유로 제거.

  • P9-3 e/j/k 키 의 "input empty" 분기 — spec 의 e=toggle explain / j=k=scroll 이 typing 과 충돌 ("explain" / "javascript" 같은 단어 입력 깨짐). input 이 비어 있을 때만 command 키로 동작 — vim "command vs insert" 컨벤션 변형. 사용자가 텍스트 입력 시 모든 알파벳 정상 통과.

  • P9-4 enter_inspect helper + Search i — spec 의 진입 경로 (Library Enter → Doc inspect, Search i → Chunk inspect) 를 한 helper 로 묶음. InspectTarget enum (Doc(DocumentId) | Chunk(ChunkId)), return_to: Pane 가 Esc 시 원래 pane 으로 복귀. c 키가 모든 section (metadata / provenance / blocks / spans / text / embeddings) 일괄 collapse/expand — spec 의 "focus 기반 selective collapse" 는 v1 단순화.

  • 2026-05-02 P9 도그푸딩 후속 (p9-fb-06)kebab reset --all|--data-only|--vector-only|--config-only [--yes] 추가. TTY 가 아니면 --yes 필수 (silent destruction 금지). --vector-only 가 SQLite embedding_records 도 함께 truncate (off-disk Lance dir 만 wipe 시 orphan 방지). 도그푸딩 막힘 강도 1위 (수동 4 경로 rm -rf 부담) 해소. spec: tasks/p9/p9-fb-06-data-reset-command.md, plan: docs/superpowers/plans/2026-05-02-p9-fb-06-reset-command.md.

  • 2026-05-02 P9 도그푸딩 후속 (spec PR #51 + p9-fb-01 + p9-fb-02)kebab ingest 진행 표시 도입. frozen design §2.4a 신설 (wire schema ingest_progress.v1 line-delimited streaming) + §10 의 long-running 작업 절 추가. kebab-app::ingest_with_config_progress(.., progress: Option<Sender<IngestEvent>>) facade 추가, 기존 _with_configprogress=None forwarding wrapper. CLI 가 indicatif TTY 진행 바 (stderr) / non-TTY 한 줄씩 / --json 모드는 line-delimited stdout. p9-fb-03 (TUI background worker) + p9-fb-04 (cancel) 가 같은 stream 위에 build.

  • 2026-05-02 P9 도그푸딩 후속 (p9-fb-03) — TUI 의 background ingest worker. Library 의 r 키가 kebab_app::ingest_with_config_progress 를 spawned thread 에서 호출, run loop 가 매 frame 마다 progress channel drain → 화면 하단 status bar 1 줄 갱신. terminal event (Completed/Aborted) 후 3 초 final 라인 hold + 자동 hide + Library auto-refresh. spec: tasks/p9/p9-fb-03-tui-ingest-background.md. (cancel slot 은 p9-fb-04 가 추가하는 형태로 단일화 — 회차 1 review 결과.)

  • 2026-05-02 P9 도그푸딩 후속 (p9-fb-04) — ingest cooperative cancellation. kebab-app::ingest_with_config_cancellable(.., cancel: Option<Arc<AtomicBool>>) facade 추가, 기존 _progresscancel=None forwarding. asset loop iter 시작 boundary 마다 cancel poll → true 면 break + IngestEvent::Aborted { partial_counts } + Ok(IngestReport) 정상 반환 (Err 아님). 부분 commit 보존, 다음 ingest 가 idempotent 재개. CLI Ctrl-C SIGINT handler (ctrlc crate) — 1회: cancel, 2회: hard exit (130). TUI Esc / Ctrl-C 가 cancel signal (in-flight 시), 그 외에는 quit. IngestStatecancel: Arc<AtomicBool> field 추가. spec: tasks/p9/p9-fb-04-ingest-cancellation.md.

  • 2026-05-02 P9 도그푸딩 후속 (spec PR #59 + p9-fb-15) — RAG multi-turn 도입. frozen design §3.8 갱신 — Answerconversation_id / turn_index optional field, 신규 Turn struct, RefusalReason::LlmStreamAborted variant. kebab-rag::AskOptshistory: Vec<Turn> / conversation_id / turn_index 3 field 추가, 기존 caller 는 Vec::new() / None (single-shot 동작 동일). RagPipeline::ask_with_history(query, history, conversation_id, turn_index, opts) helper. prompt 빌드: [이전 대화] 블록을 user prompt 위에 prepend, newest-first, char budget (cfg.rag.max_context_tokens * 4) 안에서 oldest 부터 drop. retrieval query expansion: 직전 answer 첫 200 자 concat. wire schema answer.v1 에 두 필드 + format: date-time 추가. p9-fb-16 (TUI conversation UI) + p9-fb-17/18 (V004 storage + CLI session) 가 같은 facade 위에 build. spec: tasks/p9/p9-fb-15-rag-multi-turn-core.md.

  • 2026-05-02 P9 도그푸딩 후속 (p9-fb-16) — TUI Ask conversation UI. AskStateturns: Vec<Turn> + current_question + conversation_id + last_answer 로 재설계. answer area 가 transcript (Q1/A1, Q2/A2, ...) 로 갈음, 매 Enter 가 이전 turns 를 history 로 worker 에 전달 (ask_with_history). conversation_id 는 첫 submit 시 timestamp-based 자동 생성 (conv_<unix_nanos_hex>). Ctrl-L 가 turns + conversation_id 초기화 (in-flight worker 는 그대로 finish, 결과는 새 conversation 의 stale turn 으로 silently 폐기). spec: tasks/p9/p9-fb-16-tui-ask-conversation.md.

  • 2026-05-03 P9 도그푸딩 후속 (p9-fb-20)kebab ask 의 CLI citation block. 답변 출력 후 근거: 절 — [N] <full path>#<fragment> (score=<s>) 한 줄씩. --show-citations (default ON) / --hide-citations (pipe 시 답변 본문만) flag. --json 모드는 무영향 (citations 가 항상 wire payload 에 포함). spec p9-fb-20 의 "TUI citation pane + jump" 부분은 P9-3 의 기존 render_citations_or_explain 가 일부 cover — 추가 기능 (turn 별 fold + Enter/o jump + i inspect) 은 후속 task 로 미룸 (사용자 도그푸딩 priority 5위 의 핵심 = full path 가독성 = CLI block 으로 충족). spec: tasks/p9/p9-fb-20-citation-surface.md.

  • 2026-05-03 P9 도그푸딩 후속 (p9-fb-07) — Markdown title fallback chain. kebab-normalize::derive_title(frontmatter_title, &[Block], file_stem) — 1) frontmatter title → 2) 첫 H1 → 3) 첫 H2 → 4) 첫 paragraph 80 chars → 5) 파일 stem (모든 단계 NFC 정규화, 빈 문자열 절대 반환 안 함, 마지막 sentinel "untitled"). build_canonical_document 가 lift 후 helper 호출. parser_version 상수 pulldown-cmark-0.xmd-frontmatter-v2 bump — 기존 doc 은 doc_id 가 갱신되므로 다음 ingest 가 자동 재처리 (idempotent upsert, design §9 cascade). spec: tasks/p9/p9-fb-07-md-title-fallback.md.

  • 2026-05-03 P9 도그푸딩 후속 (p9-fb-08) — TUI search async worker + generation counter. 기존 200ms debounce 후 kebab_app::search_with_config 동기 호출이 vector/hybrid 모드 50-200ms 동안 UI freeze 시키던 문제 해소. SearchStategeneration: u64 + worker_thread: Option<JoinHandle> + worker_rx: Option<Receiver<SearchWorkerMessage>> 신규. fire_search 가 spawn 만 하고 즉시 return — worker 가 별 thread 에서 검색 후 (generation, Result) 를 channel 로 post. run loop 가 매 tick poll_worker 로 try_recv, generation 일치 시 hits 적용 / 불일치 시 silently 폐기 (사용자가 더 빠르게 타이핑하면 stale 결과 자동 drop). debounce_due 가 searching && last_query == 현 input 케이스 추가 skip — in-flight worker 의 결과 기다리는 동안 동일 query 재 spawn 안 함. spec: tasks/p9/p9-fb-08-search-debounce.md.

  • 2026-05-03 P9 도그푸딩 후속 (p9-fb-05)workspace.root path policy 명확화. kebab_config::expand_path_with_base(raw, data_dir, base_dir) -> PathBuf 신규 — 기존 expand_path (tilde + env 만) 위에 relative path resolution 추가, 절대/~/${VAR} 입력은 base_dir 무시. Config.source_dir: Option<PathBuf> 필드 (#[serde(skip)]) 신규 — from_file / loadpath.parent() 로 stamp. Config::resolve_workspace_root() helper 가 expand_path_with_base(&workspace.root, "", source_dir.unwrap_or(cwd)) 호출. kebab-app + kebab-source-fs 의 모든 workspace.root 사용 사이트가 cfg.resolve_workspace_root() 로 통일 — kebab-source-fs 의 fork 된 expand_tilde 헬퍼는 제거 (kebab-app 의 storage.data_dir 한 곳만 남음, P+ 통일 caveat). kebab init 가 생성하는 config.toml 위에 path policy 안내 헤더 코멘트 자동 prepend (절대/tilde/env/상대 + 상대 base = config dir). spec: tasks/p9/p9-fb-05-config-path-policy.md.

  • 2026-05-03 P9 도그푸딩 후속 (p9-fb-19) — In-process LRU search cache + corpus_revision 카운터. SQLite V004 migration 으로 kv (key TEXT PK, value TEXT) 테이블 + corpus_revision = '0' seed. SqliteStore::corpus_revision() / bump_corpus_revision() 메서드 (UPDATE ... CAST AS INTEGER + 1 으로 atomic). kebab-app::ingest_with_config_cancellablenew + updated > 0 시 bump — no-op reingest 는 cache 보존. App.search_cache: Option<Mutex<LruCache<SearchCacheKey, Vec<SearchHit>>>> (capacity from config.search.cache_capacity, default 256, 0 = 비활성). SearchCacheKey = query_norm (NFKC + trim + lowercase) + mode + k + snippet_chars + embedding_version + chunker_version + corpus_revision snapshot. App::search 가 lookup → miss 시 search_uncached → put. search_uncached_with_config facade 추가, CLI kebab search --no-cache 로 bypass (디버깅용). frozen design §9 versioning 표에 corpus_revision row 추가. spec: tasks/p9/p9-fb-19-search-cache.md. → 후속(spine #214 + cleanup): LRU search cache 자체가 제거됨 — App.search_cache/SearchCacheKey/App::search_uncached/search_uncached_with_config facade/search --no-cache 플래그 모두 삭제. 이 항목은 이력이며 캐시·플래그는 더 이상 존재하지 않음 (search_cache: false wire capability 만 정직하게 유지). corpus_revision 카운터는 incremental ingest 용도로 잔존.

  • 2026-05-03 P9 도그푸딩 후속 (p9-fb-17) — Multi-turn chat session 영속화 (storage 만 — UI 는 p9-fb-18). SQLite V005 migration (spec 의 V004 가 p9-fb-19 의 kv 와 충돌해서 V005 로 시프트, HOTFIXES) 으로 chat_sessions (session_id PK + created_at + updated_at + title + config_snapshot_json) + chat_turns (turn_id PK + session_id FK ON DELETE CASCADE + turn_index + question + answer + citations_json + created_at, UNIQUE(session_id, turn_index)) + idx_chat_turns_session 추가. kebab_core::ChatSessionRepo trait 6 메서드 (create_session / get_session / list_sessions / delete_session / append_turn / list_turns) + kebab_core::{ChatSessionRow, ChatTurnRow} 신규 export. kebab-store-sqlite::SqliteStore impl (별 chat_sessions.rs 모듈) — append_turn 이 insert + parent updated_at bump 을 같은 conn 에서 처리. frozen design §5 storage 에 §5.7a chat_sessions/turns 절 신설. spec: tasks/p9/p9-fb-17-chat-session-storage.md. unblocks p9-fb-18 (CLI session/repl).

  • 2026-05-03 P9 도그푸딩 후속 (p9-fb-18) — CLI kebab ask --session <id> (multi-turn). p9-fb-17 의 ChatSessionRepo 위에 kebab-app::App::ask_with_session(session_id, query, opts) -> Answer 메서드. 첫 호출 시 자동으로 chat_sessions row 생성 (title = 첫 question NFC trim 40 chars), 이후 호출은 list_turns 로 prior history 받아 RagPipeline::ask_with_history 호출 + 새 turn append. App 의 helper: first_question_title(question) (NFC + trim + 40 char cap, fallback "untitled") + blake3_truncate(input) (32-hex turn_id 생성). facade kebab_app::ask_with_session_with_config + CLI --session <id> flag 추가. --repl 은 spec 명시 사항이지만 stdin loop fixture 부담 으로 후속 task 로 deferral (out of scope per HANDOFF). spec: tasks/p9/p9-fb-18-cli-ask-session-repl.md.

  • 2026-05-04 P9 post-도그푸딩 (p9-fb-23) — Incremental ingest. 사용자 도그푸딩 피드백: 변하지 않은 문서는 다시 ingest 하지 않기. blake3 checksum + parser_version + chunker_version + embedding_version 4개 input 이 모두 일치할 때 parse/chunk/embed/vector upsert 모두 회피. SQLite V006 마이그레이션 — documentslast_chunker_version + last_embedding_version 컬럼 추가. 신규 IngestItemKind::Unchanged variant + IngestReport.unchanged + AggregateCounts.unchanged (wire schema additive). IngestOpts { progress, cancel, force_reingest } struct 도입 — AskOpts 패턴. --force-reingest CLI flag 로 skip 우회. 비용 dominator (fastembed) 가 변경된 / 새 doc 에만 발생. spec: tasks/p9/p9-fb-23-incremental-ingest.md. HOTFIXES 2026-05-04 — p9-fb-23 항목이 version cascade 명시 동작의 source of truth.

  • 2026-05-05 P9 post-도그푸딩 (p9-fb-25) — Config 의 workspace.include 필드 제거 + 지원 형식 가시성. 사용자 도그푸딩 피드백: include + exclude 동시 존재가 case 4 (둘 다 매치 안 함) 의미 모호 + 어차피 처리 가능 형식 (md / png / jpg / pdf) 이 정해져 있으니 명시 필요. WorkspaceCfg.include 제거 (옛 config 의 include = [...] 은 silently 무시 + 단발 deprecation warning). IngestItem.warnings 가 Skipped 시 사유 ("unsupported media type: .docx" 등) 채움. IngestReport.skipped_by_extension: BTreeMap<String, u32> 신규 (additive wire — release 트리거 안 됨). CLI / TUI summary 에 breakdown 표시 ("5 skipped: 3 docx, 1 txt, 1 epub"). README + kebab init 헤더 주석에 지원 형식 명시. spec: tasks/p9/p9-fb-25-config-include-removal.md. HOTFIXES 2026-05-05 — p9-fb-25 가 source of truth.

  • 2026-05-04 P9 post-도그푸딩 (p9-fb-22) — TUI 입력 cursor mid-string 편집 + Ask follow-tail auto-scroll. Gitea #94 (입력 후 커서 이동 안 됨) + #95 (새 응답 자동 스크롤 안 됨) 두 건. InputBuffer 의 cursor 모델을 byte-position 기반으로 재구성 — cursor 가 끝일 때 기존 append 동작과 backwards-compatible, mid-string 일 때는 ←/→/Home/End/Delete 로 편집. AskStatefollow_tail: bool (default true). Paragraph::line_count(width) (ratatui unstable-rendered-line-info feature 활성화) 로 매 프레임 wrapped row 수 계산해 follow-tail 시 scroll 을 bottom 에 pin. j/k 가 follow-tail 끄고 Shift-G 가 다시 켬. 12 신규 InputBuffer unit + 6 신규 Ask integration. spec: tasks/p9/p9-fb-22-tui-cursor-and-autoscroll.md. HOTFIXES 항목 2026-05-04 가 live cursor 모델 source of truth.

  • 2026-05-03 P9 post-도그푸딩 (p9-fb-21)i 가 universal Normal→Insert toggle (모든 pane). 이전 mode_intercept 는 Library/Inspect/Jobs 만 i intercept 였고 Search/Ask 는 fall-through (자동 INSERT 가정). 사용자가 Esc 로 NORMAL 로 빠진 후 Insert 복귀 키 없어 dead-end → 도그푸딩에서 보고됨. mode_intercept 의 (Char('i'), Normal, _) arm 이 pane 무관 모두 INSERT flip. Search 의 chunk inspect 키 io rebind (vim "open") 으로 충돌 해소. footer hint 모든 (pane, mode, filter) 조합 첫 fragment = F1 도움말 (cheatsheet binding discoverability). Search/Ask Normal hint 에 i 입력모드 fragment 추가. cheatsheet popup Global/Search/Ask section 갱신. 6 신규 unit + 3 기존 갱신. spec: tasks/p9/p9-fb-21-tui-insert-key-discoverability.md (status completed 직접). HOTFIXES 항목이 Search io rebind 의 source of truth.

  • 2026-05-07 P9 post-도그푸딩 (p9-fb-27)kebab schema [--json] introspection 명령 + error.v1 wire 도입. 정적 (wire schemas / capabilities / models) + 동적 (stats) 한 번에. --json 모드에서 fatal error 가 stderr ndjson 으로 emit (비 --json 은 기존 stderr text 유지). exit code 0/1/2/3 unchanged — error.v1.code 가 fine-grained 분기. fb-30 MCP initialize capability matrix 의 prerequisite. spec: tasks/p9/p9-fb-27-introspection-and-error-wire.md. design: docs/superpowers/specs/2026-05-07-p9-fb-27-introspection-and-error-wire-design.md.

  • 2026-05-03 P9 도그푸딩 피드백 20/20 tasks/p9/p9-fb-01..20 모든 spec status completed. 사용자가 kebab 직접 돌려서 수집한 UX 잡음 (ingest 진행 표시 부재, mode 혼란, CJK column drift, multi-turn 부재, citation 부재 등) 이 모두 코드 또는 spec-acknowledged-deferred 형태로 해소. 도그푸딩 사이클 한 바퀴 완성 — P9-5 desktop tauri 와 별개로 TUI/CLI 사용자 경험 측면은 한 단계 안정화. P9 phase row 는 P9-5 미진행이라 🟡 유지.

다음 task 후보

구조적으로 미완인 component 는 P9-5 하나뿐. 나머지는 도그푸딩 follow-up (아래 "P10 dogfooding 백로그") 또는 사용자 결정 대기.

  • P9-5 desktop tauri — 마지막 남은 P9 component. kebab-desktop crate + Tauri 앱, 별도 분기. PDF citation rendering UI 가치 큼. 사용자 우선순위 (P9 우선 · 책/PDF 위주) 와 부합.
  • P10 도그푸딩 round 2 follow-up v0.17.0 cut (2026-05-24) 으로 세 항목 모두 closure (한국어 trigram PR-A + C typedef alias PR-B + code_lang_chunk_breakdown additive PR-C). 상세 cross-link: 아래 "P10 dogfooding 백로그" 절 + tasks/HOTFIXES.md (2026-05-24 PR-A/B/C).
  • P8 audio brainstorm — whisper-rs 시스템 dep 받을지 / 외부 transcription endpoint 사용할지 사용자 결정 필요. 사용자 패턴 (책+PDF 위주, audio 의향 없음) 상 보류.
  • fb-41 multi-hop reasoning 미구현, XL, eval 인프라 선행 + brainstorm 필요.
  • Rust symbol path retrofit — Rust code-rust-ast-v1 symbol 이 file-scope-only (1B+ 는 module prefix). code-rust-ast-v2 bump + Rust corpus re-ingest 비용 → 사용자 명시 요청까지 보류. HOTFIXES 2026-05-20.

v0.20.0 sub-item 1 (PDF scanned OCR) 머지 후 priorities (2026-05-28, 사용자 결정)

PR #189 (2026-05-28 머지, commit 09333d0) 으로 PDF scanned OCR (qwen2.5vl:3b vision LLM) + 4 round bugfix (#2/#3/#4/#6/#7/#9/#10/#11/#13/#14) + ingest log feature 가 main 으로 진입. 다음 작업 순서 = C → B → A → G.

  • C — 한국어 morphological tokenizer (Bug #8 follow-up) v0.20.1 머지 완료.

    • V007 trigram 의 ≥3 char query 제약 (HOTFIXES 2026-05-22) — '한국' 같은 2-char 한국어 query 0 hit → V009 migration + lindera-ko-dic tokenizer + tokenized_korean_text column + first-boot eager backfill 으로 해소. branch feat/korean-morphological-tokenizer (8 commit + 5 follow-up).
    • scope: search index 재빌드 cascade (corpus_revision bump) + V007 trigram 보존 (backward-compat).
    • 사용자 surface: kebab search 의 한국어 2자 query ('한국', '서울') 매칭. README + SKILL + release notes 반영.
  • B — OCR dense page coverage C 다음.

    • metro-korea.pdf page 8/13 timeout (180s, dense newspaper article). vision LLM 의 output token 과대 → 정상 timeout.
    • 가능한 path: (a) per-page max_pixels 동적 조정 (high-resolution page 만 축소), (b) column-level sub-region OCR (newspaper layout 분할 후 OCR call 분리), (c) model upgrade (qwen2.5vl:7b — Ollama 모델 변경 + max_pixels trade-off), (d) OCR timeout 점진 축소 (180s → 120s → 90s) — round 마다 p90 측정 후.
    • mojibake.pdf pdf_ocr_pages: 0 (round 1 부터 동일) — text-detect path fallback 강화 검토.
    • 별 sub-item.
  • A — v0.20 의 deferred sub-items (frozen design contract) B 다음.

    • sub-item 2 — Multi-region image dispatch (OcrText.regions bbox 분리) — image OCR + PDF column-aware OCR.
    • sub-item 3 — PDF normalize integration (ParsedPdfPage production caller + build_canonical_document_from_pdf_pages + cross-page reference graph).
    • TODO #4 — Per-page image / table extraction (PDF figure / table extract).
    • TODO #5 — Enricher trait 도입 — OCR + caption 의 Extractor trait 통합 (post-extract enrichment 의 generalization).
    • 각 sub-item 별 spec/plan/executor cycle.
  • G — v0.20.1 patch release + release notes A 머지 후 (또는 C/B 시점에 따라 조기 cut).

    • CLAUDE.md release 룰 — sub-item 1 base + bugfix1-4 + log feature + logging r2 누적 → minor surface 변경 다수 + wire schema additive minor + config 신규 → v0.20.1 patch bump + release notes.
    • 핵심 surface (사용자 도그푸딩 가이드 형식):
      • 한국어 2자 query 지원 (kebab search 에서 '한국', '서울' 같은 2자 단어 매칭 — V009 morphological tokenizer).
      • OCR timeout default 180s (HOTFIXES 2026-05-28).
      • [logging] config section (default enabled) + {state_dir}/logs/ingest-{run_id}.ndjson 자동 생성.
      • [logging] keep_recent_runs (100) + retention_days (30) — OR-on-stale cleanup.
      • ingest_progress.v1.pdf_ocr_finished 의 4 추가 field (image_byte_size, image_width, image_height, failure_reason) — image_w/h 가 round 2 (PR #190) 에서 실제 capture.
      • schema.v1.modelsactive_parsers + active_chunkers (additive minor).
      • V008 migration — pdf_ocr_events table (per-OCR-call historical record).
      • 새 wire schemas — ocr_stats.v1 + ocr_failures.v1 (CLI inspect 의 emit).
      • CLI kebab inspect ocr-stats + kebab inspect ocr-failures — sweet-spot 점진 분석.
      • CLI --media code first-class, empty query → invalid_input, --config missing → config_not_found + exit 2.
      • capabilities.streaming_ask + single_file_ingest 가 true (이전 false 거짓 정정).
    • bump 작업: workspace Cargo.toml version → 0.20.1, tag, gitea-release.

v0.20 후속 bug catalog (non-blocking known)

본 PR #189 dogfood 에서 falsified 또는 design constraint 로 분류 — fix 안 함:

  • Bug #8 (V007 trigram 2-char query 한계) → 위 C 항목.
  • Bug #12 (Code block wire .code field, .text 가 아닌 jq fallback artifact) — falsified.
  • ask 한국어 query phrasing-sensitive refusal — RAG corner case / NLI gate behavior. 별도 brainstorm.

Logging feature enhancements — closed (PR #190, 2026-05-28 merged commit 7bbdc89a)

logging round 2 (PR #190) 으로 4 enhancement 모두 closed:

  • image_width + image_height capture (raster JPEG decode).
  • SQLite mirror (V008 pdf_ocr_events table + dual-write).
  • CLI query (kebab inspect ocr-stats + ocr-failuresocr_stats.v1 + ocr_failures.v1 wire schemas).
  • log retention (keep_recent_runs + retention_days — file + SQLite cleanup).

P9 dogfooding 백로그 (fb-26 ~ fb-42) — release 분할

2026-05-06 도그푸딩 누적 피드백 + "AI agent 가 kebab 을 쓰게 한다" 궁극 목표용 surface 확장. cascade 영향 / 분량 고려해 한 minor 에 묶지 않고 분할.

  • 0.3.0 — agent foundation cut 2026-05-07: fb-26 (log), fb-27 (introspection/error wire), fb-28 (readonly/quiet). fb-29 (daemon)🚫 deferred — fb-30 stdio MCP 가 동일 가치를 daemon 복잡도 없이 제공.
  • 0.4.0 — agent integration (MCP) cut: fb-30 (MCP stdio), fb-31 (single-file/stdin ingest).
  • 0.5.0 — agent surface refinement (additive) cut 2026-05-10: fb-32 (stale doc indicator), fb-33 (streaming ask), fb-34 (output budget controls), fb-35 (verbatim fetch), fb-36 (search filter args), fb-37 (trace + stats). 모두 wire schema additive minor.
  • 0.6.0 — RAG quality 대부분 머지 (2026-05-10): fb-38 (score semantics) , fb-39 (eval foundation — precision_at_k_chunk metric) , fb-39b (embedding upgrade — multilingual-e5-large default) , fb-40 (fact-grounded answer / rag-v2 prompt) . 잔여 = fb-39 의 retrieval precision lever 실제 적용 (eval golden set 확장 선행 필요).
  • 0.7.0 또는 P+: fb-41 (multi-hop reasoning, XL) — 미구현 · brainstorm 필요; fb-42 (bulk multi-query) 머지 (2026-05-10, bulk only — rerank hint 은 deferred).

각 fb spec frontmatter 의 target_version 필드가 source of truth. INDEX.md 의 release subheader 도 동일 grouping.

P10 dogfooding 백로그 (2026-05-22 round 2)

P10 종합 도그푸딩 round 2 (/build/cache/dogfood-p10b/, OSS 8 repo + 한국어 위키 문서 10편) 에서 발견된 follow-up 후보. 자세한 내용 + 우선순위 근거는 tasks/HOTFIXES.md (2026-05-22).

  • 한국어 lexical tokenizer v0.17.0 (2026-05-24) PR-A 머지 (#159). V007 trigram migration 자동 backfill + build_match_string 재설계 + CLI/TUI/wire hint. HOTFIXES 2026-05-24 PR-A 참조.
  • code_lang_chunk_breakdown chunk 단위 집계 (LOW) v0.17.0 (2026-05-24) PR-C 머지 (#161). schema.v1.stats additive 필드. HOTFIXES 2026-05-24 PR-C 참조.
  • C typedef-wrapped struct (LOW) v0.17.0 (2026-05-24) PR-B 머지 (#160). type_definition 분기 + PARSER_VERSION code-c-v2 bump + orphan purge cascade. HOTFIXES 2026-05-24 PR-B 참조.
  • ranking glue chunk 편향 (deferred) — 자동 heuristic 은 user intent misalignment 위험. 사용자 명시 요청 전까지 surface 변경 0 유지. 1주+ 실사용 후 재 brainstorm.

검증된 운영 동작 (release binary, fastembed enabled)

P7-3 머지 직후 25 시나리오 smoke 통과 — markdown + image + PDF 5 자산 워크스페이스에서 doctor / ingest / list / inspect / search (lex/vec/hybrid) / re-ingest / byte-edit re-ingest / corrupt PDF / RAG ask + page citation 모두. 자세한 시나리오 표는 conversation 기록 참조; 워크스페이스에 직접 돌려보는 절차는 docs/SMOKE.md.