From 6bf4e82e62c28e759e44ec6bc579319cdfb7648f Mon Sep 17 00:00:00 2001 From: altair823 Date: Thu, 28 May 2026 19:40:10 +0000 Subject: [PATCH] docs(handoff): v0.20.1 full dogfood findings todo for next session MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 머지 후 v0.20.1 의 full dogfood (사용자 실제 corpus 6293 file, 3.5 시간 ingest, §1~§11 시나리오) 발견된 findings 를 새 session 의 self- contained todo handoff 로 정리. P0 (bug / 의도와 다른 동작): - #1 Ask 영어 query → 한국어 응답 (rag-v2 prompt template 강제) - #2 bulk search input format 불명확 (wire schema 미명시) - #3 list docs title 중복 (heading-based, doc_path 보조 필요) - #4 doc.lang = und 53% (code file 의 lang detection 실패) P1 (docs drift): - #5 fusion_score 위치 (.retrieval.fusion_score) - #6 score_kind="bm25" 의미 (lexical mode 의 fusion_score) - #7 schema index_version vs lexical_index_version 혼동 P2 (setup): - #8 Ollama endpoint default 가 localhost (사용자 환경 remote) 각 todo 별 severity, scenario, suspected location, action item 명시. 새 session 시작 명령 + branch 권장 + 도그푸딩 재실행 절차 + finding cumulative table 포함. Repo state: main HEAD=a0c7fa3, clean. v0.20.1 binary OK. /build/dogfood/ KB (3940 docs, 34896 chunks) preserved for regression test. --- ...28-v0.20.1-fulldogfood-findings-handoff.md | 272 ++++++++++++++++++ 1 file changed, 272 insertions(+) create mode 100644 docs/superpowers/handoffs/2026-05-28-v0.20.1-fulldogfood-findings-handoff.md diff --git a/docs/superpowers/handoffs/2026-05-28-v0.20.1-fulldogfood-findings-handoff.md b/docs/superpowers/handoffs/2026-05-28-v0.20.1-fulldogfood-findings-handoff.md new file mode 100644 index 0000000..0f8ccbe --- /dev/null +++ b/docs/superpowers/handoffs/2026-05-28-v0.20.1-fulldogfood-findings-handoff.md @@ -0,0 +1,272 @@ +--- +title: v0.20.1 full dogfood findings — todo handoff +created: 2026-05-28 +source_session: 2026-05-28 (v0.20.1 머지 + dogfood data consolidation + 전체 도그푸딩) +target_branch_candidate: fix/v0.20.2-dogfood-findings (가칭) +priority: dogfood 단계 발견 findings 의 fix / docs / behavior 검토 +--- + +# 다음 session handoff — v0.20.1 전체 도그푸딩 finding 정리 + +새 session 이 픽업해서 이어 작업할 todo. 사용자 실제 corpus (`/build/dogfood/corpus`, 6293 file) 의 fresh ingest + §1~§11 도그푸딩 결과 finding 들 정리. + +--- + +## 0. Repo + 환경 state (handoff 시점) + +- **working directory**: `/home/altair823/kebab` +- **branch**: `main` (HEAD `a0c7fa3` — dogfood 보관소 정책 commit) +- **가장 최근 머지**: PR #191 (`ebc6bf4` — V009 한국어 morphological tokenizer + N-gram supplement + eager backfill, v0.20.1). +- **env**: `export CARGO_TARGET_DIR=/build/out/cargo-target/target` +- **fresh release binary**: `/build/out/cargo-target/target/release/kebab` (v0.20.1, N-gram supplement 포함). +- **workspace test pass + clippy clean + fmt clean** (이전 session 확인됨). + +도그푸딩 data 보관소 (CLAUDE.md `## Dogfood trigger` 정책 따라): +- `/build/dogfood/corpus/` — 6293 source file, format/category 별 분류 +- `/build/dogfood/kb/` — fresh full ingest 결과 (3940 docs, 34896 chunks, 3.4G) +- `/build/dogfood/config.toml` — canonical config (Ollama remote 192.168.0.47 endpoint 패치됨) +- `/build/dogfood/logs/full-dogfood-20260528_144512.{ingest-json,ingest-stderr}` — 도그푸딩 로그 +- `/build/dogfood/_archive/` — 이전 KB state + XDG snapshot (regeneratable, wipe 가능) + +--- + +## 1. 발견된 todo (severity + priority) + +### 🐛 P0 — bug 또는 사용자 expectation 과 다른 동작 + +#### Todo #1: Ask 영어 query 의 응답이 한국어 (Finding O) + +- **Severity**: medium +- **Scenario**: `kebab ask 'What is RAG architecture?' --mode hybrid` +- **Observed**: 답변이 `"RAG는 ... 정의됩니다 [#1]"` (한국어) +- **Expected**: 답변이 input query 의 언어 (영어) 와 매칭 +- **Suspected cause**: `prompt_template_version: rag-v2` 가 응답 언어를 한국어로 강제. `crates/kebab-rag/` 의 prompt template 또는 system message 검토 필요. +- **Action**: + 1. `crates/kebab-rag/src/prompt.rs` (또는 등가 location) 의 system prompt 확인. + 2. Input query 의 language detection (`kebab-core` 의 lang detection 모듈) → response language 매칭 옵션 또는 default 변경. + 3. 한국어 user 의 default 한국어 응답 유지 + 영어 user 의 영어 응답 보장. +- **Test scenario**: handoff 시점의 `/build/dogfood/kb/` 에서 `kebab ask 'What is RAG?' --hide-citations` 응답 언어 영어 확인. + +#### Todo #2: bulk search input format 불명확 (Finding V) + +- **Severity**: medium (docs + wire schema) +- **Scenario**: + ```bash + echo '{"text":"한국","mode":"lexical","k":3}' | kebab search --bulk --json + echo '{"query":{"text":"한국","mode":"lexical","k":3}}' | kebab search --bulk --json + ``` +- **Observed**: 둘 다 `error.v1 invalid_input: "missing required field: query"`. +- **Expected**: bulk input 의 정확한 JSON shape 가 명확. +- **Suspected location**: `crates/kebab-cli/src/bulk_search.rs` (또는 등가) 의 ndjson parser. `bulk_search_item.v1.schema.json` 의 input schema 부재. +- **Action**: + 1. `docs/wire-schema/v1/bulk_search_item.schema.json` 의 input shape 명시 (가능하면 별 `bulk_search_input.schema.json`). + 2. `kebab search --bulk --help` 의 example 추가 (`echo '...' | kebab search --bulk`). + 3. `docs/DOGFOOD.md` 의 bulk scenario 예시 갱신. + 4. 가능하면 error 메시지에 expected shape hint 추가. + +#### Todo #3: list docs 의 title 중복 (Finding Q) + +- **Severity**: low (UX) +- **Scenario**: `kebab list docs --json | jq '.[0:5]'` +- **Observed**: 여러 다른 file 이 `title: "Registry"`, `title: "dispatch"` 등 동일 title 로 반환 — heading-based title 추출이 unique 안 됨. +- **Expected**: 사용자가 list 만 보고 어느 file 인지 식별 가능. +- **Action**: + 1. `crates/kebab-cli/src/commands/list.rs` (또는 등가) 의 human-readable 출력에 `doc_path` 표시 (현재 JSON 에만 노출). + 2. 또는 title 의 unique 화 (`"Registry — Registry.java"` 처럼 file basename 추가). + 3. README 의 `kebab list docs` 동작 명세 갱신. + +#### Todo #4: doc.lang = "und" 53% (Finding U) + +- **Severity**: low (UX + accuracy) +- **Scenario**: `kebab schema --json | jq '.stats.lang_breakdown'` → `{en: 1358, ko: 89, und: 2493}` +- **Observed**: Java/Kotlin/C++ 등 code file 에서 자연 언어 감지 실패율 53%. +- **Expected**: code file 의 source language (예: `lang: "rust"`, `lang: "python"`) 를 우선 사용하거나, code chunk 의 comment 만 추출해서 lang 감지. +- **Action**: + 1. `crates/kebab-core/src/lang.rs` (또는 등가) 의 lang detection 의 doc 적용 위치 확인. + 2. Code chunk 의 `code_lang` 이 이미 정확 (rust, python, typescript 등) — `doc.lang` 도 code 의 source language fallback 권장. + 3. 자연 언어 doc.lang 의 의미 명확화 — code file 의 doc.lang 은 source code lang vs comment NL 중 어느 것? + +### ⚠ P1 — Documentation drift + +#### Todo #5: fusion_score 위치 표기 (Finding H/L) + +- **Severity**: low +- **Scenario**: README 의 wire schema 예시 +- **Observed**: README 의 `fusion_score` 가 top-level 같이 표기되어 있으나, 실제 wire schema 의 `.retrieval.fusion_score`. +- **Action**: + 1. `README.md`, `docs/wire-schema/v1/search_hit.schema.json` 확인. + 2. README 의 search response 예시 갱신 — `.retrieval.{fusion_score, lexical_score, vector_score, lexical_rank, vector_rank}` 구조 명확화. + 3. `score` (top-level) vs `retrieval.fusion_score` (nested) 의 의미 차이 명시. + +#### Todo #6: score_kind="bm25" 의 의미 (Finding X) + +- **Severity**: low +- **Scenario**: `kebab search --mode lexical 'tokenizer'` → `score_kind: "bm25", score: 0.943, fusion_score: 0.943, lexical_score: 0.943` +- **Observed**: lexical mode 에서 `fusion_score == lexical_score == score` 동일. +- **Expected**: `fusion_score` 는 hybrid 전용임이 docs 에 명확. +- **Action**: README + wire schema docs 에 `fusion_score` 의 mode 별 의미 명시 (lexical/vector 에서는 single-mode score 와 동일, hybrid 에서는 RRF normalized). + +#### Todo #7: schema --json 의 index_version vs lexical_index_version (Finding G) + +- **Severity**: low +- **Observed**: `kebab schema --json | jq '.models.index_version'` → `"v1"` (wire schema 의 v1) +- **Expected**: `lexical_index_version` (`fts5-v009-korean-morphological`) 가 별도 필드. 두 의미 다름 — 사용자 혼동 가능. +- **Action**: `schema.v1` JSON 의 `index_version` 이름 또는 documentation 변경. 가능 옵션: + 1. `wire_schema_version: "v1"` + `lexical_index_version: "fts5-v009-..."` 로 rename + 2. 현재 이름 보존 + README 에 명시 +- 이미 `lexical_index_version` 은 search hit 의 `index_version` field 로 노출됨 — schema 의 top-level `index_version` 과 의미가 같지 않다는 점 documentation 화 필요. + +### 💡 P2 — Setup gap (config default) + +#### Todo #8: Ollama endpoint default 가 localhost (Finding M) + +- **Severity**: low (setup) +- **Scenario**: `kebab init` 의 default `config.toml` +- **Observed**: `endpoint = "http://127.0.0.1:11434"` (localhost) +- **Expected**: 사용자 environment 가 remote ollama (192.168.0.47) 인 경우 init 후 수동 갱신 필요. +- **Action**: + - localhost default 유지 (대부분 사용자 setup 와 일치) + - `kebab init` 의 hint 메시지에 "remote Ollama 사용 시 endpoint 갱신 필요" 안내 추가. + - 또는 `KEBAB_OLLAMA_ENDPOINT` 같은 env var 지원으로 override 편의 추가. + +### ✅ P3 — 검증된 정상 동작 (fix 불필요) + +다음은 이미 정상이며 finding 으로 분류되지 않음 (regression 방지 목적의 reference): + +- §1 Ingest: 6275 scanned (.git/ 자동 제외), 3940 new, 2335 skipped (확장자 미지원 — html/output/sample 등 의도), 0 errors, 3시간 30분 완료. +- §2.1 Lexical: 한국어 2-char 모두 hit (한국 10, 서울 6, 지하철 5, 대한민국 4), N-gram supplement 정상 (동아시아 → [동아, 아시, 시아]). +- §2.2 Vector + §2.3 Hybrid: fusion_score 0.984, lexical_score + vector_score 분리. +- §3 Ask: 한국어 RAG + 거절 동작 + citation 정상. +- §4 Inspect chunk: `text`, `tokenized_korean_text`, `heading_path`, `chunker_version` 모두 정상 노출. +- §4 Fetch chunk: kind=chunk, target.text 가 `.chunk.text` 구조. +- §5 Version cascade: corpus_revision=2 (V004 seed 0 + V009 +1 + ingest +1). +- §6 Wire schema: search_response.v1, search_hit.v1, fetch_result.v1, error.v1. +- §11 Edge cases: + - Empty query → error.v1 (`invalid_input`). + - 1-char Korean → 0 hits (MIN_QUERY_CHARS=2 filter). + - Long query (300 char) → 2 hits, no error. + - Special chars `token!@#$%` → 10 hits (FTS5 가 punct 무시). + - Korean + punct `'한국, 형태소!'` → 3 hits. +- p9-fb-32 stale doc indicator 정상 (`indexed_at`, `stale=false`). +- p9-fb-34 cursor pagination 정상 (`next_cursor` base64 `{offset, corpus_revision}`). +- p9-fb-36 filter (`--code-lang rust`, `--media code`) 정상. +- p9-fb-37 trace 정상 (`lexical_ms / vector_ms / fusion_ms / total_ms`). +- p9-fb-38 score_kind 정상. +- p9-fb-19 --no-cache 정상. + +--- + +## 2. 권장 새 session 의 첫 step + +### 2.1 작업 시작 명령 + +새 session 에서: + +``` +@/home/altair823/kebab/docs/superpowers/handoffs/2026-05-28-v0.20.1-fulldogfood-findings-handoff.md +``` + +### 2.2 우선 순위 + 작업 흐름 + +권장 순서 (P0 → P1 → P2): + +1. **Todo #2 (bulk search input)** — wire schema + help docs 빠른 정리 (S spec 없이 small fix PR 가능). +2. **Todo #1 (Ask 영어 응답 한국어)** — rag prompt template 의 system message 갱신. 별 spec/plan 필요할 수 있음 (사용자 expectation 변경). +3. **Todo #3 (list docs title 중복)** — UX 작은 fix. +4. **Todo #4 (lang=und 53%)** — 의미 명확화 + code lang fallback. 별 spec. +5. **Todo #5/#6/#7** — README + wire schema docs 한 PR 으로 묶어 정리. +6. **Todo #8** — init hint 메시지 한 줄. + +### 2.3 branch + workflow + +```bash +git checkout -b fix/v0.20.2-dogfood-findings +``` + +또는 finding 별 별 branch (예: `fix/bulk-search-input-shape`, `fix/list-docs-title`). + +전체를 v0.20.2 patch release 로 묶을 경우 single branch. 각 finding 독립적이라 cherry-pick 도 가능. + +`omc team` workflow: +- Small fixes (P1, P3): in-process Agent (sonnet) 로 직접 처리. +- Medium fixes (P0 Todo #1/#2): spec drafter (omc team writer) → plan → subagent-driven-development 권장. + +--- + +## 3. 도그푸딩 재실행 (regression 방지) + +새 finding fix 후 도그푸딩 재실행 절차: + +```bash +DG=/build/dogfood +KB=/build/out/cargo-target/target/release/kebab +CFG=$DG/config.toml + +# Fresh KB (현재 KB 의 corpus_revision=2 상태에서 incremental ingest 도 OK) +# rm -rf $DG/kb && mkdir $DG/kb # 전체 reset 시 + +# 또는 incremental +$KB --config $CFG ingest + +# 발견된 finding 의 regression 시나리오만 다시 실행 +$KB --config $CFG ask 'What is RAG architecture?' --hide-citations # Todo #1 +echo '{"text":"한국","mode":"lexical","k":3}' | $KB --config $CFG search --bulk --json # Todo #2 +$KB --config $CFG list docs --json | jq '.[0:5]' # Todo #3 +$KB --config $CFG schema --json | jq '.stats.lang_breakdown' # Todo #4 +$KB --config $CFG search --mode lexical 'tokenizer' --k 1 --json | jq '.hits[0]' # Todo #5/#6 +$KB --config $CFG schema --json | jq '.models.index_version' # Todo #7 +``` + +--- + +## 4. References + +- 이번 session 의 PR: https://gitea.altair823.xyz/altair823-org/kebab/pulls/191 (머지됨, 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` +- HOTFIXES: `tasks/HOTFIXES.md` 2026-05-28 entry (V009 + N-gram supplement + dogfood evidence) +- Release notes draft: `docs/release-notes/v0.20.1-draft.md` +- CLAUDE.md `## Dogfood trigger` policy section + dogfood 보관소 `/build/dogfood/` +- DOGFOOD scenario catalog: `docs/DOGFOOD.md` + +## 5. 발견 finding 의 cumulative summary table + +| # | Finding | Severity | Category | Target todo | +|---|---|---|---|---| +| A | scan vs corpus 21 file 차이 | none | `.git/` 자동 제외 (의도) | — | +| B | html 1415 skipped (extension) | none | 의도 — html 미지원 | — | +| C | size_exceeded 5 files | none | 의도 — config 의 max_size_kb 제한 | — | +| D | lang_breakdown und=53% | low | UX | #4 | +| E | pdf=8 from ts-zod logos | none | 부산물, 정상 동작 | — | +| F | Korean tokenized 34847/34896 | none | N-gram supplement 정상 | — | +| G | schema index_version="v1" | low | docs | #7 | +| H | fusion_score location | low | docs | #5 | +| I | Korean queries hit | none | V009 closure 확인 | — | +| J | English whole-token regression | none | V009 회귀 정상 | — | +| K | Vector search semantic | none | 정상 | — | +| L | fusion_score location docs | low | docs | #5 | +| M | Ollama endpoint default localhost | low | setup | #8 | +| N | (skipped, M 와 동일) | — | — | — | +| O | Ask 영어 query → 한국어 응답 | medium | behavior | #1 | +| P | fetch chunk target.text path | none | jq query 실수, 실제 정상 | — | +| Q | list docs title duplicate | low | UX | #3 | +| R | Edge case error handling | none | 정상 | — | +| S | jq error in test script | none | 내 query 실수 | — | +| T | Korean + punct OK | none | 정상 | — | +| U | doc.lang = und | low | UX | #4 | +| V | bulk search input shape | medium | docs+schema | #2 | +| W | code-lang filter | none | 정상 | — | +| X | score_kind="bm25" 의미 | low | docs | #6 | + +--- + +## 6. 본 handoff doc 의 path + commit + +이 file: `docs/superpowers/handoffs/2026-05-28-v0.20.1-fulldogfood-findings-handoff.md`. + +새 session 시작 시: +``` +@/home/altair823/kebab/docs/superpowers/handoffs/2026-05-28-v0.20.1-fulldogfood-findings-handoff.md +``` + +또는 본 doc 의 §1 finding list 직접 읽고 priority 따라 진행.