refactor(spec): introduce kb-parse-types thin crate #2

Merged
altair823 merged 1 commits from refactor/parse-types-crate into main 2026-04-27 20:43:22 +00:00
Owner

요약

PR #1 follow-up. review 에서 design debt 로 reserve 한 ParsedBlockkb-core 침투 문제를 해소.

kb-core 와 parsers/normalize 사이에 새 thin crate kb-parse-types 도입. ParsedBlock (+ P6/P7/P8 forward-refs) 가 거기 머문다. core 는 도메인 모델만, parsers 는 자기 라이브러리 의존만, normalize 는 parser 직접 import 없이 input 형태 알 수 있음.

P0 가 시작되기 전에 처리 → 코드 0줄 영향, 데이터 마이그레이션 0건.

의존 그래프 변경

Before                              After
------                              -----
kb-core (ParsedBlock 포함)           kb-core (도메인만)
   ▲                                    ▲
   │                                    │
parsers, normalize                   kb-parse-types ◀── parsers
                                        ▲
                                        │
                                     normalize

kb-normalize 는 이제 kb-parse-md 를 import 하지 않고도 Vec<ParsedBlock> 를 받을 수 있음 (kb-parse-types::ParsedBlock 사용).

변경 파일

파일 변경
docs/superpowers/specs/2026-04-27-kb-final-form-design.md §3.7b 신설 (kb-parse-types 정의), §8 module-boundary 갱신
tasks/p0/p0-1-skeleton.md workspace member 에 추가, public surface 에 kb-parse-types 블록
tasks/p1/p1-3-parse-md-blocks.md output type 을 Vec<kb_parse_types::ParsedBlock> 로 변경, Allowed deps 에 kb-parse-types 추가
tasks/p1/p1-4-normalize.md Allowed deps 에 kb-parse-types 추가, "ParsedBlock 을 core 로 이동" 노트 제거
tasks/INDEX.md, tasks/phase-0-skeleton.md P0 산출 crate 목록에 kb-parse-types 합류

디자인 결정

  1. Inlinekb-core 에 유지 (도메인 타입). kb-parse-types::ParsedPayload 가 이를 참조. 두 crate 에 중복 정의 금지 — 그러면 normalize 가 identity-conversion 만 하게 되어 무의미.
  2. SourceSpankb-core 유지 — parse-types 가 참조.
  3. P6/P7/P8 forward-refs (ParsedImageRegion, ParsedPdfPage, ParsedAudioSegment) 는 §3.7b 에 stub 만 두고 해당 phase task 에서 채움.
  4. kb-parse-types 자체는 serde/thiserror 외부 의존 외에 어떤 parser 라이브러리도 가지지 않음 (pulldown-cmark 등은 parsers crate 에 격리).

검토 포인트

  1. §3.7b — 새 섹션. ParsedBlock/ParsedPayload 타입 정의 + Inline 는 core 에 머문다는 결정.
  2. §8 module-boundarykb-parse-types 행 추가. parsers/normalize → kb-parse-types 단방향 의존.
  3. p0-1 public surface — kb-parse-types 블록 새로 추가. workspace member + Cargo dep 갱신.
  4. p1-4 Forbiddenkb-parse-md (외 parser crates) 가 cargo tree 에 나타나지 않아야 함을 DoD 에 명시.

Out of scope

  • 새 task spec 추가는 없음 — kb-parse-types crate 자체 구현은 P0 (p0-1) task 안에서 이뤄짐.
  • 다른 component spec (P2~P9) 은 ParsedBlock 미참조라 무영향.
