diff --git a/docs/superpowers/plans/2026-06-03-remove-doc-expansion-plan.md b/docs/superpowers/plans/2026-06-03-remove-doc-expansion-plan.md new file mode 100644 index 0000000..ce4f50d --- /dev/null +++ b/docs/superpowers/plans/2026-06-03-remove-doc-expansion-plan.md @@ -0,0 +1,49 @@ +# Plan: doc-side expansion(별칭) 제거 구현 + +spec: `docs/superpowers/specs/2026-06-03-remove-doc-expansion-spec.md`. 브랜치 `refactor/remove-doc-expansion`. 빌드 `CARGO_TARGET_DIR=/build/out/cargo-target`, 직렬 `-j 4`(전체 테스트는 `-j 1`). + +원칙: 작은 단위로 컴파일 가능 상태 유지. 각 단계 후 `cargo build -p -j 4`. 최종 clippy+test. + +## Task 1 — kebab-core: Chunk.aliases 필드 제거 +- `chunk.rs`: `pub aliases: Option` + serde default + `aliases_defaults_to_none_on_deserialize` 테스트 제거. +- **금지**: `metadata.rs` `Metadata.aliases`(Vec) 는 손대지 않음. +- 컴파일 깨짐 → Task 2~ 에서 Chunk 리터럴 정리하며 해소. + +## Task 2 — Chunk 리터럴 정리 (kebab-chunk/*, kebab-parse-*/*, store-sqlite, app) +- `grep -rn "aliases: None" crates/*/src` 로 Chunk 생성부 전수 → `aliases: None,` 줄 삭제. +- store-sqlite `documents.rs`: chunks INSERT 컬럼리스트/바인딩에서 `aliases` 제거(line ~126/156), SELECT 매핑의 aliases 제거, `aliases: None`(271) 제거. + +## Task 3 — kebab-app: expansion 모듈 + 루프 제거 +- `lib.rs`: `pub mod expansion;` 삭제, `expansion.rs` 파일 삭제. +- ingest_one_asset: expansion 블록 전체(`if app.config.ingest.expansion.enabled { … }` + `alias_version_key`/`alias_cache_*`/`alias_touch_keys`/embed_aliases 임베딩/sentinel 벡터 생성) 제거. `expansion_ms` 타이밍은 0 고정 또는 AssetTimings 에서 필드 유지하되 항상 0 — **AssetTimings 의 expansion_ms 필드는 유지(wire 호환)**, 값 0. +- alias sentinel 벡터 upsert 경로 제거, purge_vector_orphans 는 본문 벡터 정리로 유지. + +## Task 4 — kebab-config: ExpansionCfg 제거 +- `lib.rs`: `ExpansionCfg` struct + `IngestCfg.expansion` 필드 + Default 제거. +- `migrate.rs`: `[ingest.expansion]` 처리/주석 제거. +- config 직렬화 테스트에서 expansion 기대 제거. + +## Task 5 — kebab-search: alias lexical arm 제거 +- `lexical.rs`: `run_alias_query`, `merge_body_alias`, alias 분기 제거. body_rows 직접 사용으로 단순화. alias 관련 테스트 제거/갱신. + +## Task 6 — wire/progress 정리 +- `kebab-app/ingest_progress.rs`: `IngestEvent::ExpansionProgress` variant + 직렬화 테스트 제거. AssetChunked/AssetTimings 유지. +- `kebab-cli/progress.rs`, `kebab-tui/ingest_progress.rs`: ExpansionProgress 매치/렌더 제거. +- `kebab-tui/inspect.rs`: 별칭 표시 제거. +- `docs/wire-schema/v1/ingest_progress.schema.json`: expansion_progress kind 제거. + +## Task 7 — sqlite 마이그레이션: DROP chunk_aliases_fts + chunks.aliases +- `schema.rs`(refinery 마이그레이션 등록부) 확인 → 신규 forward 마이그레이션 추가: `DROP TABLE IF EXISTS chunk_aliases_fts` (+ 관련 트리거/shadow 테이블 chunk_aliases_fts_*), `ALTER TABLE chunks DROP COLUMN aliases`. +- chunk_aliases_fts 를 만들던 기존 마이그레이션은 **수정 금지**(과거 마이그레이션 freeze) — 새 마이그레이션으로 덮어 제거. +- `tests/chunk_aliases.rs` 삭제. `tests/migration.rs` 신규 마이그레이션 반영. +- 번들 sqlite DROP COLUMN 지원 확인(3.35+); 미지원이면 테이블 재생성 패턴. + +## Task 8 — 검증 + 문서 +- `cargo clippy --workspace --all-targets -j 4 -- -D warnings`. +- `cargo test --workspace --no-fail-fast -j 1`. +- fresh KB `.schema` 로 chunk_aliases_fts/aliases 부재 확인. `kebab ingest` 스모크(별칭 config 없이). +- grep 잔존 0 (spec Acceptance 의 정규식). +- 문서: HOTFIXES dated entry, 2026-05-30 doc-expansion-design spec Risks/notes cross-link, HANDOFF 1줄, wire schema, design 본문 removed 주석, Cargo.toml version bump. + +## 리뷰 루프 +구현 완료 → `gitea-pr`(title `refactor(app): doc-side expansion(별칭) 제거`, body 요약/검증) → gitea-pr 리뷰 루프(actionable 해소까지) → 사용자 머지. diff --git a/docs/superpowers/specs/2026-06-03-remove-doc-expansion-spec.md b/docs/superpowers/specs/2026-06-03-remove-doc-expansion-spec.md new file mode 100644 index 0000000..5aebd40 --- /dev/null +++ b/docs/superpowers/specs/2026-06-03-remove-doc-expansion-spec.md @@ -0,0 +1,55 @@ +# Spec: doc-side expansion(별칭) 기능 제거 + +**날짜**: 2026-06-03 +**유형**: 기능 제거 (refactor/removal) +**근거**: `docs/superpowers/research/2026-06-03-expansion-cost-rethink-research.md` (Step 0/1 측정 + 딥리서치). 별칭 ROI 음수: cross-lingual 은 e5-large 단독으로 이미 완벽, 별칭 기여는 설명형 +2 그룹뿐인데 대가가 청크당 색인-시 LLM(살아있는 KB 에 지속 불가). 문헌(arXiv 2309.08541)도 "강한 검색기엔 expansion 해롭다" 확인. +**design contract 영향**: design §(Phase 2 doc-side expansion) 에서 도입된 기능 제거 → `tasks/HOTFIXES.md` dated entry + 원 spec(`docs/superpowers/specs/2026-05-30-doc-side-expansion-design.md`)의 Risks/notes 에 제거 cross-link 1줄. design 본문은 별도 spec PR 이 아닌 본 PR 에서 "deprecated/removed" 주석만. + +## 목표 +색인-시 청크당 LLM 별칭 생성 + 별칭 검색 경로를 **완전히 제거**한다. 기본 동작 불변(별칭은 이미 default-off)이라 일반 사용자 체감 0. 코드/스키마/wire 표면을 정리해 유지보수 부담을 없앤다. + +## 제거 대상 (REMOVE) +- `crates/kebab-app/src/expansion.rs` — 모듈 전체 (ExpansionGenerator, is_nav_boilerplate, parse_aliases, strip_list_marker). +- `crates/kebab-app/src/lib.rs` — `pub mod expansion;`, ingest_one_asset 의 expansion 루프(별칭 생성·캐시 조회/저장·`alias_version_key`·`embed_aliases` 임베딩·alias sentinel 벡터 `{orig}#alias#N`), 관련 카운터(`alias_cache_hit/miss`, `alias_touch_keys`). +- `crates/kebab-config/src/lib.rs` — `ExpansionCfg` 구조체 + `IngestCfg.expansion` 필드 + 기본값. +- `crates/kebab-config/src/migrate.rs` — `[ingest.expansion]` 섹션 주석/마이그레이션 처리. +- `crates/kebab-core/src/chunk.rs` — `Chunk.aliases: Option` 필드 (+ 관련 serde default 테스트). **주의: `crates/kebab-core/src/metadata.rs` 의 `Metadata.aliases: Vec` 는 문서 메타데이터(§3.6)로 무관 — 유지.** +- `crates/kebab-search/src/lexical.rs` — `run_alias_query`, `merge_body_alias`, alias FTS 분기(`build_match_string_for_column(.., "aliases")`). +- `crates/kebab-store-sqlite` — `chunk_aliases_fts` 테이블 + 트리거 + `chunks.aliases` 컬럼: **신규 forward 마이그레이션(V0XX)으로 DROP**. INSERT/SELECT 경로(`documents.rs` 의 aliases 컬럼 쓰기/읽기) 제거. +- `crates/kebab-app/src/ingest_progress.rs` — `IngestEvent::ExpansionProgress` variant (+ 직렬화 테스트). **`AssetChunked`/`AssetTimings` 는 유지**(별칭과 무관, 청킹/타이밍 가시성). +- `crates/kebab-cli/src/progress.rs` + `crates/kebab-tui/src/ingest_progress.rs` — ExpansionProgress 렌더(`별칭 확장 N/chunks`). +- `crates/kebab-tui/src/inspect.rs` — chunk 별칭 표시(있으면). +- derivation_cache 의 `"alias"` kind: 쓰기 경로 제거. 기존 행은 무해(읽지 않음), `kebab reset` 시 정리. kind enum 에서 alias 제거는 선택(read 호환 위해 남겨도 무방). + +## 유지 (KEEP — 제거 금지) +- `Metadata.aliases` (문서 메타데이터, metadata.rs). +- `AssetChunked`, `AssetTimings` wire 이벤트 + 렌더. +- derivation_cache 의 `embedding` kind (V012 임베딩 캐시 — 별칭과 독립, 성능 핵심). +- `chunks_fts`(본문 FTS) 전부. +- `Chunk` 구조체를 생성하는 모든 곳(kebab-chunk/*, kebab-parse-*/*): `aliases: None` 리터럴은 필드 제거에 맞춰 **삭제만**(기능 변경 아님). + +## 결정 사항 +- **마이그레이션**: 신규 forward-only 마이그레이션으로 `chunk_aliases_fts`(+ 트리거)와 `chunks.aliases` 컬럼 DROP. SQLite 3.35+ `DROP COLUMN` 사용(번들 sqlite 확인). down 마이그레이션 불필요(refinery forward-only 관행 따름). 기존 KB: 별칭 default-off 라 대부분 빈 데이터 → 손실 없음. corpus_revision cascade 불필요(별칭은 검색 보조였을 뿐, 본문/임베딩 불변). +- **wire schema**: `ingest_progress.v1` 에서 `expansion_progress` kind 제거. v0.24.0 에서 막 추가된 additive variant 라 소비자(agent/CLI)는 부재 허용 → major bump 불요. `docs/wire-schema/v1/ingest_progress.schema.json` 에서 해당 kind 정의 삭제 + 주석. +- **버전**: workspace `version` patch/minor bump(별칭 제거 = surface 정리, breaking schema 아님 — 단 chunk_aliases_fts DROP 마이그레이션 포함이라 이전 binary 가 새 DB 열 때 영향 없음(컬럼 제거는 구 binary 의 SELECT 깨뜨릴 수 있으나 단일 사용자·forward-only 전제). minor bump 권장. +- **config**: `[ingest.expansion]` 제거 후 기존 사용자 config.toml 에 해당 섹션이 있어도 serde forward-compat(unknown field ignore)로 무해. `kebab config migrate` 가 섹션 제거하도록 갱신(선택). + +## 문서 동기화 (같은 PR) +- `tasks/HOTFIXES.md`: dated entry — 제거 근거(연구 링크) + 마이그레이션 + wire 변경. +- `docs/superpowers/specs/2026-05-30-doc-side-expansion-design.md`: Risks/notes 에 "2026-06-03 제거됨, 본 spec 참조" 1줄. +- `README.md` / `HANDOFF.md`: 별칭이 README 에 노출돼 있으면 제거(default-off 라 노출 없을 가능성). HANDOFF 한 줄. +- `docs/wire-schema/v1/ingest_progress.schema.json`: expansion_progress 제거. +- design 본문(frozen contract)에 Phase 2 별칭 기술이 있으면 "removed (HOTFIXES 2026-06-03)" 주석. + +## 검증 기준 (Acceptance) +- `cargo clippy --workspace --all-targets -j 4 -- -D warnings` 통과. +- `cargo test --workspace --no-fail-fast -j 1` 통과 — 별칭 전용 테스트(`tests/chunk_aliases.rs`, expansion.rs 테스트, lexical alias 테스트)는 삭제, 그 외 회귀 0. +- 신규 마이그레이션 적용된 fresh KB 에 `chunk_aliases_fts`/`chunks.aliases` 부재 확인(`.schema`). +- `kebab ingest`(별칭 config 없이) 정상 — AssetChunked/AssetTimings 진행 표시 유지, expansion_progress 미출력. +- 기존 별칭 데이터가 있던 KB 도 마이그레이션 후 search/ask 정상(별칭 벡터는 무시/정리). +- grep 잔존 0: `expansion::|ExpansionCfg|chunk_aliases|run_alias_query|merge_body_alias|ExpansionProgress|embed_aliases|is_nav_boilerplate|Chunk.*aliases`. + +## 비범위 (out of scope) +- 별칭 대체 방법(heading enrichment / arctic-ko 임베더 / reranker / query-side) — 후속 별 작업(연구문서 §7 Layer A~D). +- `Metadata.aliases`(문서 메타) 변경. +- derivation_cache GC wiring.