회차 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>
35 KiB
HANDOFF — 진척도
새 conversation / 다른 사람이 이어받을 때 "지금 어디까지 됐고 다음에 뭘 할지" 의 단일 출처. 사용자 사용법은 README.md, 아키텍처는 docs/ARCHITECTURE.md, per-component 진행은 tasks/INDEX.md, 머지 후 발견된 버그는 tasks/HOTFIXES.md. 이 파일은 "phase 단위 진척" + "다음 task 후보" 만 담는다.
한 줄 요약
P0–P5 + P6 + P7 + P9-1/2/3/4 (Library / Search / Ask / Inspect) 머지 완료. kebab ingest 가 markdown / image / PDF 모두 처리. kebab search / kebab ask 가 매체 가로질러 결과 + page citation 반환. kebab tui 가 4 패널 (Library + Search + Ask + Inspect) 제공 — 사용자가 ? 로 ask, / 로 search, Library Enter / Search i 로 inspect, Search g 로 editor jump. 다음 후보 = P9-5 (desktop tauri) 또는 보류 중인 P8 (audio) 의 시스템 dep brainstorm.
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 | kebab-parse-pdf |
P5 | ✅ 완료 (3/3 component, page-level chunker + ingest wiring) |
| P8 | 음성 transcription + timestamp citation | kebab-parse-audio |
P5 | ⏸ 보류 (whisper-rs 시스템 dep brainstorm 필요) |
| P9 | TUI + desktop app | kebab-tui, kebab-desktop |
P5 | 🟡 진행 (4/5 component — P9-1/2/3/4 완료 [Library / Search / Ask / Inspect], P9-5 desktop 예정 · 도그푸딩 피드백 20/20 ✅) |
| P10 | code ingest framework | kebab-parse-code |
P5 | 🟡 진행 중 (1A-1 머지 직전) — 1A-1 머지 시점 wire schema additive minor + 새 crate kebab-parse-code skeleton 동결, 실제 code chunker 는 1A-2 부터 |
P0P5 직렬. P6P9 P5 이후 병렬 가능.
Component 카운트
총 33 component task — spec 시점 31 개 + 후속 wiring task 3 (P3-5 / P6-4 / P7-3) 가 머지 시점에 추가됨. per-component 진행 + status 는 tasks/INDEX.md.
머지 후 발견된 버그 / 결정 (요약)
머지 후 발견된 모든 deviation / hotfix 의 dated 로그는 tasks/HOTFIXES.md. 본 요약은 "누군가가 인수받을 때 알아두면 시간을 많이 절약하는" 항목만:
-
2026-05-07 fb-26 (progress.rs) —
Abortedunconditional writeln (TTY duplicate) +CompletedTTY no summary fixed;KEBAB_PROGRESS=plainenv + quiet suppression added -
2026-05-07 fb-28 (main.rs) —
--readonly(KEBAB_READONLY) blocks Ingest/IngestFile/IngestStdin/Reset;--quietsuppresses progress stderr; error.v1 code: "readonly_mode" -
2026-05-07 macOS XDG path collision (config 사라지는 버그) —
dirscrate 가 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 toolingest_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 cratekebab-mcp(lib only) — stdio JSON-RPC server. 4 read-only tool (search/ask/schema/doctor) 가kebab-appfacade 위에 build. rmcp 1.6 SDK 채택, manualtools/list+tools/calldispatch (rmcp 의#[tool_router]매크로 대신).error_classify모듈을kebab-cli→kebab-app::error_wire로 promotion (UI crate 끼리 import 회피, facade 룰 준수).ErrorV1에schema_version: String필드 추가 — kebab-mcp 의 직접 serialize 경로에서도 wire 정합.KebabAppState가(Config, Option<PathBuf>)carry — doctor tool 의 path-aware behavior 위해. ask + search arm 의tokio::task::spawn_blockingwrap —OllamaLanguageModel의 reqwest blocking client 가 async 안에서 panic 회피. capability flagmcp_serverfalse→true. 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_configcompanion 을 호출해야 함. 두 번 같은 모양으로 회귀했음. -
P6-2 OCR 기본 엔진 — spec literal 의 Tesseract 가 시스템 dep 부담으로 거부됨, Ollama vision LM 으로 대체.
OcrEnginetrait 그대로라 future swap 가능. -
P6-3 caption —
GenerateRequest.images필드를kebab-core::LanguageModeltrait 에 신설. 기존 caller 모두images: Vec::new()로 마이그레이션. -
P7-2
chunk_id충돌 — pdf-page-v1 가 한 페이지 여러 chunk 분할 → 같은block_ids충돌. per-chunkpolicy_hash#c{char_start}변형 으로 회피. -
P7-3 storage UNIQUE bug —
assets.workspace_pathUNIQUE +upsert_asset_row의ON CONFLICT(asset_id)gap 으로 byte 변경 re-ingest 실패.purge_orphan_at_workspace_pathhelper 추가, 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 과 어긋나 있어 제거. 테스트 seamApp::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, Searchi→ Chunk inspect) 를 한 helper 로 묶음.InspectTargetenum (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가 SQLiteembedding_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 schemaingest_progress.v1line-delimited streaming) + §10 의 long-running 작업 절 추가.kebab-app::ingest_with_config_progress(.., progress: Option<Sender<IngestEvent>>)facade 추가, 기존_with_config가progress=Noneforwarding 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 추가, 기존_progress가cancel=Noneforwarding. asset loop iter 시작 boundary 마다 cancel poll → true 면 break +IngestEvent::Aborted { partial_counts }+Ok(IngestReport)정상 반환 (Err 아님). 부분 commit 보존, 다음 ingest 가 idempotent 재개. CLI Ctrl-C SIGINT handler (ctrlccrate) — 1회: cancel, 2회: hard exit (130). TUI Esc / Ctrl-C 가 cancel signal (in-flight 시), 그 외에는 quit.IngestState에cancel: 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 갱신 —
Answer에conversation_id/turn_indexoptional field, 신규Turnstruct,RefusalReason::LlmStreamAbortedvariant.kebab-rag::AskOpts에history: Vec<Turn>/conversation_id/turn_index3 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 schemaanswer.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.
AskState가turns: 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.x→md-frontmatter-v2bump — 기존 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-09) — TUI external editor return restore. Search
g키 (citation jump) 후 TUI 화면이 깨지는 버그 수정.kebab-tui::editor::with_external_program(&mut TuiTerminal, Command)helper 가 suspend (LeaveAlternateScreen + Show cursor + disable_raw_mode) → spawn → restore (enable_raw_mode + EnterAlternateScreen + Hide cursor +terminal.clear()) 시퀀스를 RAII guard 로 atomic 하게 묶음.App.pending_editor: Option<EditorRequest>+App.force_redraw: bool추가 — 키 핸들러는 EditorRequest enqueue 만, 실제 spawn 은 run loop 가TuiTerminal핸들 들고 처리. 후속 task (p9-fb-20 의 citation jump 등) 가 같은 helper 위에 build. spec:tasks/p9/p9-fb-09-tui-editor-restore.md. -
2026-05-03 P9 도그푸딩 후속 (p9-fb-14) — TUI color theme module.
kebab-tui::theme::{Theme, Role, Palette}신규 — 16 개 Role (BorderActive/Title/Path/ModeLexical/ModeVector/ModeHybrid/Selected/Hint/Heading/Warning/Error/Success/CitationMarker/Bullet/Body/BorderInactive) 을 dark + light 두 팔레트가 exhaustive match 로 매핑. 모든 Pane (library/search/ask/inspect/run/error_popup) 의 inlineStyle::default().fg(Color::*)호출이theme.style(Role::X)로 격리됨.Config.ui.theme: String(default"dark") 신규.App.theme: Theme가App::new에서Theme::from_name(&config.ui.theme)로 build — 알 수 없는 값은 dark fallback (config 가 typo 로 죽지 않음).T키 runtime toggle 은 mode machine (p9-fb-12) 미진행이라 skip — config 만으로 결정. p9-fb-11 (ask markdown render) 의 Theme 의존성 unblock. spec:tasks/p9/p9-fb-14-tui-color-theme.md. -
2026-05-03 P9 도그푸딩 후속 (p9-fb-11) — TUI Ask 답변 본문 markdown 렌더.
kebab-tui::markdown::render(text, &Theme) -> Vec<Line<'static>>신규 —pulldown-cmark = "0.13"위에서 inline (bold/italic/strikethrough/inline code/link)·block (heading H1-H6, ordered/unordered list with nesting, fenced code block, table, blockquote▎, horizontal rule) 변환. heading H1/H2 =Role::Heading, H3+ =Role::Title, link =Role::CitationMarker + UNDERLINE, code =Role::Hint. askpush_turn_lines가 grounded 답변에서만 markdown 렌더; refusal (Role::Warning) / streaming (Role::Hint) 은 raw 로 두어 role color 시그널 보존. CLIkebab ask출력은 raw markdown 그대로 (terminal 호환성). 매 frame 재 parse — pulldown 토크나이저가 µs/KB 라 비용 무시. spec:tasks/p9/p9-fb-11-ask-markdown-render.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 시키던 문제 해소.SearchState에generation: u64+worker_thread: Option<JoinHandle>+worker_rx: Option<Receiver<SearchWorkerMessage>>신규.fire_search가 spawn 만 하고 즉시 return — worker 가 별 thread 에서 검색 후(generation, Result)를 channel 로 post. run loop 가 매 tickpoll_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.rootpath 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/load가path.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_cancellable가new + updated > 0시 bump — no-op reingest 는 cache 보존.App.search_cache: Option<Mutex<LruCache<SearchCacheKey, Vec<SearchHit>>>>(capacity fromconfig.search.cache_capacity, default 256, 0 = 비활성).SearchCacheKey=query_norm(NFKC + trim + lowercase) +mode+k+snippet_chars+embedding_version+chunker_version+corpus_revisionsnapshot.App::search가 lookup → miss 시search_uncached→ put.search_uncached_with_configfacade 추가, CLIkebab search --no-cache로 bypass (디버깅용). frozen design §9 versioning 표에corpus_revisionrow 추가. spec:tasks/p9/p9-fb-19-search-cache.md. -
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::ChatSessionRepotrait 6 메서드 (create_session / get_session / list_sessions / delete_session / append_turn / list_turns) +kebab_core::{ChatSessionRow, ChatTurnRow}신규 export.kebab-store-sqlite::SqliteStoreimpl (별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_sessionsrow 생성 (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-hexturn_id생성). facadekebab_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-03 P9 도그푸딩 후속 (p9-fb-12 partial) — TUI vim-style mode machine (절반 ship — heuristic 제거는 follow-up).
kebab_tui::Mode::{Normal, Insert}enum +Mode::auto_for(pane)(Library/Inspect/Jobs → Normal, Search/Ask → Insert) +Mode::label()("-- NORMAL --"/"-- INSERT --") +App.mode: Modefield. run loopmode_intercept(app, key)가 dispatch 전 intercept — Insert 에서Esc→ Normal (어디서나), Normal 에서i→ Insert (Library/Inspect/Jobs 만, Search/Ask 는 자동 Insert 라i가 typed char). 헤더 우측에 mode label colored (Insert = Role::Success green, Normal = Role::Heading cyan+bold). pane 전환 시app.mode = Mode::auto_for(p)자동 flip. Deferred (HOTFIXES entry):is_typing_mod(search) + input-empty heuristic (ask) 는 후속 PR 에서 mode-authoritative 로 교체 — 현재는 user-visible signal (label + auto flip + i/Esc) 만 ship, 키 dispatch 는 heuristic 유지. spec statusin_progress(notcompleted). spec:tasks/p9/p9-fb-12-tui-mode-machine.md. -
2026-05-03 P9 도그푸딩 후속 (p9-fb-12 follow-up) — heuristic 제거 (partial PR 의 deferred 부분 finalize).
search::is_typing_mod(CTRL/ALT chord filter) 함수 삭제 +ask::handle_key_ask의 input-empty heuristic 삭제. 새 dispatch:search::handle_key_search의i(chunk inspect) /g(editor jump) pre-pass 가state.mode == Mode::Normal일 때만 fire (Insert 에서는 typed char). main match 의j/k/Char(c) 가state.mode로 분기 (Normal → 선택 이동, Insert → input.push).ask::handle_key_ask의e/j/k도 동일 패턴 — Normal 에서 toggle/scroll, Insert 에서 input typing. 테스트 fixture (tests/search.rs::fresh_app,tests/ask.rs::fresh_app) 가app.mode = Mode::auto_for(focus)로 run-loop 동작 mirror. 기존 nav 테스트 (j_k_move, g_key_enqueues, e_toggles) 는 explicitapp.mode = Mode::Normal추가, 신규 4 테스트 (j_in_insert_types / arbitrary_char_in_normal_noop / e_types_in_insert / jk_scroll-in-normal-type-in-insert) 가 mode-authoritative 동작 pin. spec statusin_progress→completed. spec:tasks/p9/p9-fb-12-tui-mode-machine.md. -
2026-05-03 P9 도그푸딩 후속 (p9-fb-10 partial) — TUI CJK rendering helpers.
kebab-tui::input::{display_width, truncate_to_display_width}신규 —unicode-width위에서 column-단위 width 계산 (ASCII=1, Hangul/CJK/fullwidth=2, combining=0) + char-boundary 안전 truncate (wide char 를 split 없이 keep-or-omit, ellipsis 1 col). library.rs 의 중복truncate_to_display_widthprivate fn 제거 — 단일 source. 9 unit tests (ASCII / Hangul / Japanese / mixed / truncate fits·overflow·zero-cols·wide-char-boundary /String::popchar-aware sanity) + 1 integration render test (Korean + Japanese fixture, TestBackend 80×20, 한글/일본어 글자가 frame 에 살아남음 확인). spec 의InputBufferstruct (cursor 가 column 단위 wide-char width 추적) 도입은 follow-up — Ask/Search/Editor pane 의 String + cursor 일괄 마이그레이션이 회귀 표면이 커서 helper 만 먼저 머지. backspace 는 모든 pane 이 이미String::pop()사용 (char-aware) → byte-boundary 안전성 helper 없이도 확보. crossterm 0.28 이 native IME composing 미노출 — preedit handling out of scope. spec statusplanned→in_progress. spec:tasks/p9/p9-fb-10-tui-cjk-input.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 마이그레이션 —
documents에last_chunker_version+last_embedding_version컬럼 추가. 신규IngestItemKind::Unchangedvariant +IngestReport.unchanged+AggregateCounts.unchanged(wire schema additive).IngestOpts { progress, cancel, force_reingest }struct 도입 —AskOpts패턴.--force-reingestCLI flag 로 skip 우회. 비용 dominator (fastembed) 가 변경된 / 새 doc 에만 발생. spec:tasks/p9/p9-fb-23-incremental-ingest.md. HOTFIXES2026-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. HOTFIXES2026-05-05 — p9-fb-25가 source of truth. -
2026-05-04 P9 post-도그푸딩 (p9-fb-24) — TUI status/key bar + Library 컬럼 헤더 + Ask/Inspect PgUp/PgDn. 사용자 도그푸딩 3 건 (Library 컬럼 의미 부재, 페이지 스크롤 키 부재, 상태바 + 버전 정보 항상 노출 요청) 을 단일 PR 로 통합. bottom 영역을 status bar (1 row, version + pane + docs + dynamic state) + key hint bar (1 row, 기존
footer_hints그대로) 두 줄로 분할; 기존 ingest progress dedicated row 는 status bar 의 dynamic slot 에 흡수 (priority cascade: streaming → searching → indexing → idle). LibraryList위에format_doc_header행 + Layout 분할로 헤더 표시 (TITLE / TAGS / UPDATED / CHUNKS, display-width 정렬).kebab-tui::pager::PAGE_STEP = 10신규 — Ask 의 PgUp/PgDn 추가 + Inspect 의 기존 +/-10 hardcode 가 같은 상수 참조로 통일. Ask 의 page-scroll 은j/k와 동일하게follow_tail = false로 freeze. spec:tasks/p9/p9-fb-24-tui-affordances.md. HOTFIXES2026-05-04 — p9-fb-24항목이 footer 단행 row (p9-fb-13) + ingest dedicated row (p9-fb-03) 와의 layout 충돌의 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로 편집.AskState에follow_tail: bool(default true).Paragraph::line_count(width)(ratatuiunstable-rendered-line-infofeature 활성화) 로 매 프레임 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 만iintercept 였고 Search/Ask 는 fall-through (자동 INSERT 가정). 사용자가 Esc 로 NORMAL 로 빠진 후 Insert 복귀 키 없어 dead-end → 도그푸딩에서 보고됨. mode_intercept 의(Char('i'), Normal, _)arm 이 pane 무관 모두 INSERT flip. Search 의 chunk inspect 키i→orebind (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(statuscompleted직접). HOTFIXES 항목이 Searchi→orebind 의 source of truth. -
2026-05-03 P9 도그푸딩 후속 (p9-fb-10 follow-up) — InputBuffer struct + 모든 text-input pane 마이그레이션 + cursor column 정렬.
kebab-tui::input::InputBuffer { content, cursor_col }신규 —push_char/pop_char/clear/take가 wide-char 단위로 cursor_col 진행 (ASCII=1, Hangul/CJK=2, combining=0).SearchState.input/AskState.input/FilterEdit.{tags_buf, lang_buf}가 InputBuffer 로 교체. render 단계에서f.set_cursor_position(...)가block.inner(area)기반 prompt 폭 + cursor_col 으로 caret 을 정확한 column 에 배치 (right-edge clamp). ratatui 0.28 의 cursor visibility 는cursor_positionSome/None 으로 자동 결정 — Search/Ask/Filter 가Some이라 caret 보임, Library/Inspect 는None이라 hidden. Korean lexical 검색은crates/kebab-app/tests/search_korean.rs에서 ingest → search → 결과 한 건 이상 + Korean 파일 stem 매칭 assert 로 회귀 핀.lexical_querytest helper 가crates/kebab-app/tests/common/mod.rs로 promotion. spec statusin_progress→completed. spec:tasks/p9/p9-fb-10-tui-cjk-input.md. -
2026-05-07 P9 post-도그푸딩 (p9-fb-27) —
kebab schema [--json]introspection 명령 +error.v1wire 도입. 정적 (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 MCPinitializecapability 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 statuscompleted. 사용자가kebab직접 돌려서 수집한 UX 잡음 (ingest 진행 표시 부재, mode 혼란, CJK column drift, multi-turn 부재, citation 부재 등) 이 모두 코드 또는 spec-acknowledged-deferred 형태로 해소. 도그푸딩 사이클 한 바퀴 완성 — P9-5 desktop tauri 와 별개로 TUI/CLI 사용자 경험 측면은 한 단계 안정화. P9 phase row 는 P9-5 미진행이라 🟡 유지. -
2026-05-03 P9 도그푸딩 후속 (p9-fb-13 follow-up) — verb-form hint line 재구성.
pub fn footer_hints(focus: Pane, mode: Mode, filter_open: bool) -> &'static str신규 (run.rs). 한국어 동사구 ("위로"/"아래로"/"필터"/"타이핑 검색어"/"Esc 로 NORMAL 모드"등) + mode-aware (NORMAL = navigation verbs, INSERT = typing + Esc reminder) + Library filter overlay 별 분기. 8 unit tests pin 모든 (pane, mode, filter) 조합 — exhaustive non-empty + Library Normal/filter, Search Normal/Insert, Ask Normal/Insert, Inspect Normal 별 verb fragment 존재 검증. spec statusin_progress→completed— p9-fb-13 partial 의 deferred verb-form 항목이 닫힘. -
2026-05-03 P9 도그푸딩 후속 (p9-fb-13) — TUI cheatsheet popup.
kebab-tui::cheatsheet::render_cheatsheet(f, area, app)신규 — 70%/60% centered modal, sections (Global / Library / Search / Ask / Inspect) + global toggle table + 현재 focused pane footer.App.cheatsheet_visible: bool필드 +pub fn cheatsheet_visible()getter. run loopcheatsheet_intercept(app, key)가 mode_intercept 보다 먼저 dispatch —F1토글 (open/close),Esc가 visible 일 때 닫기 (mode_intercept 를 우회해서 cheatsheet 닫기 가 mode flip 도 발동시키지 않도록), 그 외 키는 fall-through (popup 열린 채 navigation 가능). modifier-bearing F1 (Ctrl-F1 등) 은 무시. HOTFIXES 기록: spec 의?trigger 가 Library 의 quick-Ask binding 과 충돌해서F1으로 rebind. spec 의 verb-form hint line 재구성은 별 후속 PR (기존 footer 가 동일 역할). spec statusplanned→in_progress(verb hint deferral 으로 partial). spec:tasks/p9/p9-fb-13-tui-cheatsheet.md.
다음 task 후보
- P9-2 TUI search —
App.searchslot 채움. Library 의/가 enable 됨. - P9-3 TUI ask —
App.askslot 채움.?enable. - P9-4 TUI inspect —
App.inspectslot 채움.Enterenable. - P9-5 desktop tauri — 별도 분기. PDF citation rendering UI 가치 큼.
- P8 audio brainstorm — whisper-rs 시스템 dep 받을지 / 외부 transcription endpoint 사용할지 사용자 결정 필요. 사용자 패턴 (책+PDF 위주, audio 의향 없음) 상 후순위.
P9-2/3/4 는 P9-1 의 parallel-safety contract (sub-state slot 패턴) 덕에 병렬 진행 가능 — 같은 App 손대지 않음.
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 🟡 진행: fb-38 (score semantics) ✅ 머지 (2026-05-10), fb-40 (fact-grounded answer / rag-v2 prompt) ✅ 머지 (2026-05-10), fb-39 (retrieval precision tuning, embedding_version cascade) — 미진행 (eval golden set 선행 필요).
- 0.7.0 또는 P+: fb-41 (multi-hop reasoning, XL), fb-42 (bulk multi-query / rerank, Nice).
각 fb spec frontmatter 의 target_version 필드가 source of truth. INDEX.md 의 release subheader 도 동일 grouping.
검증된 운영 동작 (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.