feat(tui): fb-41 PR-6 TUI Ask multi-hop toggle + hop trace summary #173

Merged
altair823 merged 2 commits from feat/fb-41-pr-6-tui-multi-hop-toggle into main 2026-05-25 09:30:08 +00:00
Owner

요약

fb-41 multi-hop RAG 의 마지막 component PR (PR-5 머지 직후). TUI Ask 패널의 user-facing surface — F2 toggle, multi-hop badge, status panel 의 hop count summary, cheatsheet 안내. v0.18.0 cut 준비.

설계: docs/superpowers/specs/2026-05-25-p9-fb-41-multi-hop-rag-design.md
계획: docs/superpowers/plans/2026-05-25-p9-fb-41-multi-hop-rag.md (PR-6 단락)

TUI surface

  • AskState.multi_hop: bool field (default false). 토글 상태 인-패널 보존, 대화 history 와 직교 — F2 flipping mid-conversation 도 turns 보존 (다음 turn 만 다른 pipeline 으로 route).
  • handle_key_ask(KeyCode::F(2), _) arm — mode-agnostic (physical function key, Normal/Insert 양쪽). Plan 의 candidate (F2 / Ctrl-T) 중 F2 채택. Ctrl-M 은 Enter 와 conflict 이미 명시, F2 가 가장 깨끗.
  • spawn_ask_workerAskOpts.multi_hop 가 spawn 시점에 snapshot — 이후 F2 flip 은 다음 Enter 부터 (in-flight turn 무영향).
  • render_input 의 input pane title 에 F2=multi-hop binding 안내 + prompt row 에 multi-hop badge (Success 녹색, toggled-on 일 때만). 다음 query 가 어느 pipeline 으로 갈지 항상 가시.
  • render_status 의 status panel 에 multi-hop: N hops line (last_answer.hops 가 Some 일 때만). forced_stop 발생 시 forced_stop=K suffix — depth/pool cap tuning 단서.
  • cheatsheet.rs 의 Ask section 에 F2 toggle multi-hop pipeline entry 추가.

Tests (tests/ask.rs 신규 6 multi-hop pins)

  • f2_toggles_multi_hop_flag_from_insert_mode: Insert 에서 F2 toggle (fresh_app default mode).
  • f2_toggles_multi_hop_flag_from_normal_mode: Normal 에서도 동일 (mode-agnostic 회귀 핀).
  • input_pane_shows_multi_hop_badge_when_toggled_on: prompt row 의 multi-hop 등장 + title 의 binding hint 등장.
  • input_pane_omits_multi_hop_badge_when_toggled_off: badge 부재 (title hint 는 유지 — discoverability).
  • status_panel_summarizes_hops_when_answer_has_trace: 3-hop trace → multi-hop: 3 hops line.
  • status_panel_omits_hops_summary_for_single_pass: hops=None → summary 부재.
  • spawn_snapshot_multi_hop_into_askopts: AskState.multi_hop 의 field shape 회귀 핀.

변경 없음 (의도된 deferral)

  • InspectTarget::Hop(turn_index) variant — plan 의 PR-6 stretch goal. per-iter hop trace detail 을 Inspect 패널에 노출하는 기능은 별 PR (PR-6b 또는 v0.18 dogfood follow-up). PR-6 의 핵심 가치 (multi-hop 토글 + 결과의 hop count 가시) 는 status panel summary 로 100% cover. Inspect 진입은 드물게 필요한 surface — v0.18 cut 부담 회피.
  • prompt_template_version (rag-multi-hop-v1) — 그대로.
  • MCP / CLI surface — PR-4 / PR-5 의 책임.

검증

  • cargo test -p kebab-tui -j 1 — 신규 6 multi-hop + 기존 ask / search / library / mode / cheatsheet / inspect / status_bar 모두 통과. 회귀 없음.
  • cargo clippy -p kebab-tui --all-targets -j 1 -- -D warnings clean.
  • 단일 crate 직렬 build (16 GB RAM 제약).

