Files
kebab/HANDOFF.md
th-kim0823 7961f8813d fix(p10-1a-1): PR review round 1 — doc inconsistencies
회차 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>
2026-05-15 18:24:15 +09:00

35 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) 머지 완료. 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)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-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) 의 inline Style::default().fg(Color::*) 호출이 theme.style(Role::X) 로 격리됨. Config.ui.theme: String (default "dark") 신규. App.theme: ThemeApp::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. ask push_turn_lines 가 grounded 답변에서만 markdown 렌더; refusal (Role::Warning) / streaming (Role::Hint) 은 raw 로 두어 role color 시그널 보존. CLI kebab 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 시키던 문제 해소. 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.

  • 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-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: Mode field. run loop mode_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 status in_progress (not completed). 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_searchi (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_aske/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) 는 explicit app.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 status in_progresscompleted. 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_width private fn 제거 — 단일 source. 9 unit tests (ASCII / Hangul / Japanese / mixed / truncate fits·overflow·zero-cols·wide-char-boundary / String::pop char-aware sanity) + 1 integration render test (Korean + Japanese fixture, TestBackend 80×20, 한글/일본어 글자가 frame 에 살아남음 확인). spec 의 InputBuffer struct (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 status plannedin_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 마이그레이션 — 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-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). Library List 위에 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. HOTFIXES 2026-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 로 편집. 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-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_position Some/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_query test helper 가 crates/kebab-app/tests/common/mod.rs 로 promotion. spec status in_progresscompleted. spec: tasks/p9/p9-fb-10-tui-cjk-input.md.

  • 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 미진행이라 🟡 유지.

  • 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 status in_progresscompleted — 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 loop cheatsheet_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 status plannedin_progress (verb hint deferral 으로 partial). spec: tasks/p9/p9-fb-13-tui-cheatsheet.md.

다음 task 후보

  • P9-2 TUI searchApp.search slot 채움. Library 의 / 가 enable 됨.
  • P9-3 TUI askApp.ask slot 채움. ? enable.
  • P9-4 TUI inspectApp.inspect slot 채움. Enter enable.
  • 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.