진행 로그 개선은 검색·색인 결과 불변 + 새 명령/플래그/config 없음 + additive-only
wire(asset_phase)라 CLAUDE.md 신규 규칙(기능/인터페이스 변경=minor, 없으면 patch)상
patch 가 맞음. version·라벨·HOTFIXES 헤더를 0.26.1 로 정정.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
별칭을 줄별 개별 dense 벡터(sentinel `{chunk}#alias#N`)로 색인하고
boilerplate 청크는 별칭 생성을 skip. 묶음 1벡터 방식은 평균화로 특정
표현이 희석돼 오히려 회귀(13/18)했던 것을 폐기. 변형 일관성 14/18 →
16/18, mean_spread@10 0.222 → 0.111 (나무위키 ~1000 문서 CS corpus).
`kebab-core::strip_alias_suffix` 가 suffix 형과 per-alias 형 둘 다 처리.
파생물 캐시(V012): embedding 벡터 + 별칭 LLM 결과를 청크 내용 해시
키로 캐싱해 재색인 시 내용 불변 청크의 재계산을 skip. cache_key =
blake3(kind ‖ text_blake3 ‖ version_key)[:32], version_key 에
model/prompt/dimensions 포함 → §9 cascade 와 정합(버전 bump 시 자동
miss). 측정: 정답 3개 cold 1879s → warm 13s ≈ 145배. 순수 가산이라
corpus_revision bump 없음. search/ask 는 kebab.sqlite+lancedb 만으로
동작 → 외부 서버 색인 후 DB 만 복사하는 이식 워크플로 가능.
V012 schema migration + 신규 surface 로 workspace version 0.20.2 →
0.21.0 (minor) bump. README/HANDOFF/ARCHITECTURE/HOTFIXES sync.
known limitation: stack·svm 설명형 2개 잔존 + grounded 판정이 부분
인용을 grounded 로 오분류(후속 후보).
측정 상세: docs/superpowers/handoffs/2026-05-31-namu-wiki-alias-cache-study.md
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CLAUDE.md docs-split 규칙에 따라 사용자 visible surface 변경 동기화.
README:
- [rag] prompt_template_version default rag-v2 → rag-v3 (v0.20.2)
- v3 규칙 설명 (답변 언어 = 질문 언어)
- O-2 known limitation (소형 모델 refusal 언어 불일치)
HANDOFF:
- 머지 후 발견된 버그/결정 에 v0.20.2 1줄 요약 추가
- 검색 품질 baseline (hybrid MRR=0.833) + O-2 known limitation 언급
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>
PR #190 (2026-05-28 commit 7bbdc89a) merge 후:
- "Logging feature future enhancements" section → ✅ closed (4 enhancement 모두 PR #190 에서 ship).
- G (v0.20.1 release) section 의 release notes scope 갱신 — V008 migration + pdf_ocr_events + CLI inspect + retention 추가.
다음 작업 priorities 그대로 C → B → A → G.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
v0.18.0 cut PR. fb-41 multi-hop RAG + NLI verification 의 user-visible surface (PR #176-180) + post-PR9 cleanup/refactor (PR #181) ship 마무리.
## 변경 사항
### Version
- workspace `Cargo.toml`: 0.17.2 → 0.18.0. Cargo.lock 자동 cascade (24 kebab-* crate 모두 0.18.0).
### Frozen design contract
- `docs/superpowers/specs/2026-04-27-kebab-final-form-design.md`:
- §3.8 RAG types — RefusalReason 에 NliVerificationFailed + NliModelUnavailable + MultiHopDecomposeFailed 추가 + Multi-hop RAG + NLI verification 의 ask_multi_hop facade + step 8.5 NLI hook + HopRecord / VerificationSummary 명시.
- §9 versioning rules 표 — nli_model_version row 신규 (선택 — v0.19+ second adapter 시 wire surface candidate).
### Status transitions
- `docs/superpowers/specs/2026-05-25-p9-fb-41-finalize-spec.md`: status approved-by-team → completed.
- `docs/superpowers/plans/2026-05-25-p9-fb-41-finalize-plan.md`: status approved-by-team → completed (spec_status 도).
### User-facing docs
- `README.md`: 명령 표의 `kebab ask` row 에 `--multi-hop` flag + NLI 옵션 안내 한 단락 (mDeBERTa-v3 XNLI 280 MB 자동 다운로드 / RAM peak ~7-8 GB / threshold tuning 0.5 prod / 0.0 disable).
- `docs/SMOKE.md`: `[rag] nli_threshold = 0.0` config 예시 + 활성화 절차 + first-run download + RAM 권장 inline 안내.
### Handoff + dashboard
- `HANDOFF.md`: 한 줄 요약 의 현재 version 0.17.2 → 0.18.0. v0.18.0 cut entry 추가 (fb-41 multi-hop + NLI + cleanup ship). Component 카운트 단락에 fb-41 PR-9 의 kebab-nli + ask_multi_hop 추가 명시. 머지 후 결정 절 맨 위에 v0.18.0 fb-41 entry 신규.
- `tasks/INDEX.md`: p9-fb-41 ⏳ → ✅ 머지 (v0.18.0). v0.18.0 subsection 신규 — PR #176-181 의 6 sub-PR + cleanup 각 한 줄 요약.
## 비범위 / 별 작업
- HOTFIXES.md 의 fb-41 entry 는 이미 PR #180 (PR-9d closure) 에서 작성 완료 — 본 cut PR 에서 추가 anchor 불필요.
- SKILL.md 의 v0.18+ NLI 안내는 이미 PR-9c-2 에서 inline 추가 완료.
## 검증
- `cargo check --workspace -j 1` 통과 (모든 24 crate v0.18.0 확인).
- frozen design 의 RefusalReason enum 확장이 kebab-core 의 production code 와 정합 (PR-9c-1 시점부터 동일 variants 있음).
Wire 영향: 없음 (additive minor 는 PR-9c-1 에서 이미 ship, 본 commit 은 documentation cascade only).
Behavior 영향: 없음.
머지 후 `gitea-release v0.18.0` 으로 tag + release notes 작성.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
v0.17.1 post-dogfood polish cut. 두 PR 묶어 release:
- PR #164 — `[image.ocr] request_timeout_secs` 별 노브 (v0.17.1
미진행 closure). LLM 패턴을 OCR 어댑터에 동일 적용, 별 노브로
분리 (OCR vs LLM 의 cold start 패턴 차이로 독립 조절).
- PR #165 — `heading_path` FTS5 column filter 로 text-only 매칭
+ raw-mode escape hatch (2026-05-24 v0.17.0 trigram entry 의
JSON 노이즈 closure). lexical.rs 가 non-raw 분기 결과를
`text : (<expr>)` 로 wrap, 색인 자체는 V007 verbatim 그대로
유지. raw mode `'heading_path : <token>'` 로 opt-in 가능.
둘 다 additive (옛 config 호환) + re-ingest 불필요. binary 교체만.
HANDOFF 한 줄 요약 + 머지 후 결정 절에 v0.17.2 entry 추가.
HOTFIXES 의 두 entry anchor 가 `post-v0.17.1 dogfood` → `v0.17.2`
로 갱신.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- HANDOFF 한 줄 요약 v0.17.0 → v0.17.1 + release URL 추가
(v0.17.1 cut: PR #162 + #163 한 묶음 안내).
- 머지 후 발견 deviation 절: 2026-05-25 v0.17.1 entry 추가.
- INDEX P10 Dogfooding Feedback section 하단에 'v0.17.1
post-dogfood polish' subsection 추가 (PR #162, #163 각 한 줄).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- 한 줄 요약 v0.16.1 → v0.17.0 + release notes URL + PR-A/B/C
한 줄 요약.
- 머지 후 발견 deviation 절: PR-A 외 PR-B / PR-C 의 2026-05-24
closure entry 추가.
- '다음 task 후보' 의 P10 round 2 follow-up 라인: 세 항목 모두
v0.17.0 closure 표시.
- 'P10 dogfooding 백로그' 의 chunk_breakdown + C typedef 두
항목도 ✅ v0.17.0 closure.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- HOTFIXES: 새 2026-05-24 절 — v0.17.0 closure 영향 (한국어
lexical 3-gram, 영어 substring 변경, BM25 분포, 디스크 용량,
heading_path JSON 노이즈 관찰). 기존 2026-05-22 한국어 lexical
항목의 Status / Next step 을 closure 표현으로 갱신.
- HANDOFF: 머지 후 발견 deviation 절에 2026-05-24 entry +
기존 2026-05-22 항목을 closure cross-link 로 정리. P10
백로그 한국어 tokenizer 항목 ✅ v0.17.0 + "다음 task 후보"
follow-up 라인의 상태 갱신.
- README: 검색 명령 행에 trigram 동작 + hint + 디스크 용량 한 줄.
- SMOKE: 새 "한국어 trigram 검색 (v0.17.0)" 절 — 도그푸딩 query
시퀀스 (충돌은 raw / 해시 충돌 multi-token / Rust 충돌은
mixed / 충돌 2자 + stderr / --json hint 검증) + 영어 substring
동작 변경 안내.
- SKILL.md: search 절에 hint 필드 안내 한 줄 — agent 가
short query 케이스에서 같은 query 재시도 대신 사용자에게
surface 하도록.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- README adds Tier 3 to the ingest row (shell + fallback) and the Mermaid
chunker enumeration; --code-lang shell admitted.
- HANDOFF flips p10-3 to ✅ (v0.15.0) and updates the 한 줄 요약 + next
candidates.
- ARCHITECTURE adds Tier 3 to the code-parser row, extends the flowchart
pcode node, and lists code_text_paragraph_v1.rs in the chunker tree.
- SMOKE adds a P10-3 walkthrough (shell + non-k8s YAML fallback) and a
verification checklist entry.
- tasks/INDEX + tasks/p10/INDEX flip p10-3 to ✅.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
User-visible surface sync per the docs-split rule:
- README adds Tier 2 langs (yaml / dockerfile / toml / json / xml / groovy / go-mod) to the ingest支援 list and --code-lang options.
- HANDOFF flips p10-2 phase row to ✅ (v0.14.0) and updates the next-task candidates.
- ARCHITECTURE extends crates/kebab-chunk/src/ tree with k8s_manifest_resource_v1.rs / dockerfile_file_v1.rs / manifest_file_v1.rs / tier2_shared.rs, plus a Tier 2 note on the code-parser row and flowchart node.
- SMOKE adds a Tier 2 smoke walkthrough (k8s yaml + Dockerfile + Cargo.toml ingest + --code-lang search) and a P10-2 entry in the verification checklist.
- tasks/INDEX + tasks/p10/INDEX flip p10-2 to ✅ (v0.14.0).
Workspace test gate (-j 1) + clippy --workspace pass cleanly.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
회차 1 review 의 4 건 actionable 모두 반영:
1. frozen design §2.1 의 code variant 예시에서 존재하지 않는 `repo` 필드 제거 + nested form 에서 actual wire (flat) 형태로 정리. 5 variant 의 nested-form illustrative example 은 그대로 두고, code variant 만 별도 block 으로 분리해서 actual wire 와 1:1 매칭. 또 위쪽 6 variant nested-form group 에서도 'code' 행 삭제 (정확한 contract 는 별도 block 에 있음).
2. §2.2 SearchHit 예시의 `repo: null, code_lang: null` + 'omitted when null' 주석 모순 제거 — 키 자체를 빼고 inline 주석으로 'markdown hit 에는 absent, 코드 hit 에서만 surface' 설명.
3. HANDOFF Phase row 식별자 `**10**` → `**P10**` (다른 row 와 일관성).
4. README synopsis 의 중복 `[--media code]` 제거 (`--media` 는 이미 위쪽에 한 번 있음, code 는 값 중 하나라 prose 에서 설명).
코드 변경 없음 — 모두 markdown 문서.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
dirs::config_dir() and dirs::data_dir() both return ~/Library/Application Support
on macOS, so data_dir == config parent dir. ResetScope::DataOnly removes data_dir
and silently deletes config.toml along with it.
Fix: bypass dirs crate fallback for config/data/cache dirs; use
$HOME/.config, $HOME/.local/share, $HOME/.cache directly (XDG standard).
xdg_state_dir already used this pattern. dirs::home_dir() still used for
portability.
Migration: Config::load(None) auto-copies legacy ~/Library/Application
Support/kebab/config.toml to the new ~/.config/kebab/ on first run and
prints a migration notice to stderr.
- fb-26 (progress.rs): Fixed Aborted unconditional writeln (TTY duplicate output)
and Completed TTY path missing summary line. Added KEBAB_PROGRESS=plain env
override and quiet field to ProgressMode.
- fb-28 (main.rs): Added --readonly / --quiet global flags with KEBAB_READONLY env.
Readonly blocks mutating commands (ingest/ingest-file/ingest-stdin/reset) with
exit code 1; error.v1 code "readonly_mode" in --json mode. Quiet suppresses all
human progress/hint stderr while preserving errors.
- Updated task spec status for p9-fb-26 and p9-fb-28 to 'merged'.
- Updated tasks/INDEX.md and HANDOFF.md with merge status and summary entries.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- README 명령 표 에 `kebab mcp` 추가 + Claude Code MCP config 예시
- HANDOFF post-도그푸딩 항목 한 줄 (rmcp 1.6 + manual dispatch + error_wire promotion + ask/search spawn_blocking + capability flag flip 명시)
- CLAUDE.md facade 룰 의 UI crate 카테고리 에 `kebab-mcp` 추가
- integrations skill — MCP 사용 안내 (recommended over subprocess)
- design §10.2 MCP transport 절 신설
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 brainstorm 결정 — fb-29 HTTP daemon defer.
근거:
- single-user local-first 환경에서 daemon 복잡도 (PID file / port lock /
single-instance / lifecycle UX / loopback security) 가 비대.
- fb-30 stdio MCP 가 동일 사용자 가치 (agent integration + session 동안
hot cache) 를 daemon 없이 제공 — agent host (Claude Code, Cursor 등)
가 subprocess 띄우면 session 동안 process 유지 = 자연스러운 hot state.
- ask 의 dominant cost 는 Ollama LLM 추론 (수 초) 라 daemon 효과 제한적.
search 만 의미 있는데 그 비용도 fastembed model load (~1s) 가 dominant —
stdio MCP subprocess 가 동일하게 회피.
후속 fb-30 의 transport 는 stdio 단일. HTTP-SSE 옵션은 future task —
재개 trigger:
- browser agent / remote multi-host 시나리오 등장.
- TUI ↔ CLI 다중 인스턴스 state sharing 요구.
- fb-30 MCP HTTP-SSE 변형 도입 검토.
영향:
- fb-29 spec frontmatter `status: open` → `deferred`,
`target_version: 0.3.0` → `P+`, `unblocks: [p9-fb-30]` → `[]`.
- fb-30 `depends_on: [p9-fb-27, p9-fb-29]` → `[p9-fb-27]`.
- INDEX.md 의 0.3.0 group + HANDOFF 의 release 그룹 표 갱신.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- README 명령 표 에 `kebab schema` 추가
- HANDOFF post-도그푸딩 항목 한 줄
- CLAUDE.md wire schema 절 schema.v1 / error.v1 추가
- integrations skill — schema 활용 안내 (additive)
- design §10.1 capability matrix subsection 신설
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- P9 dogfooding 백로그 항목 fb-26 ~ fb-42 추가
- 각 항목의 목표, 증상, 후속 작업 및 위험 요소 명시
- release 계획에 따른 0.3.0 ~ 0.6.0 분할
📝 docs(INDEX): 백로그 항목에 대한 세부 정보 추가
- fb-26 ~ fb-42 항목의 세부 정보 및 상태 추가
- 각 항목의 목표와 후속 작업 명시
- 도그푸딩 피드백에 따른 개선 사항 반영
🔧 chore(tasks): 새로운 백로그 항목 파일 생성
- p9-fb-26 ~ p9-fb-42 각 항목에 대한 개별 파일 생성
- 각 파일에 목표, 증상, 후속 작업 및 위험 요소 포함
- doogfooding 피드백을 기반으로 한 개선 사항 문서화
도그푸딩 중 발견된 두 건 (Gitea #94, #95) 동시 수정.
#94 — `InputBuffer` 가 append-only 라 Ask/Search/Filter overlay 에서
타이핑한 텍스트의 중간을 편집할 수 없었음. cursor 모델을 byte-position
기반으로 재구성 (cursor_col 은 prefix slice 의 unicode-width 합으로
derive). 신규 메서드: `move_left / move_right / move_home / move_end /
delete_after`. 기존 `push_char` / `pop_char` 는 cursor 위치에서 동작
(cursor 가 끝일 때 backwards-compatible). Ask / Search / Library filter
overlay 세 곳에 `← / → / Home / End / Delete` key handler 추가. Search 는
cursor 이동만으로는 input_dirty_at 을 reset 하지 않음 (커서 이동 ≠ 쿼리
변경 → debounce 타이머 유지).
#95 — Ask 트랜스크립트의 `Paragraph::scroll((s.scroll, 0))` 가 위에서
부터 카운트라, 새 답변 도착 시 `s.scroll = 0` 으로 리셋하면 viewport 가
위쪽 고정 → 트랜스크립트가 길어지면 새 응답이 시야 밖으로 밀림. `AskState`
에 `follow_tail: bool` (default true) 추가. `render_answer` 가 follow_tail
동안 매 프레임 `Paragraph::line_count(width)` 로 wrapped row 수 계산해
스크롤을 `line_count - inner_height` 에 pin. `j` / `k` 가 follow_tail 끄고
`Shift-G` 가 다시 켬. 새 submission, `Ctrl-L` 도 follow-tail 재활성화.
`kebab-tui` 의 ratatui dep 에 `unstable-rendered-line-info` feature
활성화 — `Paragraph::line_count` 가 ratatui 0.28 에서 unstable. 0.28 에
pin 되어있는 동안 안정. 향후 ratatui bump 시 본 feature 의 stable 여부
재확인 필요.
cheatsheet popup Search/Ask section 에 화살표 + Home/End + Delete row
추가, Ask 에 `Shift-G` row 추가. README + HANDOFF + HOTFIXES + INDEX 동기.
Tests: 12 신규 InputBuffer unit + 6 신규 Ask integration. 기존 699 워크
스페이스 테스트 모두 통과 (cursor 가 끝일 때 backwards-compat).
Spec: `tasks/p9/p9-fb-22-tui-cursor-and-autoscroll.md` (status `completed`).
Live deviation 기록: `tasks/HOTFIXES.md` `2026-05-04 — p9-fb-22`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
도그푸딩 피드백 (사용자 2026-05-03): Ask Insert→Esc→Normal 후 Insert 로
돌아가는 키 모름. 전반적 키바인딩 안내 부족.
Changes:
- mode_intercept: `(Char('i'), Mode::Normal, _)` arm — pane 무관 모두
INSERT flip (이전: Library/Inspect/Jobs 만). 사용자가 어느 pane 에서든
Esc 후 `i` 로 Insert 즉시 복귀 가능.
- Search 의 chunk inspect 키 `i`→`o` (vim "open") rebind. `i` 가
universal Insert toggle 로 자유로워짐.
- `footer_hints` 모든 (pane, mode, filter) 조합 첫 fragment = `F1 도움말`.
cheatsheet binding 의 discoverability 보장.
- Search/Ask Normal hint 에 `i 입력모드` fragment 추가.
- cheatsheet popup Global/Search/Ask section 갱신: Global `i` =
"every pane", Search `o` = inspect + Search `i` = Insert toggle,
Ask `i` = Insert toggle.
- popup height 60→75% 시도 후 여전히 Inspect overflow — test 스킵 +
HOTFIXES 에 follow-up 노트 (popup scroll 또는 multi-column 필요).
Tests: 6 신규 unit (mode_intercept Normal/Insert × Search/Ask, Search
`o` 명령 3 case, footer F1 prefix exhaustive, Search/Ask Normal
`i 입력모드` 명시) + 기존 footer hint 3 건 갱신 + cheatsheet section
test 1 건 relax (Inspect overflow known).
spec: `tasks/p9/p9-fb-21-tui-insert-key-discoverability.md` (status
`completed` 직접 — 도그푸딩 직접 피드백 source).
`pub fn footer_hints(focus: Pane, mode: Mode, filter_open: bool) -> &'static str`
신규 (run.rs). 기존 `render_footer` 의 영문 `key=action` 형식이 한국어
동사구로 — `"위로"` / `"아래로"` / `"필터"` / `"타이핑 검색어"` /
`"Esc 로 NORMAL 모드"` 등 — 변경되고 (pane, mode, filter_open) 조합에
따라 자동 분기. NORMAL 모드는 navigation verbs, INSERT 모드는
typing + Esc reminder. Library filter overlay 는 overlay-only key 3
개로 override.
8 unit tests pin: 모든 (pane, mode, filter) 조합 non-empty exhaustive
+ Library Normal/filter, Search Normal/Insert, Ask Normal/Insert,
Inspect Normal 별 verb fragment 존재 검증.
spec status `in_progress` → `completed` — p9-fb-13 partial 의 deferred
verb-form 항목이 닫힘.
`kebab-tui::input::{display_width, truncate_to_display_width}` 신규.
unicode-width 위에서 column-단위 width 계산 (ASCII=1, Hangul/CJK/
fullwidth=2, combining=0) + char-boundary 안전 truncate.
library.rs 의 중복 `truncate_to_display_width` private fn 제거 — 단일
source 로 통일. 9 unit tests + 1 integration render test (Korean +
Japanese fixture, TestBackend 80×20).
spec 의 `InputBuffer` struct 도입은 follow-up — Ask/Search/Editor pane
의 String + cursor 일괄 마이그레이션이 회귀 표면이 커서 helper 만
먼저 머지. backspace 는 모든 pane 이 이미 `String::pop()` 사용 → byte-
boundary 안전성 확보. crossterm 0.28 가 native IME composing 미노출 →
preedit handling out of scope.
spec status `planned` → `in_progress`. HOTFIXES.md 에 InputBuffer
struct deferral 사유 기록.
도그푸딩 item 11 — vim 비익숙 사용자도 TUI 조작 가능. F1 으로 cheatsheet
modal popup, 현재 pane 의 키 매핑 + global 토글 (i/Esc/F1) 한 자리.
## 핵심 변경
- **`kebab-tui::cheatsheet::render_cheatsheet(f, area, app)`** 신규 —
70%/60% centered modal. 5 sections (Global / Library / Search / Ask
/ Inspect) 각 pane 의 모든 키 + 동사구 설명. footer 에 현재 focused
pane 명시. theme.style(Role::Heading/CitationMarker/Hint) 으로 색
계층 (header bold, key cyan-marker, body plain, hint dim).
- **`App.cheatsheet_visible: bool`** field + `pub fn cheatsheet_
visible() -> bool` getter (read-only — set/unset 은 F1 intercept
invariant).
- **`cheatsheet_intercept(app, key)`** in run.rs:
- F1 → toggle (open ↔ close), consumed
- Esc 가 visible 일 때 → close, consumed (mode_intercept 가 같은
Esc 를 mode flip 으로 해석하지 않도록 cheatsheet_intercept 가
먼저 dispatch)
- 그 외 키 → fall-through (popup 열린 채 navigation 가능)
- modifier-bearing F1 (Ctrl-F1 등) 무시
- **run loop 통합**: `cheatsheet_intercept` → `mode_intercept` →
pane dispatch 순. render_root 가 error overlay 위에 cheatsheet
overlay (사용자가 error 도중에도 도움말 소환 가능).
## HOTFIXES (`?` → `F1` rebind)
spec 은 `?` 를 trigger 로 명시했지만 Library 가 이미 `Char('?')` 를
quick-Ask binding 으로 사용 중 (handle_key_library line 305). spec 의
`?` 채택 = 기존 binding 깨거나 mode-aware special case 추가. 후자는
mode machine 에 더 많은 분기 추가하므로 회피.
**Live binding**: `F1` (universal help key, no collision).
**Per-pane verb hint line**: spec 의 verb-form hint 재구성도 본 PR
에서 deferral. 기존 `render_footer` 의 pane-별 힌트 문자열이 동일 UX
역할 — 후속 PR 에서 mode-aware verb fragments 로 split 가능.
spec status `planned` → `in_progress` (NOT `completed` — verb hint
deferral 명시).
## 테스트
- 5 신규 integration unit (`tests/cheatsheet.rs`):
- F1 toggles visibility (open ↔ close, consumed 양쪽)
- Esc closes when visible / falls through when hidden
- modifier-bearing F1 (Ctrl-F1, Alt-F1) 무시
- arbitrary keys (j, /, q, Enter) fall through 하면서 popup 열린 채
- render_cheatsheet 가 모든 section header (Global/Library/Search/
Ask/Inspect) + global toggle (F1, Esc) 출력
- 기존 113 TUI 테스트 + 신규 5 = 118 통과
- `cargo test --workspace --no-fail-fast -j 1` exit 0
- `cargo clippy --workspace --all-targets -- -D warnings` clean
## 문서
- README `kebab tui` 행: F1 cheatsheet popup 안내
- HANDOFF: 2026-05-03 entry
- HOTFIXES: ?→F1 rebind rationale + verb hint deferral
- spec status `planned` → `in_progress`
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
도그푸딩 item 10 — vim 비익숙 사용자도 \"지금 키가 입력 vs 명령\" 명확히
구분 가능. 절반 ship: 사용자 가시 signal (mode label + auto flip + i/Esc
global) 만 land, 키 dispatch 의 input-empty heuristic 제거는 follow-up.
## 핵심 변경
- **`kebab_tui::Mode { Normal, Insert }`** enum + `Default = Normal`.
- `Mode::label()` → `"-- NORMAL --"` / `"-- INSERT --"` (status bar
문자열, 테스트로 핀).
- `Mode::auto_for(pane)` → Library/Inspect/Jobs = Normal,
Search/Ask = Insert. pane 전환 시 자동 적용.
- **`App.mode: Mode`** field. `App::new` 가 starting pane 의 auto
mode 로 init.
- **run loop `mode_intercept(app, key)`** — pane dispatch 전에 호출:
- Insert + `Esc` → Normal (어디서나, modifier 없음)
- Normal + `i` (Library/Inspect/Jobs 만) → Insert
- Search/Ask 의 `i` 는 fall-through (이미 Insert 라 typed char)
- 그 외 fall-through
- **pane 전환 시** `app.mode = Mode::auto_for(p)` 자동 flip — 사용자가
Tab 으로 Search 가면 자동으로 Insert.
- **status bar (header)** 에 mode label colored — Insert = Role::
Success (green), Normal = Role::Heading (cyan + bold). a11y: 색은
reinforcement, 글자가 authoritative signal.
## Deferred (HOTFIXES entry 추가)
spec p9-fb-12 의 \"기존 P9-3 ask 의 e/j/k input-empty heuristic 제거 —
mode 로 명확히\" 는 별 PR 로. 현재 dispatch 는 여전히:
- search.rs 의 `is_typing_mod` (SHIFT 만 typing 으로, CTRL/ALT 는 chord)
- ask.rs 의 input.is_empty() 가 e/j/k 를 navigation 으로 분기
테스트가 heuristic 에 의존해 있어, 회귀 surface 좁게 유지하려고 splitting.
spec status `in_progress` 유지 (not `completed`) — follow-up PR 가
heuristic 제거 + 완전 mode-authoritative 후 `completed` flip.
## 테스트
- 신규 3 unit (`Mode::auto_for` 모든 pane, label literals 핀,
default = Normal)
- 기존 98 TUI 테스트 모두 통과 (heuristic 그대로라 회귀 0)
- workspace 전체 `cargo test --workspace --no-fail-fast -j 1` exit 0
- `cargo clippy --workspace --all-targets -- -D warnings` clean
## 문서
- README `kebab tui` 행: vim-style mode + auto NORMAL/INSERT + i/Esc
안내
- HANDOFF entry (partial-ship 명시)
- HOTFIXES entry (heuristic 제거 deferral 사유)
- spec status planned → in_progress (NOT completed)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>