시험 항목 (Test Plan)

  • F2 가 mode (Normal/Insert) 무관 toggle
  • multi-hop badge 가 prompt row 에 toggle 따라 표시/비표시
  • title binding hint (F2=multi-hop) 가 항상 가시 (discoverability)
  • status panel 의 multi-hop: N hops summary (last_answer.hops 가 Some 일 때만)
  • AskOpts.multi_hop 가 spawn 시점에 snapshot
  • cheatsheet 의 Ask section 에 F2 entry
  • 기존 ask / search / library / inspect / mode tests 회귀 없음

다음 — v0.18.0 cut

PR-6 머지 후 v0.18.0 cut step:

  1. Workspace Cargo.toml version 0.17.2 → 0.18.0 (minor — surface 확장 + new prompt_template_version = "rag-multi-hop-v1").
  2. HANDOFF.md 의 한 줄 요약 + 머지 후 결정 절에 fb-41 entry 추가.
  3. HOTFIXES.md 의 fb-41 PR 시리즈 (PR-1~PR-6) anchor 정리.
  4. INDEX.md 의 fb-41 status opencompleted.
  5. gitea-release v0.18.0 --auto-notes + release notes.

Assisted-by: Claude Code

## 요약 fb-41 multi-hop RAG 의 **마지막 component PR** (PR-5 머지 직후). TUI Ask 패널의 user-facing surface — F2 toggle, multi-hop badge, status panel 의 hop count summary, cheatsheet 안내. v0.18.0 cut 준비. 설계: docs/superpowers/specs/2026-05-25-p9-fb-41-multi-hop-rag-design.md 계획: docs/superpowers/plans/2026-05-25-p9-fb-41-multi-hop-rag.md (PR-6 단락) ## TUI surface - `AskState.multi_hop: bool` field (default false). 토글 상태 인-패널 보존, 대화 history 와 직교 — F2 flipping mid-conversation 도 turns 보존 (다음 turn 만 다른 pipeline 으로 route). - `handle_key_ask` 의 `(KeyCode::F(2), _)` arm — mode-agnostic (physical function key, Normal/Insert 양쪽). Plan 의 candidate (F2 / Ctrl-T) 중 F2 채택. Ctrl-M 은 Enter 와 conflict 이미 명시, F2 가 가장 깨끗. - `spawn_ask_worker` 의 `AskOpts.multi_hop` 가 spawn 시점에 snapshot — 이후 F2 flip 은 다음 Enter 부터 (in-flight turn 무영향). - `render_input` 의 input pane title 에 `F2=multi-hop` binding 안내 + prompt row 에 `multi-hop` badge (Success 녹색, toggled-on 일 때만). 다음 query 가 어느 pipeline 으로 갈지 항상 가시. - `render_status` 의 status panel 에 `multi-hop: N hops` line (last_answer.hops 가 Some 일 때만). `forced_stop` 발생 시 `forced_stop=K` suffix — depth/pool cap tuning 단서. - `cheatsheet.rs` 의 Ask section 에 `F2 toggle multi-hop pipeline` entry 추가. ## Tests (`tests/ask.rs` 신규 6 multi-hop pins) - `f2_toggles_multi_hop_flag_from_insert_mode`: Insert 에서 F2 toggle (fresh_app default mode). - `f2_toggles_multi_hop_flag_from_normal_mode`: Normal 에서도 동일 (mode-agnostic 회귀 핀). - `input_pane_shows_multi_hop_badge_when_toggled_on`: prompt row 의 `multi-hop` 등장 + title 의 binding hint 등장. - `input_pane_omits_multi_hop_badge_when_toggled_off`: badge 부재 (title hint 는 유지 — discoverability). - `status_panel_summarizes_hops_when_answer_has_trace`: 3-hop trace → `multi-hop: 3 hops` line. - `status_panel_omits_hops_summary_for_single_pass`: hops=None → summary 부재. - `spawn_snapshot_multi_hop_into_askopts`: AskState.multi_hop 의 field shape 회귀 핀. ## 변경 없음 (의도된 deferral) - `InspectTarget::Hop(turn_index)` variant — plan 의 PR-6 stretch goal. per-iter hop trace detail 을 Inspect 패널에 노출하는 기능은 별 PR (PR-6b 또는 v0.18 dogfood follow-up). PR-6 의 핵심 가치 (multi-hop 토글 + 결과의 hop count 가시) 는 status panel summary 로 100% cover. Inspect 진입은 *드물게* 필요한 surface — v0.18 cut 부담 회피. - `prompt_template_version` (`rag-multi-hop-v1`) — 그대로. - MCP / CLI surface — PR-4 / PR-5 의 책임. ## 검증 - `cargo test -p kebab-tui -j 1` — 신규 6 multi-hop + 기존 ask / search / library / mode / cheatsheet / inspect / status_bar 모두 통과. 회귀 없음. - `cargo clippy -p kebab-tui --all-targets -j 1 -- -D warnings` clean. - 단일 crate 직렬 build (16 GB RAM 제약). ## 시험 항목 (Test Plan) - [x] F2 가 mode (Normal/Insert) 무관 toggle - [x] multi-hop badge 가 prompt row 에 toggle 따라 표시/비표시 - [x] title binding hint (F2=multi-hop) 가 항상 가시 (discoverability) - [x] status panel 의 `multi-hop: N hops` summary (last_answer.hops 가 Some 일 때만) - [x] AskOpts.multi_hop 가 spawn 시점에 snapshot - [x] cheatsheet 의 Ask section 에 F2 entry - [x] 기존 ask / search / library / inspect / mode tests 회귀 없음 ## 다음 — v0.18.0 cut PR-6 머지 후 v0.18.0 cut step: 1. Workspace `Cargo.toml` version 0.17.2 → 0.18.0 (minor — surface 확장 + new `prompt_template_version = "rag-multi-hop-v1"`). 2. HANDOFF.md 의 한 줄 요약 + 머지 후 결정 절에 fb-41 entry 추가. 3. HOTFIXES.md 의 fb-41 PR 시리즈 (PR-1~PR-6) anchor 정리. 4. INDEX.md 의 fb-41 status `open` → `completed`. 5. `gitea-release v0.18.0 --auto-notes` + release notes. Assisted-by: Claude Code
altair823 added 1 commit 2026-05-25 09:27:12 +00:00
fb-41 multi-hop RAG 의 **마지막 component PR** (PR-5 머지 직후). TUI Ask
패널의 user-facing surface — F2 toggle, multi-hop badge, status panel
의 hop count summary, cheatsheet 안내. v0.18.0 cut 준비.