## 요약 PR #1 follow-up. review 에서 design debt 로 reserve 한 **`ParsedBlock` 의 `kb-core` 침투** 문제를 해소. `kb-core` 와 parsers/normalize 사이에 새 thin crate **`kb-parse-types`** 도입. `ParsedBlock` (+ P6/P7/P8 forward-refs) 가 거기 머문다. core 는 도메인 모델만, parsers 는 자기 라이브러리 의존만, normalize 는 parser 직접 import 없이 input 형태 알 수 있음. **P0 가 시작되기 전**에 처리 → 코드 0줄 영향, 데이터 마이그레이션 0건. ## 의존 그래프 변경 ``` Before After ------ ----- kb-core (ParsedBlock 포함) kb-core (도메인만) ▲ ▲ │ │ parsers, normalize kb-parse-types ◀── parsers ▲ │ normalize ``` `kb-normalize` 는 이제 `kb-parse-md` 를 import 하지 않고도 `Vec<ParsedBlock>` 를 받을 수 있음 (`kb-parse-types::ParsedBlock` 사용). ## 변경 파일 | 파일 | 변경 | |------|------| | `docs/superpowers/specs/2026-04-27-kb-final-form-design.md` | §3.7b 신설 (kb-parse-types 정의), §8 module-boundary 갱신 | | `tasks/p0/p0-1-skeleton.md` | workspace member 에 추가, public surface 에 kb-parse-types 블록 | | `tasks/p1/p1-3-parse-md-blocks.md` | output type 을 `Vec<kb_parse_types::ParsedBlock>` 로 변경, Allowed deps 에 kb-parse-types 추가 | | `tasks/p1/p1-4-normalize.md` | Allowed deps 에 kb-parse-types 추가, "ParsedBlock 을 core 로 이동" 노트 제거 | | `tasks/INDEX.md`, `tasks/phase-0-skeleton.md` | P0 산출 crate 목록에 kb-parse-types 합류 | ## 디자인 결정 1. **`Inline` 은 `kb-core` 에 유지** (도메인 타입). `kb-parse-types::ParsedPayload` 가 이를 *참조*. 두 crate 에 중복 정의 금지 — 그러면 normalize 가 identity-conversion 만 하게 되어 무의미. 2. **`SourceSpan` 도 `kb-core` 유지** — parse-types 가 참조. 3. P6/P7/P8 forward-refs (`ParsedImageRegion`, `ParsedPdfPage`, `ParsedAudioSegment`) 는 §3.7b 에 stub 만 두고 해당 phase task 에서 채움. 4. `kb-parse-types` 자체는 `serde`/`thiserror` 외부 의존 외에 어떤 parser 라이브러리도 가지지 않음 (`pulldown-cmark` 등은 parsers crate 에 격리). ## 검토 포인트 1. **§3.7b** — 새 섹션. ParsedBlock/ParsedPayload 타입 정의 + Inline 는 core 에 머문다는 결정. 2. **§8 module-boundary** — `kb-parse-types` 행 추가. parsers/normalize → kb-parse-types 단방향 의존. 3. **p0-1 public surface** — kb-parse-types 블록 새로 추가. workspace member + Cargo dep 갱신. 4. **p1-4 Forbidden** — `kb-parse-md` (외 parser crates) 가 cargo tree 에 나타나지 않아야 함을 DoD 에 명시. ## Out of scope - 새 task spec 추가는 없음 — `kb-parse-types` crate 자체 구현은 P0 (p0-1) task 안에서 이뤄짐. - 다른 component spec (P2~P9) 은 ParsedBlock 미참조라 무영향.
altair823 added 1 commit 2026-04-27 20:42:07 +00:00
PR #1 review left a design-debt note: ParsedBlock landing in kb-core would
(a) force every crate to recompile on parser-internal changes, and
(b) cause namespace pollution when P6/P7/P8 parsers add their own variants.

Resolution: a new thin crate kb-parse-types sits between kb-core and parsers.
Owns ParsedBlock + ParsedPayload + Warning + forward-refs for image/pdf/audio
parser intermediates. Depends on kb-core only (for SourceSpan / Inline).

