5 Commits

Author SHA1 Message Date
546c1564b0 feat(rag): fb-41 PR-9c-1 — core types + wire scaffolding (NLI verification)
Surface-only PR (no behavior wiring — that's PR-9c-2):
- kebab-core: RefusalReason::NliVerificationFailed + NliModelUnavailable (serde rename_all="snake_case", wire = identical strings).
- kebab-core: Answer.verification: Option<VerificationSummary> field (additive minor wire — pre-v0.18 reader 무영향).
- kebab-core: VerificationSummary { nli_score: f32, nli_threshold: f32, nli_passed: bool } struct + lib.rs 재-export.
- kebab-config: NliCfg { model, provider } + ModelsCfg.nli (default Xenova/mDeBERTa-v3-base-xnli-multilingual-nli-2mil7).
- kebab-config: RagCfg.nli_threshold: f32 (default 0.0 = disabled, spec §2.6 single gate).
- kebab-config: env override KEBAB_MODELS_NLI_MODEL/PROVIDER + KEBAB_RAG_NLI_THRESHOLD (parse 실패 시 tracing::warn + default 유지).
- kebab-rag: RagPipeline.verifier: Option<Arc<dyn NliVerifier>> field + with_verifier builder (모두 #[allow(dead_code)] — PR-9c-2 의 step 8.5 hook 가 활성화 시 제거). RagPipeline::new signature 유지 (round-2 NEW-M1 Option B).
- kebab-rag: Cargo.toml 에 kebab-nli path 의존 추가.
- kebab-store-sqlite + kebab-tui: 두 신규 RefusalReason variant 에 대한 exhaustive match arm 추가 (snake_case label / 표시 문구).
- 모든 Answer 구축 site (rag 6 + cli/tui/eval 3 fixture) 에 verification: None 추가.
- wire schemas: answer.schema.json verification field + \$defs.VerificationSummary + refusal_reason.enum 2 추가. error.schema.json code.enum + details.description 2 추가 (forward-looking reserved).
- docs/ARCHITECTURE.md: Mermaid Adapters subgraph 의 nli 노드 + rag→nli + app→nli (forward-looking) + nli→config edges. nli→core edge 는 skip (kebab-nli/Cargo.toml direct dep 가 config 만, ARCHITECTURE 컨벤션 = direct deps only). 디렉토리 트리에 crates/kebab-nli/ 추가.

Tests: kebab-core 3 (serde rename + verification skip + struct shape) + kebab-config 6 (defaults + legacy + env + malformed env) + kebab-cli wire 5 (schema verification + enum 검증).
검증: cargo test --workspace -j 1 회귀 0 (pre-existing kebab-mcp::tools_call_ask_multi_hop flaky 1개 동일 — spec 에 명시된 known-flaky). cargo clippy --workspace --all-targets -D warnings clean.
Wire 영향: additive minor — answer.v1 의 verification optional + refusal_reason.enum 확장 + error.v1.code 확장.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 23:27:36 +00:00
c56242d04f chore(cli): PR #171 회차 1 리뷰 반영
`answer.schema.json` 의 `refusal_reason` description 의 PR 번호 정정:
`multi_hop_decompose_failed` 도입 시점 = PR-2 (#167, RefusalReason variant
+ ask_multi_hop decompose-failure 분기). PR-3a (#168) 는 `Answer.hops`
field + RagCfg knob 만 — refusal variant 와 무관.

검증
- `cargo test -p kebab-cli -j 1 --test wire_ask_multi_hop` 4 모두 통과.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 08:47:35 +00:00
17c48a0ee6 feat(cli): fb-41 PR-4 — CLI --multi-hop flag + answer.v1 / error.v1 wire 확장
fb-41 multi-hop RAG 의 **PR-4** (PR-3b-ii 의 ScriptedLm + tests 위에서
user-facing CLI surface + JSON Schema 확장). PR-3b-i / PR-3b-ii 의 multi-hop
pipeline 을 `kebab ask --multi-hop` 으로 사용자에게 노출.

설계: 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-4 단락)

## CLI surface

- `kebab ask --multi-hop <query>` — 새 flag (default false). `AskOpts.multi_hop`
  로 전달, stream + non-stream 두 callsite 모두 갱신.
- `--show-citations` / `--hide-citations` / `--stream` / `--session` 등 기존
  flag 와 orthogonal.
- `--json` 모드에서 `Answer.hops` 배열이 multi-hop happy path / refusal-with-
  partial-trace 양쪽 경로에서 노출됨 (PR-3b-i + PR-3b-ii 의 wiring).

## Wire schema 확장

- `docs/wire-schema/v1/answer.schema.json`:
  - 신규 `hops: array | null` 필드 (optional, additive). `HopRecord` 의
    `$defs` 추가 — `iter` / `kind` (decompose|decide|synthesize) /
    `sub_queries` / `context_chunks_added` / `forced_stop` / `llm_call_ms`
    6 필드 + per-field doc.
  - `refusal_reason` 필드를 `anyOf [enum, null]` 로 명시 — 6 variant
    (`score_gate`, `llm_self_judge`, `no_index`, `no_chunks`,
    `llm_stream_aborted`, `multi_hop_decompose_failed`). 이전 schema 는
    `type: string|null` 만 명시 → enum 명시는 agent / consumer 의 strict
    validate 강화 (additive — 기존 producer 값 모두 enum 안).
  - `$id` / `schema_version` 변경 없음 — additive minor.
- `docs/wire-schema/v1/error.schema.json`:
  - `code` enum 에 `multi_hop_decompose_failed` 추가. **이는 forward-looking
    enum extension** — 현재 RefusalReason 은 `Answer.refusal_reason` (stdout)
    으로만 노출되고 `error.v1` (stderr) 경로 안 거침. 미래 PR 에서 fatal
    promotion 정책 결정 시 trigger 가능하도록 enum 만 미리 reserve.
  - details.description 의 per-code 안내에 `multi_hop_decompose_failed: {}`
    note 추가 — reserved 상태 명시.

## Tests

- `crates/kebab-cli/tests/wire_ask_multi_hop.rs` 신규 (4 Ollama-free pins):
  - `cli_ask_help_advertises_multi_hop_flag`: clap-level smoke, `kebab ask
    --help` 출력에 `--multi-hop` 등장 확인.
  - `answer_schema_declares_hops_property_with_hop_record_defs`: `hops`
    property 존재 + `$defs.HopRecord` 의 `kind` enum 3 variant
    (decompose/decide/synthesize) 회귀 핀.
  - `answer_schema_refusal_reason_enum_includes_multi_hop_decompose_failed`:
    6 variant 모두 enum 에 존재 — 기존 5 도 함께 핀 (회귀 방지).
  - `error_schema_code_enum_includes_multi_hop_decompose_failed`: 신규
    code enum 확장 + 기존 code (config_invalid / not_indexed / ...) 보존 핀.

End-to-end multi-hop ask 의 live Ollama 검증은 후속 `#[ignore]` test 로
(같은 `wire_ask_stale.rs` 패턴). PR-4 의 범위 = clap + schema 정합성 만.

## 변경 없음

- `crates/kebab-app/src/error_wire.rs` — plan 의 "error_wire 매핑" 항목은
  현재 RefusalReason 가 `Answer.refusal_reason` 로만 노출 (anyhow chain 안
  거침) 라 trigger 가 없음. enum reservation 만으로 충분, 매핑 코드는 dead
  code 회피. 향후 fatal-promotion 정책 (refusal → error.v1) 결정 시 PR-4b
  로 split.
- `prompt_template_version` — `rag-multi-hop-v1` 그대로.
- TUI / MCP surface — PR-5 / PR-6 에서.

## 검증

- `cargo test -p kebab-cli -j 1` — 모든 test 통과 (신규 wire_ask_multi_hop 4 +
  기존 ask / search / schema / ingest / mcp / reset 등 모두).
- `cargo clippy -p kebab-cli --all-targets -j 1 -- -D warnings` clean.
- 단일 crate 직렬 build (16 GB RAM 제약).

## 다음 PR

- PR-5: MCP `ask` tool 의 `multi_hop: bool` argument + `integrations/claude-
  code/kebab/SKILL.md` 의 ask 절 갱신.
- PR-6: TUI Ask 패널 multi-hop toggle (F2 / Ctrl-T) + hop trace render.
- v0.18.0 cut (PR-6 머지 후): `Cargo.toml` 0.17.2 → 0.18.0 + HANDOFF /
  HOTFIXES / INDEX 갱신 + gitea-release.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 08:45:01 +00:00
ecb85651ea spec(p9-fb-15): RAG multi-turn 정책 + answer.v1 conversation_id/turn_index
도그푸딩 후 추가된 ask multi-turn (꼬리 물기) surface 를 frozen design
+ wire schema 에 명시. p9-fb-15 (RAG core) + p9-fb-16 (TUI UI) +
p9-fb-17 (V004 chat sessions) + p9-fb-18 (CLI session/repl) 의 spec
PR — impl PR 들이 이어진다.

변경:
- §2.3 Answer wire schema: conversation_id (String?) + turn_index
  (u32?) 두 optional 필드. 기존 single-shot 소비자 (외부 wrapper)
  영향 없음 — 두 필드 모두 optional.
- §3.8 RAG types:
  - Answer struct 에 conversation_id / turn_index field 추가.
  - Turn struct 신설 (history 가 prompt 에 들어갈 때 한 turn).
- §3.8 \"Multi-turn behaviour\" 신설 절:
  - kebab-rag::ask vs ask_with_history 두 entry.
  - prompt 빌드 priority: system+question (필수) → retrieved chunks
    (k 줄여 fit) → history (newest 우선, oldest drop).
  - retrieval query expansion (직전 answer 첫 200자 concat).
  - Aborted vs Completed semantics — ask 는 single-shot 이라 cancel
    시 partial token + grounded=false + LlmStreamAborted refusal
    (variant 추가는 p9-fb-15 impl 가 함께).
- docs/wire-schema/v1/answer.schema.json: 두 필드 추가 +
  created_at 에 format: date-time (sibling ingest_progress.v1 와
  일관).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 22:09:34 +00:00
a166b7051c p0-1: wire-schema stubs, doc/spec stubs, V001 migration, fixtures
- docs/wire-schema/v1/ ships 7 schema stubs (citation, search_hit,
  answer, ingest_report, doc_summary, chunk_inspection, doctor) that
  pin schema_version + required fields per design §2. Full property
  validation lands in later phases.
- docs/spec/ ships 7 markdown stubs each linking to the canonical
  frozen design (domain-model, ids, canonical-document, chunk-policy,
  citation-policy, module-boundaries, ai-generation-guidelines).
- migrations/V001__init.sql contains only schema_meta + migrations
  tables per design §5.1; data tables ship in P1-6/P2-1/P3-3.
- fixtures/ has the 11 subdirectories every downstream task references
  (markdown, source-fs, search/{lexical,hybrid}, embed, vector, rag,
  eval, image, pdf, audio). Empty subdirs use .gitkeep so they track.
  fixtures/markdown/ ships the 3 phase-0 fixtures: simple-note.md,
  nested-headings.md, code-and-table.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 05:17:32 +00:00