설계: docs/superpowers/specs/2026-05-25-p9-fb-41-multi-hop-rag-design.md
계획: docs/superpowers/plans/2026-05-25-p9-fb-41-multi-hop-rag.md (PR-6 단락)

## TUI surface

- `crates/kebab-tui/src/app.rs`:
  - `AskState.multi_hop: bool` field + Default false. 사용자 토글
    상태를 인-패널 보존, 대화 history 와 직교 — F2 flipping mid-
    conversation 도 turns 보존 (다음 turn 만 다른 pipeline 으로 route).
- `crates/kebab-tui/src/ask.rs`:
  - `handle_key_ask` 에 `(KeyCode::F(2), _) → s.multi_hop = !s.multi_hop`.
    Mode-agnostic (physical function key — Normal/Insert 양쪽 작동, typing
    ambiguity 없음). Briefing 의 candidate (F2 vs Ctrl-T) 중 F2 채택 —
    Ctrl-M 은 Enter 와 collision 이미 명시, F2 가 cleanest.
  - `spawn_ask_worker` 의 `AskOpts.multi_hop` 가 spawn 시점에 토글값
    snapshot. 이후 F2 flip 은 다음 Enter 부터 적용 (in-flight turn 무영향).
  - `render_input` 의 input pane title 에 `F2=multi-hop` binding 안내
    추가 + prompt row 에 `multi-hop` badge (Success 녹색, toggled-on 일
    때만). 사용자가 어떤 pipeline 으로 다음 query 를 보낼지 항상 가시.
  - `render_status` 의 status panel 에 `multi-hop: N hops` line 추가
    (last_answer.hops 가 Some 일 때만). forced_stop 발생 시
    `forced_stop=K` suffix — depth/pool cap tuning 단서.