Updates:
- design §3.7b: add new section defining kb-parse-types
- design §8: add kb-parse-types to module-boundary diagram + forbidden list
- design §3.4 Inline stays in kb-core; kb-parse-types references it (no duplication)
- p0-1 skeleton: workspace + Cargo deps + public surface block
- p1-3 parse-md-blocks: outputs Vec<kb_parse_types::ParsedBlock> directly
- p1-4 normalize: Allowed gains kb-parse-types, drops cross-coupling note
- INDEX + phase-0 epic: list kb-parse-types in P0 deliverables
claude-reviewer-01 approved these changes 2026-04-27 20:43:12 +00:00
claude-reviewer-01 left a comment
Member

APPROVE — 9fa3854

Tight, surgical refactor. PR #1 review 의 design debt 가 정확히 해소됨. core 와 parsers 사이 layering 이 깔끔해지고, P6/P7/P8 미래 변종도 forward-decl 로 슬롯 마련.

핵심 결정:

  1. kb-parse-types 는 thin crate, kb-core 만 의존. parser 라이브러리 0건.
  2. Inline 같은 도메인 타입은 core 에 머물고 parse-types 가 참조 — identity-conversion 회피.
  3. kb-normalize Forbidden + DoD cargo tree 검증으로 의존 침범 차단.

frozen design 변경 (§3.7b 신설, §8 갱신) 도 additive — 기존 spec 깨짐 0. 30 component spec 중 영향받은 건 p0-1 / p1-3 / p1-4 셋뿐.

머지 가능. inline comment 5개 모두 praise.

## APPROVE — `9fa3854` **Tight, surgical refactor.** PR #1 review 의 design debt 가 정확히 해소됨. core 와 parsers 사이 layering 이 깔끔해지고, P6/P7/P8 미래 변종도 forward-decl 로 슬롯 마련. 핵심 결정: 1. `kb-parse-types` 는 thin crate, kb-core 만 의존. parser 라이브러리 0건. 2. `Inline` 같은 도메인 타입은 core 에 머물고 parse-types 가 *참조* — identity-conversion 회피. 3. `kb-normalize` Forbidden + DoD `cargo tree` 검증으로 의존 침범 차단. frozen design 변경 (§3.7b 신설, §8 갱신) 도 additive — 기존 spec 깨짐 0. 30 component spec 중 영향받은 건 p0-1 / p1-3 / p1-4 셋뿐. 머지 가능. inline comment 5개 모두 praise.
@@ -600,6 +600,69 @@ pub enum AudioType { M4a, Mp3, Wav, Flac, Ogg, Other(String) }
`OffsetDateTime``time::OffsetDateTime`, `Result` 는 crate-local alias.
### 3.7b Parser intermediate types — `kb-parse-types`

Praise. §3.7b 신설은 design debt 의 정확한 해결. parser 중간 표현이 core 가 아니라 별도 thin crate 에 머무는 게 옳음. 향후 ParsedImageRegion / ParsedPdfPage / ParsedAudioSegment 가 합류할 슬롯도 미리 forward-decl 로 잡혀 있어 P6/P7/P8 task 가 design doc 변경 없이 정의를 채울 수 있음.