- `crates/kebab-tui/src/cheatsheet.rs`:
  - Ask section 에 `F2 toggle multi-hop pipeline` entry 추가.

## 변경 없음 (의도된 deferral)

- `InspectTarget::Hop(turn_index)` variant — plan 의 PR-6 stretch goal.
  per-iter hop trace detail 을 Inspect 패널에 노출하는 기능은 별 PR
  (PR-6b 또는 v0.18 dogfood follow-up). PR-6 의 핵심 가치
  (사용자가 multi-hop pipeline 을 토글하고 결과의 hop count 를 본다)
  는 status panel 의 한 줄 summary 로 100% cover. Inspect 진입은
  multi-hop 사용자가 *드물게* 필요한 surface — v0.18 cut 부담 회피.
- prompt_template_version (`rag-multi-hop-v1`) — 그대로.
- MCP / CLI surface — PR-4 / PR-5 의 책임.

## Tests (`tests/ask.rs` 신규 6 multi-hop pins)

- `f2_toggles_multi_hop_flag_from_insert_mode`: Insert 에서 F2 toggle
  (fresh_app default mode).
- `f2_toggles_multi_hop_flag_from_normal_mode`: Normal 에서도 동일
  — mode-agnostic 회귀 핀.
- `input_pane_shows_multi_hop_badge_when_toggled_on`: 토글 on 시
  prompt row 에 `multi-hop` 등장 + title 의 `F2=multi-hop` binding
  hint 등장.
- `input_pane_omits_multi_hop_badge_when_toggled_off`: 토글 off 시
  prompt row 의 badge 부재 (title hint 는 유지 — 사용자 discoverability).
- `status_panel_summarizes_hops_when_answer_has_trace`: 3-hop trace
  (Decompose + Decide + Synthesize) → `multi-hop: 3 hops` line.
- `status_panel_omits_hops_summary_for_single_pass`: hops=None → 본문
  에 summary line 부재 (title binding hint 만).
- `spawn_snapshot_multi_hop_into_askopts`: AskState.multi_hop 의
  field shape 회귀 핀 (default false / settable / round-trip).

## 검증

- `cargo test -p kebab-tui -j 1` — 신규 6 multi-hop + 기존 ask /
  search / library / mode / cheatsheet / inspect / status_bar 모두
  통과 (42 ask test + 10 mode + 기타). 회귀 없음.
- `cargo clippy -p kebab-tui --all-targets -j 1 -- -D warnings` clean.
- 단일 crate 직렬 build (16 GB RAM 제약).

## v0.18.0 cut (다음 단계)

- Workspace `Cargo.toml` version 0.17.2 → 0.18.0 (minor — surface
  확장 + new prompt_template_version `rag-multi-hop-v1`).
- HANDOFF.md / HOTFIXES.md / INDEX.md 갱신 (fb-41 entry 정리).
- `gitea-release v0.18.0 --auto-notes`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
claude-reviewer-01 requested changes 2026-05-25 09:28:28 +00:00
Dismissed
claude-reviewer-01 left a comment
Member

회차 1 — test name 1 건 nit.

PR-6 의 scope (TUI Ask multi-hop toggle + badge + status summary + cheatsheet + 6 test) 자체는 컴팩트하고 흐름 깨끗. AskState field doc / F2 keybinding doc / spawn snapshot doc / render badge styling 모두 명확. plan 의 InspectTarget::Hop 은 의도된 deferral 로 PR body 에 잘 명시됨.

본 유일 nit: spawn_snapshot_multi_hop_into_askopts test 이름이 약속하는 spawn 동작 검증을 실제로는 안 한다 (단순 field shape 회귀 핀). 이름 rename 1 줄 권장. inline 코멘트에 옵션 두 가지.

설계·계획 정합 / clippy / 6 test 의 coverage / cheatsheet 갱신은 모두 정합.

회차 1 — test name 1 건 nit. PR-6 의 scope (TUI Ask multi-hop toggle + badge + status summary + cheatsheet + 6 test) 자체는 컴팩트하고 흐름 깨끗. AskState field doc / F2 keybinding doc / spawn snapshot doc / render badge styling 모두 명확. plan 의 `InspectTarget::Hop` 은 의도된 deferral 로 PR body 에 잘 명시됨. 본 유일 nit: `spawn_snapshot_multi_hop_into_askopts` test 이름이 약속하는 spawn 동작 검증을 실제로는 안 한다 (단순 field shape 회귀 핀). 이름 rename 1 줄 권장. inline 코멘트에 옵션 두 가지. 설계·계획 정합 / clippy / 6 test 의 coverage / cheatsheet 갱신은 모두 정합.

test name 과 실제 검증 mismatch (actionable nit): 이 test 이름은 spawn_snapshot_multi_hop_into_askopts — "toggle 값이 spawn 시점에 snapshot 되어 AskOpts 로 들어간다" 라는 spawn 동작 약속을 시사. 하지만 실제 본문은:

  • spawn_ask_worker 를 호출하지 않음
  • AskOpts 를 inspect 하지 않음
  • 단순히 AskState.multi_hop 필드의 default + setter round-trip 만 검증

doc string 안에는 "strategy: 가벼운 field shape 회귀 핀" 라고 trade-off 설명이 있어 의도는 명확하지만 — test 이름이 약속을 빌려 안 지키는 모양새. 두 옵션:

  • rename (가벼움): multi_hop_field_default_false_and_round_trips 또는 ask_state_multi_hop_field_shape_pin — 실제 검증과 일치하는 이름.
  • (더 무거움) 실제 spawn 까지 검증 — 그러나 worker thread 가 Ollama / KB 필요 → infeasible. 가볍게 rename 이 적절.

다른 6 multi-hop test 의 이름 (f2_toggles_*, input_pane_*, status_panel_*) 은 모두 정확하게 검증과 매치 — 일관성 측면으로도 rename 권장.

**test name 과 실제 검증 mismatch (actionable nit)**: 이 test 이름은 `spawn_snapshot_multi_hop_into_askopts` — "toggle 값이 spawn 시점에 snapshot 되어 AskOpts 로 들어간다" 라는 spawn 동작 약속을 시사. 하지만 실제 본문은: - `spawn_ask_worker` 를 호출하지 않음 - AskOpts 를 inspect 하지 않음 - 단순히 `AskState.multi_hop` 필드의 default + setter round-trip 만 검증 doc string 안에는 "strategy: 가벼운 field shape 회귀 핀" 라고 trade-off 설명이 있어 의도는 명확하지만 — test 이름이 약속을 빌려 안 지키는 모양새. 두 옵션: - **rename** (가벼움): `multi_hop_field_default_false_and_round_trips` 또는 `ask_state_multi_hop_field_shape_pin` — 실제 검증과 일치하는 이름. - (더 무거움) 실제 spawn 까지 검증 — 그러나 worker thread 가 Ollama / KB 필요 → infeasible. 가볍게 rename 이 적절. 다른 6 multi-hop test 의 이름 (`f2_toggles_*`, `input_pane_*`, `status_panel_*`) 은 모두 정확하게 검증과 매치 — 일관성 측면으로도 rename 권장.
altair823 added 1 commit 2026-05-25 09:29:41 +00:00
test `spawn_snapshot_multi_hop_into_askopts` →
`ask_state_multi_hop_field_default_false_and_round_trips` 로 rename.
이전 이름은 spawn 동작 검증을 약속했으나 본문은 단순 field
default + setter round-trip 만 검증 — name 과 실제 의도의 mismatch.
새 이름이 실제 검증 (field shape pin) 과 정확히 일치.