**Praise.** §3.7b 신설은 design debt 의 정확한 해결. parser 중간 표현이 core 가 아니라 별도 thin crate 에 머무는 게 옳음. 향후 `ParsedImageRegion` / `ParsedPdfPage` / `ParsedAudioSegment` 가 합류할 슬롯도 미리 forward-decl 로 잡혀 있어 P6/P7/P8 task 가 design doc 변경 없이 정의를 채울 수 있음.
@@ -603,0 +651,4 @@
pub enum WarningKind { MalformedFrontmatter, MalformedTable, EncodingFallback, ExtractFailed }
```
`Inline``kb-core` (§3.4) 에 있는 도메인 타입. `kb-parse-types` 는 그것을 *참조* 만 한다 — 같은 의미를 두 crate 에 중복 정의하지 않는다 (그러면 normalize 가 identity-conversion 을 해야 해서 무의미).

Praise. Inline 을 core 에 유지하고 kb-parse-types참조 만 한다는 결정 좋음. 만약 두 곳에 중복 정의했다면 normalize 가 kb_parse_types::Inline → kb_core::Inline identity-conversion 을 끝없이 작성하게 됐을 것. 도메인 vs intermediate 분리는 명확하지만 공통 도메인 타입 은 한 곳에 — 정확한 구분.

**Praise.** `Inline` 을 core 에 유지하고 `kb-parse-types` 는 *참조* 만 한다는 결정 좋음. 만약 두 곳에 중복 정의했다면 normalize 가 `kb_parse_types::Inline → kb_core::Inline` identity-conversion 을 끝없이 작성하게 됐을 것. 도메인 vs intermediate 분리는 명확하지만 *공통 도메인 타입* 은 한 곳에 — 정확한 구분.
@@ -1164,11 +1229,15 @@ kb-cli, kb-tui, kb-desktop
└─> kb-core (모두 의존)
```
`kb-parse-types``kb-core` 와 parsers/normalize 사이의 thin layer (§3.7b 참조). parser-별 중간 표현 (`ParsedBlock`, `ParsedImageRegion`, `ParsedPdfPage`, `ParsedAudioSegment`, `Inline`) 을 한 곳에 모아 (a) `kb-core` 의 namespace 폭발을 막고 (b) `kb-normalize` 가 parser 를 직접 import 하지 않게 한다.

Praise. §8 boundary 표에 kb-parse-types 가 자연스럽게 합류했고 단방향 의존 (parsers, normalize → kb-parse-types) 이 명시. CI deny rule 로 강제 가능한 형태. "kb-parse-types → 어떤 parser/normalize/store/llm/embed/search/rag/ui ✗" 한 줄로 thin-layer 정체성을 잠금.

**Praise.** §8 boundary 표에 `kb-parse-types` 가 자연스럽게 합류했고 단방향 의존 (`parsers, normalize → kb-parse-types`) 이 명시. CI deny rule 로 강제 가능한 형태. "kb-parse-types → 어떤 parser/normalize/store/llm/embed/search/rag/ui ✗" 한 줄로 thin-layer 정체성을 잠금.
@@ -231,2 +232,4 @@
```
```rust
// ── kb-parse-types ──────────────────────────────────────────────────────────

Praise. p0-1 안에 kb-parse-types public surface 블록을 fully spec 한 것 좋음 — 별도 task 로 분리하지 않고 P0 안에 합쳐 한 PR 로 정착시키는 결정이 가벼우면서도 충분. workspace member + Cargo dep + Forbidden 까지 coherent.

**Praise.** p0-1 안에 `kb-parse-types` public surface 블록을 fully spec 한 것 좋음 — 별도 task 로 분리하지 않고 P0 안에 합쳐 한 PR 로 정착시키는 결정이 가벼우면서도 충분. workspace member + Cargo dep + Forbidden 까지 coherent.
@@ -101,3 +100,2 @@
- [ ] Determinism test runs ≥ 1000 iterations under 1 second
- [ ] No `kb-parse-md` import (consumed via `kb-core::ParsedBlock`)
- [ ] PR links design §4.2, §4.3
- [ ] No `kb-parse-md` (or any other parser crate) appears in `cargo tree -p kb-normalize` — input types come from `kb-parse-types` only

Praise. DoD 에 "kb-parse-md (or any other parser crate) does not appear in cargo tree -p kb-normalize" 명시 — 의존 침범을 사람이 잊어도 CI 가 잡는 형태. 단순한 "forbidden 목록" 보다 verifiable acceptance 가 진짜 가드.

**Praise.** DoD 에 "`kb-parse-md` (or any other parser crate) does not appear in `cargo tree -p kb-normalize`" 명시 — 의존 침범을 사람이 잊어도 CI 가 잡는 형태. 단순한 "forbidden 목록" 보다 verifiable acceptance 가 진짜 가드.
altair823 merged commit c29ccc7925 into main 2026-04-27 20:43:22 +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#2