doc string 도 spawn 동작은 별 path (live dogfood) 로 검증된다고
명확히 표기 — test 의 책임 범위가 무엇인지 reader 가 즉시 파악.

검증
- `cargo test -p kebab-tui -j 1 --test ask` — 42 test (6 multi-hop
  포함) 모두 통과.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
claude-reviewer-01 approved these changes 2026-05-25 09:29:57 +00:00
claude-reviewer-01 left a comment
Member

회차 2 — test name 의 mismatch 완벽 정리.

spawn_snapshot_multi_hop_into_askoptsask_state_multi_hop_field_default_false_and_round_trips rename + doc string 갱신 (spawn 검증은 live dogfood 의 책임이라는 정직한 표기). test name 이 실제 검증 범위와 정확히 일치 — 다른 6 multi-hop test 명명과도 일관.

추가 actionable 항목 없음 — 머지에 동의.

요약:

  • TUI Ask 패널의 AskState.multi_hop field + F2 mode-agnostic toggle + spawn_ask_worker 시점 snapshot.
  • input pane prompt row 의 multi-hop badge (Success 녹색, toggled-on 일 때만) + title 의 F2=multi-hop binding hint (항상 가시 — discoverability).
  • status panel 의 multi-hop: N hops summary line (last_answer.hops 가 Some 일 때만, forced_stop count suffix 포함).
  • cheatsheet 의 Ask section 에 F2 entry.
  • 7 multi-hop test (F2 toggle ×2 modes + badge ON/OFF + hops summary ON/OFF + field shape pin).
  • cargo test -p kebab-tui -j 1 모두 통과 (회귀 없음), cargo clippy ... -- -D warnings clean.
  • InspectTarget::Hop 은 의도된 deferral — v0.18 dogfood follow-up 의 책임.
회차 2 — test name 의 mismatch 완벽 정리. `spawn_snapshot_multi_hop_into_askopts` → `ask_state_multi_hop_field_default_false_and_round_trips` rename + doc string 갱신 (spawn 검증은 live dogfood 의 책임이라는 정직한 표기). test name 이 실제 검증 범위와 정확히 일치 — 다른 6 multi-hop test 명명과도 일관. 추가 actionable 항목 없음 — 머지에 동의. 요약: - TUI Ask 패널의 `AskState.multi_hop` field + F2 mode-agnostic toggle + `spawn_ask_worker` 시점 snapshot. - input pane prompt row 의 `multi-hop` badge (Success 녹색, toggled-on 일 때만) + title 의 `F2=multi-hop` binding hint (항상 가시 — discoverability). - status panel 의 `multi-hop: N hops` summary line (last_answer.hops 가 Some 일 때만, `forced_stop` count suffix 포함). - cheatsheet 의 Ask section 에 F2 entry. - 7 multi-hop test (F2 toggle ×2 modes + badge ON/OFF + hops summary ON/OFF + field shape pin). - `cargo test -p kebab-tui -j 1` 모두 통과 (회귀 없음), `cargo clippy ... -- -D warnings` clean. - `InspectTarget::Hop` 은 의도된 deferral — v0.18 dogfood follow-up 의 책임.
altair823 merged commit 5bfea3c28b into main 2026-05-25 09:30:08 +00:00
altair823 deleted branch feat/fb-41-pr-6-tui-multi-hop-toggle 2026-05-25 09:30:09 +00:00
Sign in to join this conversation.
No Reviewers
No Label
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: altair823-org/kebab#173