refactor(parse-md): absorb kebab-normalize + kebab-parse-types — 24 → 22 crates + §3.7b 재작성 #186

Merged
altair823 merged 1 commits from refactor/normalize-absorption into main 2026-05-26 15:37:24 +00:00
Owner

요약

kebab-normalize (1097 LOC, build_canonical_document + derive_title) + kebab-parse-types (98 LOC, 5 사용 type + 3 forward-declared struct) 두 crate 를 kebab-parse-md 로 흡수. 24 → 22 crates + frozen design §3.7b 4-단락 재작성 + §8 graph 갱신 + HOTFIXES design deviation entry.

medium-agnostic lift layer (kebab-normalize) 가 markdown 만 통과하는 reality 와 design §3.7b 의 intent (4 parser 통합 lift) 갭 해소 — 4 parser 중 md 만 lift 경유, 3 parser (pdf/image/code) 가 CanonicalDocument 직접 emit 으로 lift bypass. 흡수 후 kebab-parse-md 가 multi-parser lift 의 single destination — future image/pdf normalize integration (v0.20+) 의 base.

설계: docs/superpowers/specs/2026-05-26-normalize-absorption-spec.md (3 round APPROVE)
계획: docs/superpowers/plans/2026-05-26-normalize-absorption-plan.md (3 round ACCEPT)

핵심 변경

  • kebab-parse-md::types 신설 (98 LOC) — 5 사용 type (ParsedBlock / ParsedBlockKind / ParsedPayload / Warning / WarningKind) + 3 forward-declared struct (ParsedImageRegion / ParsedPdfPage / ParsedAudioSegment) 모두 byte-identical 이식. 3 dead struct 는 보존 (future re-extraction trigger 대비 — spec §11).
  • kebab-parse-md::normalize 신설 (1097 LOC) — build_canonical_document + derive_title + warning_agent + 6 hard-coded literal (tracing target target: "kebab-normalize" + 5 agent string "kb-source-fs"/"kb-parse-md"/"kb-normalize") 모두 byte-identical 이식 (stage label 일관성 — SQLite audit log + tracing log grep 호환).
  • kebab-parse-md/Cargo.tomlkebab-parse-types regular dep 제거 + unicode-normalization = "0.1" 추가 (NFKC 의존성 흡수) + description 갱신.
  • kebab-app callsite migrationlib.rs:51 import path + :1119 context string. :1308 + :1474 historical comment 는 보존 (git blame 일관성 + reader 가 흡수 history 추적 가능).
  • chunk + store-sqlite dev-dep migration + 통합 test source use 갱신.
  • design §3.7b 4-단락 재작성 (strike 아닌 재작성) — original intent + reality + 보존된 surface + future re-extraction trigger 명시. design intent 자체는 유효 (multi-region image, multi-block pdf 가능 시 재추출 trigger), 단 현재는 dead abstraction.
  • design §8 graph — 3 edge 제거 (parse-md → parse-types, normalize → parse-types, kebab-normalize entry) + 2 forbidden bullet 의미 갱신 + commentary 한 줄 (기존 parse-* → store/llm/embed ✗ 룰이 흡수된 lift 까지 자동 포함).
  • workspace.members 24 → 22 + workspace.package.version 0.18.0 → 0.19.0 (frozen design contract 변경 trigger — CLAUDE.md "Release / binary version bump" 룰).
  • HOTFIXES.md — 신규 entry (4-block 변형 "design deviation — post-PR9 audit identified dead abstraction") + tasks/INDEX.md "Future work / deferred" 섹션 신설 + L169 v0.18.1+ defer mention closure + image/pdf normalize integration entry.
  • ARCHITECTURE.md Mermaid graph 갱신 (2 노드 + 4 edge 제거) + crate tree 정리 + v0.19.0 흡수 mention.
  • HANDOFF.md "머지 후 발견된 버그 / 결정 (요약)" 의 최상단 cross-link.

OMC review history

Phase A (spec, 3 round):

  • analyst (Phase A read-only): evidence chain investigation, 6 open question. Write/Edit 차단으로 planner agent 위임.
  • planner (spec drafter): spec body 작성, 1068 lines, 11 main sections + 67 sub-headers.
  • critic round 1: 22 finding (3 CRITICAL + 8 MAJOR + 4 MINOR + 2 NIT + 6 missing + 2 ambiguity) — CRITICAL #1 signature byte-mismatch (asset: &RawAsset vs spec &AssetInfo, metadata: Metadata by-value vs spec &Metadata, derive_title&[Block] vs spec &[ParsedBlock]) / CRITICAL #2 dev-dep direction 부정확 / CRITICAL #3 §11 미존재 (false-positive, line 793 실존 verified)
  • critic round 2: 6 NEW finding (2 NEW MAJOR + 3 MINOR + 1 NIT) — tracing target literal 자동 derive 가정 부정확 (lib.rs:109 explicit literal) / warning_agent body = "kb-parse-md" 단일 return + 5 hard-coded "kb-normalize" 위치 분리 명시 / line ref stale 갱신 / R9/R10 ordering swap
  • critic round 3: APPROVE — 28 finding 모두 closed (1 false-positive 포함) + 2 NIT (metadata only)

Phase B (plan, 3 round):

  • planner (15-step decompose): 885 lines plan, 15 step + 9 main sections.
  • critic-plan round 1 (2 CRITICAL + 4 MAJOR + 3 MINOR + 1 NIT) + verifier-plan round 1 (2 BLOCKER + 3 MAJOR + 3 MINOR) — unicode-normalization 신규 dep 누락 / pub use kebab_core::{id_for_*} 제거 시 in-body unqualified call 깨짐 / parse-md tests/ stale import / blocks.rs 의 4 hit file-wide replace 누락 / Step 7 verify self-contradiction
  • critic-plan round 2 (3 CRITICAL + 2 MAJOR): blocks.rs:1589 fully-qualified path 누락 / parse-md/tests/ stale ref / parse-md/Cargo.toml unicode-normalization 미추가 / doc-comment 정책 / kebab-app:1308/1474 historical comment
  • verifier-plan round 2: ACCEPT — 8 gap closure + 15-step A grade
  • critic-plan round 3: APPROVE — 5/5 closure 정확 + 0 CRITICAL/MAJOR 신규 + 3 MINOR wording (non-blocking)

Implementation (executor):

  • 15 step + 1 clean commit (710945c)
  • 27 file changed: 2 new (types.rs + normalize.rs) + 17 modified + 2 deleted (kebab-normalize/ + kebab-parse-types/ 디렉토리) + 1 renamed (normalize_snapshot.rs test) + 4 doc updated (design + ARCHITECTURE + INDEX + HOTFIXES + HANDOFF)

검증

11 acceptance gate (plan §4 + Step 15 exit gate)

  • cargo test -p kebab-parse-md -j 1green (workspace test 안 통과)
  • cargo test -p kebab-chunk/store-sqlite -j 1green
  • cargo build -p kebab-app -j 1 + cargo tree -p kebab-app --depth 2 | grep -E "kebab_(parse_types|normalize)" | wc -l0 줄
  • cargo metadata --no-deps | jq '.workspace_members | length'22
  • cargo test --workspace --no-fail-fast -j 11313 PASS, 0 failed (spec §5.1 expected baseline 과 byte-identical match, net delta = 0)
  • cargo clippy --workspace --all-targets -j 1 -- -D warningsclean (5m 46s, 0 warning)
  • cargo build --release -p kebab-cli -j 1clean (36m 20s, 0 warning, binary 262M, kebab-cli v0.19.0)
  • cargo deny check → CI 검증 (본 머신 미설치)

Literal preservation verify

  • grep -c 'target: "kebab-normalize"' crates/kebab-parse-md/src/normalize.rs1 (tracing target 보존)
  • grep -cE 'agent:\s*"kb-(source-fs|parse-md|normalize)"\.to_string\(\)' crates/kebab-parse-md/src/normalize.rs4 (4 hard-coded literal 보존)
  • grep -c "kebab_parse_types::" crates/kebab-parse-md/src/normalize.rs0 (9 hit fully-qualified path 갈음 후)

Source migration verify

  • grep -rn "kebab_parse_types" crates/kebab-parse-md/ production hit → 0 (doc-comment 의 historical mention 3 hit 만 — production code 0)
  • grep -rn "kebab_normalize\|kebab_parse_types" crates/kebab-app/src/0 (line 51/1119 갱신, 1308/1474 comment 보존)

Doc + frozen contract verify

  • design §3.7b + §8 갱신 — 의미상 2 logical section (raw hunk count 5 — multi-paragraph replace 의 unchanged line split)
  • grep -c "design deviation — post-PR9 audit" tasks/HOTFIXES.md1
  • grep -c "## Future work / deferred" tasks/INDEX.md1
  • git diff main..HEAD --name-only | grep "^tasks/p"0 (~25 referencing task spec frozen 유지)
  • git diff main..HEAD -- docs/wire-schema/v1/0 (wire schema 변경 0)

Cargo.lock + version cascade

  • Cargo.lockkebab-normalize + kebab-parse-types [[package]] entry → 0 (자동 cleanup)
  • 22 kebab-* crate 모두 v0.19.0 cascade 적용 (workspace.package version inherit)

Wire / 변경 없음

  • wire schema (docs/wire-schema/v1/*.json): 변경 0
  • CLI / TUI / MCP user-facing surface: 변경 0
  • README: 변경 0 (사용자 visible surface 0)
  • warning_agent("kb-...") return string: 보존 (SQLite documents.provenance_json BLOB persist, wire-invisible — spec §1.9 의 16-row production flow trace 검증)
  • tracing::debug!(target: "kebab-normalize", ...) literal: 보존 (log scraper grep 일관성)
  • ~25 referencing task spec (tasks/p<N>/): frozen 유지 — CLAUDE.md "Task specs themselves stay frozen as the historical contract" + HOTFIXES.md live source 룰
  • 4 frozen task spec (p1-2, p1-3, p1-4, p9-fb-07): frozen 유지 (id_for_* re-export 후퇴는 production caller 0 검증)
  • Cargo features: 변경 0
  • parser_version cascade: 변경 0

workspace.package.version 0.18.0 → 0.19.0 (minor bump) 가 internal Rust crate-API surface 의 이동에 따른 design contract 변경 trigger — 사용자 docpfood 영향 0 이지만 CLAUDE.md "Release / binary version bump" 의 "frozen design contract 변경 머지 후" trigger 충족.

시험 항목 (Test Plan)

  • cargo test --workspace --no-fail-fast -j 1 → 1313 PASS 그대로 (net delta = 0)
  • cargo metadata --no-deps | jq '.workspace_members | length' → 22
  • cargo build --release -p kebab-cli -j 1 → green (binary 262M, v0.19.0)
  • cargo clippy --workspace --all-targets -j 1 -- -D warnings → clean
  • grep -c "kebab_parse_types::" crates/kebab-parse-md/src/ → 0
  • design §3.7b 재작성 + §8 graph 갱신 (post-merge dogfood 시 contract reader 가 reality 정합 확인)

Assisted-by: Claude Code

## 요약 `kebab-normalize` (1097 LOC, build_canonical_document + derive_title) + `kebab-parse-types` (98 LOC, 5 사용 type + 3 forward-declared struct) 두 crate 를 `kebab-parse-md` 로 흡수. 24 → 22 crates + frozen design §3.7b 4-단락 재작성 + §8 graph 갱신 + HOTFIXES design deviation entry. medium-agnostic lift layer (`kebab-normalize`) 가 markdown 만 통과하는 reality 와 design §3.7b 의 intent (4 parser 통합 lift) 갭 해소 — 4 parser 중 md 만 lift 경유, 3 parser (pdf/image/code) 가 `CanonicalDocument` 직접 emit 으로 lift bypass. 흡수 후 `kebab-parse-md` 가 multi-parser lift 의 single destination — future image/pdf normalize integration (v0.20+) 의 base. 설계: docs/superpowers/specs/2026-05-26-normalize-absorption-spec.md (3 round APPROVE) 계획: docs/superpowers/plans/2026-05-26-normalize-absorption-plan.md (3 round ACCEPT) ## 핵심 변경 - **`kebab-parse-md::types` 신설** (98 LOC) — 5 사용 type (`ParsedBlock` / `ParsedBlockKind` / `ParsedPayload` / `Warning` / `WarningKind`) + 3 forward-declared struct (`ParsedImageRegion` / `ParsedPdfPage` / `ParsedAudioSegment`) 모두 byte-identical 이식. 3 dead struct 는 **보존** (future re-extraction trigger 대비 — spec §11). - **`kebab-parse-md::normalize` 신설** (1097 LOC) — `build_canonical_document` + `derive_title` + `warning_agent` + 6 hard-coded literal (tracing target `target: "kebab-normalize"` + 5 agent string `"kb-source-fs"`/`"kb-parse-md"`/`"kb-normalize"`) 모두 byte-identical 이식 (stage label 일관성 — SQLite audit log + tracing log grep 호환). - **`kebab-parse-md/Cargo.toml`** — `kebab-parse-types` regular dep 제거 + `unicode-normalization = "0.1"` 추가 (NFKC 의존성 흡수) + description 갱신. - **kebab-app callsite migration** — `lib.rs:51` import path + `:1119` context string. `:1308` + `:1474` historical comment 는 *보존* (git blame 일관성 + reader 가 흡수 history 추적 가능). - **chunk + store-sqlite dev-dep migration** + 통합 test source `use` 갱신. - **design §3.7b 4-단락 재작성** (strike 아닌 재작성) — original intent + reality + 보존된 surface + future re-extraction trigger 명시. design intent 자체는 유효 (multi-region image, multi-block pdf 가능 시 재추출 trigger), 단 현재는 dead abstraction. - **design §8 graph** — 3 edge 제거 (`parse-md → parse-types`, `normalize → parse-types`, `kebab-normalize entry`) + 2 forbidden bullet 의미 갱신 + commentary 한 줄 (기존 `parse-* → store/llm/embed ✗` 룰이 흡수된 lift 까지 자동 포함). - **`workspace.members`** 24 → 22 + **`workspace.package.version`** 0.18.0 → **0.19.0** (frozen design contract 변경 trigger — CLAUDE.md "Release / binary version bump" 룰). - **HOTFIXES.md** — 신규 entry (4-block 변형 "design deviation — post-PR9 audit identified dead abstraction") + `tasks/INDEX.md` "Future work / deferred" 섹션 신설 + L169 v0.18.1+ defer mention closure + image/pdf normalize integration entry. - **ARCHITECTURE.md** Mermaid graph 갱신 (2 노드 + 4 edge 제거) + crate tree 정리 + v0.19.0 흡수 mention. - **HANDOFF.md** "머지 후 발견된 버그 / 결정 (요약)" 의 최상단 cross-link. ## OMC review history **Phase A (spec, 3 round)**: - analyst (Phase A read-only): evidence chain investigation, 6 open question. Write/Edit 차단으로 planner agent 위임. - planner (spec drafter): spec body 작성, 1068 lines, 11 main sections + 67 sub-headers. - critic round 1: 22 finding (3 CRITICAL + 8 MAJOR + 4 MINOR + 2 NIT + 6 missing + 2 ambiguity) — CRITICAL #1 signature byte-mismatch (`asset: &RawAsset` vs spec `&AssetInfo`, `metadata: Metadata` by-value vs spec `&Metadata`, `derive_title` 의 `&[Block]` vs spec `&[ParsedBlock]`) / CRITICAL #2 dev-dep direction 부정확 / CRITICAL #3 §11 미존재 (false-positive, line 793 실존 verified) - critic round 2: 6 NEW finding (2 NEW MAJOR + 3 MINOR + 1 NIT) — tracing target literal 자동 derive 가정 부정확 (lib.rs:109 explicit literal) / warning_agent body = "kb-parse-md" 단일 return + 5 hard-coded "kb-normalize" 위치 분리 명시 / line ref stale 갱신 / R9/R10 ordering swap - critic round 3: APPROVE — 28 finding 모두 closed (1 false-positive 포함) + 2 NIT (metadata only) **Phase B (plan, 3 round)**: - planner (15-step decompose): 885 lines plan, 15 step + 9 main sections. - critic-plan round 1 (2 CRITICAL + 4 MAJOR + 3 MINOR + 1 NIT) + verifier-plan round 1 (2 BLOCKER + 3 MAJOR + 3 MINOR) — `unicode-normalization` 신규 dep 누락 / `pub use kebab_core::{id_for_*}` 제거 시 in-body unqualified call 깨짐 / parse-md tests/ stale import / blocks.rs 의 4 hit file-wide replace 누락 / Step 7 verify self-contradiction - critic-plan round 2 (3 CRITICAL + 2 MAJOR): blocks.rs:1589 fully-qualified path 누락 / parse-md/tests/ stale ref / parse-md/Cargo.toml unicode-normalization 미추가 / doc-comment 정책 / kebab-app:1308/1474 historical comment - verifier-plan round 2: ACCEPT — 8 gap closure + 15-step A grade - critic-plan round 3: APPROVE — 5/5 closure 정확 + 0 CRITICAL/MAJOR 신규 + 3 MINOR wording (non-blocking) **Implementation (executor)**: - 15 step + 1 clean commit (`710945c`) - 27 file changed: 2 new (types.rs + normalize.rs) + 17 modified + 2 deleted (kebab-normalize/ + kebab-parse-types/ 디렉토리) + 1 renamed (normalize_snapshot.rs test) + 4 doc updated (design + ARCHITECTURE + INDEX + HOTFIXES + HANDOFF) ## 검증 ### 11 acceptance gate (plan §4 + Step 15 exit gate) - `cargo test -p kebab-parse-md -j 1` → **green** (workspace test 안 통과) - `cargo test -p kebab-chunk/store-sqlite -j 1` → **green** - `cargo build -p kebab-app -j 1` + `cargo tree -p kebab-app --depth 2 | grep -E "kebab_(parse_types|normalize)" | wc -l` → **0 줄** - `cargo metadata --no-deps | jq '.workspace_members | length'` → **22** - `cargo test --workspace --no-fail-fast -j 1` → **1313 PASS, 0 failed** (spec §5.1 expected baseline 과 byte-identical match, net delta = 0) - `cargo clippy --workspace --all-targets -j 1 -- -D warnings` → **clean** (5m 46s, 0 warning) - `cargo build --release -p kebab-cli -j 1` → **clean** (36m 20s, 0 warning, binary **262M**, kebab-cli v0.19.0) - `cargo deny check` → CI 검증 (본 머신 미설치) ### Literal preservation verify - `grep -c 'target: "kebab-normalize"' crates/kebab-parse-md/src/normalize.rs` → **1** (tracing target 보존) - `grep -cE 'agent:\s*"kb-(source-fs|parse-md|normalize)"\.to_string\(\)' crates/kebab-parse-md/src/normalize.rs` → **4** (4 hard-coded literal 보존) - `grep -c "kebab_parse_types::" crates/kebab-parse-md/src/normalize.rs` → **0** (9 hit fully-qualified path 갈음 후) ### Source migration verify - `grep -rn "kebab_parse_types" crates/kebab-parse-md/` production hit → **0** (doc-comment 의 historical mention 3 hit 만 — production code 0) - `grep -rn "kebab_normalize\|kebab_parse_types" crates/kebab-app/src/` → **0** (line 51/1119 갱신, 1308/1474 comment 보존) ### Doc + frozen contract verify - design §3.7b + §8 갱신 — 의미상 2 logical section (raw hunk count 5 — multi-paragraph replace 의 unchanged line split) - `grep -c "design deviation — post-PR9 audit" tasks/HOTFIXES.md` → **1** - `grep -c "## Future work / deferred" tasks/INDEX.md` → **1** - `git diff main..HEAD --name-only | grep "^tasks/p"` → **0** (~25 referencing task spec frozen 유지) - `git diff main..HEAD -- docs/wire-schema/v1/` → **0** (wire schema 변경 0) ### Cargo.lock + version cascade - `Cargo.lock` 의 `kebab-normalize` + `kebab-parse-types` `[[package]]` entry → **0** (자동 cleanup) - 22 kebab-* crate 모두 `v0.19.0` cascade 적용 (workspace.package version inherit) ## Wire / 변경 없음 - wire schema (`docs/wire-schema/v1/*.json`): 변경 0 - CLI / TUI / MCP user-facing surface: 변경 0 - README: 변경 0 (사용자 visible surface 0) - `warning_agent("kb-...")` return string: 보존 (SQLite `documents.provenance_json` BLOB persist, wire-invisible — spec §1.9 의 16-row production flow trace 검증) - `tracing::debug!(target: "kebab-normalize", ...)` literal: 보존 (log scraper grep 일관성) - ~25 referencing task spec (`tasks/p<N>/`): frozen 유지 — CLAUDE.md "Task specs themselves stay frozen as the historical contract" + HOTFIXES.md live source 룰 - 4 frozen task spec (p1-2, p1-3, p1-4, p9-fb-07): frozen 유지 (id_for_* re-export 후퇴는 production caller 0 검증) - Cargo features: 변경 0 - `parser_version` cascade: 변경 0 `workspace.package.version` 0.18.0 → 0.19.0 (minor bump) 가 internal Rust crate-API surface 의 이동에 따른 design contract 변경 trigger — 사용자 docpfood 영향 0 이지만 CLAUDE.md "Release / binary version bump" 의 "frozen design contract 변경 머지 후" trigger 충족. ## 시험 항목 (Test Plan) - [ ] `cargo test --workspace --no-fail-fast -j 1` → 1313 PASS 그대로 (net delta = 0) - [ ] `cargo metadata --no-deps | jq '.workspace_members | length'` → 22 - [ ] `cargo build --release -p kebab-cli -j 1` → green (binary 262M, v0.19.0) - [ ] `cargo clippy --workspace --all-targets -j 1 -- -D warnings` → clean - [ ] `grep -c "kebab_parse_types::" crates/kebab-parse-md/src/` → 0 - [ ] design §3.7b 재작성 + §8 graph 갱신 (post-merge dogfood 시 contract reader 가 reality 정합 확인) Assisted-by: Claude Code
altair823 added 1 commit 2026-05-26 15:29:41 +00:00
design §3.7b 의 thin layer (ParsedBlock 류) 가 4 parser 중 1개 (markdown) 만 lift 를
경유하는 현실 — fan-in/fan-out 모두 1 → layer 의미 잃음. kebab-normalize (1097 LOC)
+ kebab-parse-types (98 LOC) 둘을 kebab-parse-md 로 흡수.

설계: docs/superpowers/specs/2026-05-26-normalize-absorption-spec.md
플랜: docs/superpowers/plans/2026-05-26-normalize-absorption-plan.md
HOTFIXES: tasks/HOTFIXES.md 의 2026-05-26 entry (design deviation)

- 5 사용 type + 3 forward-declared struct → kebab-parse-md::types module 의 pub explicit re-export.
- build_canonical_document + derive_title + warning_agent → kebab-parse-md::normalize module.
- 4 hard-coded agent literal (lib.rs:122/128/134/153) + warning_agent body return + tracing target literal 모두 보존 — stage label 일관성.
- kebab-app callsite (lib.rs:51 use + :1119 context string) + Cargo.toml 의 2 dep (regular + dead) 제거.
- kebab-chunk + kebab-store-sqlite 의 [dev-dependencies] kebab-normalize → 제거 (kebab-parse-md 로 갈음). 통합 test source 의 use shift.
- test file 이동 (kebab-normalize/tests/normalize_snapshot.rs → kebab-parse-md/tests/).
- workspace Cargo.toml: Hunk (a) members 2 entry 삭제 + Hunk (b) version 0.18.0 → 0.19.0 (frozen contract 변경).
- design §3.7b 4-단락 재작성 (원래 intent 보존 + 현재 상태 + 보존된 surface + future re-extraction trigger).
- design §8 graph 갱신 (3 edge 제거 + 2 forbidden bullet 의미 갱신 + commentary).
- ARCHITECTURE.md crate graph + directory tree mechanical 갱신.
- tasks/INDEX.md L169 closure mention + "Future work / deferred" 섹션 신설 (image/pdf normalize integration entry).
- tasks/HOTFIXES.md 신규 entry (4-block — design deviation Symptom).
- HANDOFF.md cross-link 한 줄.
- 3 dead struct (ParsedImageRegion / ParsedPdfPage / ParsedAudioSegment) 는 보존 — v0.20+ image/pdf normalize integration 의 future surface (spec §11).

Wire / surface impact: 0건. CLI / TUI / MCP / --json 출력 / config / XDG path /
parser_version 모두 unchanged. wire-invisible provenance.events[].agent + tracing target
literal "kb-normalize" 도 보존 — old DB row 와 new DB row 의 audit log 일관성.

Verification: cargo test --workspace --no-fail-fast -j 1 → 1313 passed / 0 failed (172 result blocks).
cargo clippy --workspace --all-targets -j 1 -- -D warnings → 0 warning (5m 46s).
cargo metadata --no-deps --format-version 1 | jq '.workspace_members | length' = 22.
cargo tree -p kebab-app --depth 2 | grep -E "kebab_(parse_types|normalize)" = 0 줄.
claude-reviewer-01 approved these changes 2026-05-26 15:30:38 +00:00
claude-reviewer-01 left a comment
Member

회차 1 — normalize + parse-types absorption refactor 검토.

OMC team normalize-absorption 의 3-round spec APPROVE (analyst → planner spec drafter → 3 critic round) + 3-round plan ACCEPT (planner → 3 round critic-plan + 2 round verifier-plan) 의 모든 closure 결과가 본 PR 의 코드에 정확히 reflect. workspace 1313 tests + 11 acceptance gate 모두 green.

칭찬 (산문):

  1. design intent 자체 보존하는 §3.7b 4-단락 재작성 — spec round 1 critic 의 핵심 질문 ("§3.7b 의 raison d'être 가 dead 인데 strike 가 정답?") 에 대한 답이 strike 아닌 4-단락 재작성 (original intent + reality + 보존된 surface + future re-extraction trigger). 사용자 결정 (dead struct 3 보존 — future surface 명시) + multi-region image / multi-block pdf 의 future trigger 가능성이 design contract 의 raison d'être 와 align. ~25 referencing task spec 의 historical contract 인용도 의미적 backward-compat.

  2. signature byte-identical 보존의 micro-precision — spec round 1 CRITICAL #1 의 발견 (asset: &RawAsset vs spec 초안 &AssetInfo, metadata: Metadata by-value vs &Metadata, derive_title&[Block] lifted vs &[ParsedBlock] pre-lift) 가 plan + executor 단계까지 정확히 propagate. 특히 derive_title&[Block] (lift 이후 호출) 의 의미적 구분이 보존되어 caller 가 type-error 회피.

  3. unicode-normalization dep silent drop 회피 — plan round 1 critic CRITICAL #1 + verifier GAP2 둘 다 잡은 결함 (spec §3.4 의 hunk 가 plan 의 어느 step 에도 명시 안 됨). round 2 reflection 으로 Step 3 Action (e) 신설 + Cargo.toml hunk + exit gate grep -c "unicode-normalization" ≥ 1 모두 closure. executor 단계에서 actual lib.rs:31 의 use 가 normalize.rs 동반 이식 시 unresolved crate error 회피.

  4. pub use kebab_core::{id_for_*} 제거의 in-body call resolve 정합 — plan round 1 critic CRITICAL #2 의 발견 (re-export 제거 시 current module scope import 도 동시 사라져 unqualified call 깨짐). round 2 reflection 으로 Step 3 Action (d) 가 기존 use kebab_core::{Block, BlockId, ...} block 에 id_for_block, id_for_doc 추가 명시. line 67 + 241 의 unqualified call resolve 보장.

  5. stage label 보존 정책의 일관성tracing::debug!(target: "kebab-normalize", ...) (lib.rs:109) + 4 hard-coded agent: "kb-..." literal (lib.rs:122/128/134/143/153) 모두 보존. log scraper grep 일관성 + SQLite documents.provenance_json BLOB 의 audit log 일관성. spec round 2 critic NEW MAJOR #N1 (자동 module-path derive 가정 부정확) + NEW MAJOR #N2 (warning_agent body = "kb-parse-md" 단일 return vs 5 hard-coded literal 분리) 의 closure 가 executor 단계까지 정확 transcribe.

  6. 9 hit fully-qualified path file-wide replace — executor self-detect (plan round 2) — actual kebab-normalize/src/lib.rs 의 9 hit kebab_parse_types::ParsedBlockKind::* (line 29 use + line 489/498/507/516/525/818/862/1070) 가 normalize.rs 이식 시 동반. sed file-wide replace 로 crate::types:: 갈음 + exit gate grep -c "kebab_parse_types::" = 0 검증.

  7. kebab-parse-md/tests/ stale ref 누락 회피 — verifier round 1 BLOCKER #1 의 발견 (tests/blocks_snapshots.rs:19 + frontmatter_snapshots.rs:23 의 stale import) 가 round 2 reflection 으로 Step 5 file list + Action (c)(d) + exit gate scope 확장 (src/ 한정 해제). integration test 는 crate:: 사용 불가 → kebab_parse_md::* 사용으로 정확 갈음.

  8. frozen task spec 보존 + HOTFIXES live source 룰 준수 — CLAUDE.md "Task specs themselves stay frozen as the historical contract" rule 정확 적용. git diff main..HEAD --name-only | grep "^tasks/p" = 0 line (~25 referencing task spec mechanical update 0). HOTFIXES 신규 entry (4-block 변형, design deviation — post-PR9 audit identified dead abstraction) + INDEX.md "Future work / deferred" 섹션 신설 + L169 v0.18.1+ defer mention closure + image/pdf normalize integration entry 한 줄. spec §11 cross-link 정확.

  9. workspace.package.version 0.18.0 → 0.19.0 cascade — CLAUDE.md "Release / binary version bump" 의 "frozen design contract 변경 머지 후" trigger 정확. 22 kebab-* crate 모두 version = { workspace = true } 로 자동 cascade — release binary 262M 의 v0.19.0 stamp 확인.

  10. workspace 회귀 net delta = 0 의 정량 검증 — spec §5.1 expected baseline (1313) 과 post-refactor cargo test --workspace --no-fail-fast -j 1 결과 (1313 PASS, 0 failed) byte-identical match. 13 test 1:1 이동 (12 unit + 1 integration via normalize_snapshot.rs rename) + 모든 test 함수 보존. release binary 262M + 0 warning + 0 error.

추가 actionable 없음. 26 file changed (production scope 27 unique paths), 모든 11 acceptance gate green. Wire / CLI / TUI / MCP / README 변경 0, 사용자 docpfood 영향 0. internal Rust crate-API surface 만 이동 (8 type + 2 fn re-export 가 kebab_parse_md::* 로 symmetric 이동).

머지 OK. 머지 후 gitea-release v0.19.0 (CLAUDE.md "Release 절차" 룰) 으로 release tag 컷 권장 — frozen design contract 변경 + workspace.package version bump 가 새 release cut trigger. 다음 작업 (Lens 3 Extractor + Chunker dispatch unification, 1d medium risk) 동일 spec/plan/review/PR 사이클로 진행 — sonnet 모델 routing 정책 (closure verify round 2+) 적용.

회차 1 — normalize + parse-types absorption refactor 검토. OMC team `normalize-absorption` 의 3-round spec APPROVE (analyst → planner spec drafter → 3 critic round) + 3-round plan ACCEPT (planner → 3 round critic-plan + 2 round verifier-plan) 의 모든 closure 결과가 본 PR 의 코드에 정확히 reflect. workspace 1313 tests + 11 acceptance gate 모두 green. 칭찬 (산문): 1. **design intent 자체 보존하는 §3.7b 4-단락 재작성** — spec round 1 critic 의 핵심 질문 ("§3.7b 의 raison d'être 가 dead 인데 strike 가 정답?") 에 대한 답이 strike 아닌 4-단락 재작성 (original intent + reality + 보존된 surface + future re-extraction trigger). 사용자 결정 (dead struct 3 보존 — future surface 명시) + multi-region image / multi-block pdf 의 future trigger 가능성이 design contract 의 raison d'être 와 align. ~25 referencing task spec 의 historical contract 인용도 의미적 backward-compat. 2. **signature byte-identical 보존의 micro-precision** — spec round 1 CRITICAL #1 의 발견 (`asset: &RawAsset` vs spec 초안 `&AssetInfo`, `metadata: Metadata` by-value vs `&Metadata`, `derive_title` 의 `&[Block]` lifted vs `&[ParsedBlock]` pre-lift) 가 plan + executor 단계까지 정확히 propagate. 특히 `derive_title` 의 `&[Block]` (lift *이후* 호출) 의 의미적 구분이 보존되어 caller 가 type-error 회피. 3. **`unicode-normalization` dep silent drop 회피** — plan round 1 critic CRITICAL #1 + verifier GAP2 둘 다 잡은 결함 (spec §3.4 의 hunk 가 plan 의 어느 step 에도 명시 안 됨). round 2 reflection 으로 Step 3 Action (e) 신설 + Cargo.toml hunk + exit gate `grep -c "unicode-normalization" ≥ 1` 모두 closure. executor 단계에서 actual lib.rs:31 의 use 가 normalize.rs 동반 이식 시 unresolved crate error 회피. 4. **`pub use kebab_core::{id_for_*}` 제거의 in-body call resolve 정합** — plan round 1 critic CRITICAL #2 의 발견 (re-export 제거 시 current module scope import 도 동시 사라져 unqualified call 깨짐). round 2 reflection 으로 Step 3 Action (d) 가 기존 `use kebab_core::{Block, BlockId, ...}` block 에 `id_for_block, id_for_doc` 추가 명시. line 67 + 241 의 unqualified call resolve 보장. 5. **stage label 보존 정책의 일관성** — `tracing::debug!(target: "kebab-normalize", ...)` (lib.rs:109) + 4 hard-coded `agent: "kb-..."` literal (lib.rs:122/128/134/143/153) 모두 보존. log scraper grep 일관성 + SQLite `documents.provenance_json` BLOB 의 audit log 일관성. spec round 2 critic NEW MAJOR #N1 (자동 module-path derive 가정 부정확) + NEW MAJOR #N2 (warning_agent body = "kb-parse-md" 단일 return vs 5 hard-coded literal 분리) 의 closure 가 executor 단계까지 정확 transcribe. 6. **9 hit fully-qualified path file-wide replace** — executor self-detect (plan round 2) — actual `kebab-normalize/src/lib.rs` 의 9 hit `kebab_parse_types::ParsedBlockKind::*` (line 29 use + line 489/498/507/516/525/818/862/1070) 가 normalize.rs 이식 시 동반. sed file-wide replace 로 `crate::types::` 갈음 + exit gate `grep -c "kebab_parse_types::" = 0` 검증. 7. **`kebab-parse-md/tests/` stale ref 누락 회피** — verifier round 1 BLOCKER #1 의 발견 (`tests/blocks_snapshots.rs:19` + `frontmatter_snapshots.rs:23` 의 stale import) 가 round 2 reflection 으로 Step 5 file list + Action (c)(d) + exit gate scope 확장 (`src/` 한정 해제). integration test 는 `crate::` 사용 불가 → `kebab_parse_md::*` 사용으로 정확 갈음. 8. **frozen task spec 보존 + HOTFIXES live source 룰 준수** — CLAUDE.md "Task specs themselves stay frozen as the historical contract" rule 정확 적용. `git diff main..HEAD --name-only | grep "^tasks/p"` = 0 line (~25 referencing task spec mechanical update 0). HOTFIXES 신규 entry (4-block 변형, design deviation — post-PR9 audit identified dead abstraction) + INDEX.md "Future work / deferred" 섹션 신설 + L169 v0.18.1+ defer mention closure + image/pdf normalize integration entry 한 줄. spec §11 cross-link 정확. 9. **`workspace.package.version` 0.18.0 → 0.19.0 cascade** — CLAUDE.md "Release / binary version bump" 의 "frozen design contract 변경 머지 후" trigger 정확. 22 kebab-* crate 모두 `version = { workspace = true }` 로 자동 cascade — release binary 262M 의 v0.19.0 stamp 확인. 10. **workspace 회귀 net delta = 0 의 정량 검증** — spec §5.1 expected baseline (1313) 과 post-refactor `cargo test --workspace --no-fail-fast -j 1` 결과 (1313 PASS, 0 failed) byte-identical match. 13 test 1:1 이동 (12 unit + 1 integration via normalize_snapshot.rs rename) + 모든 test 함수 보존. release binary 262M + 0 warning + 0 error. 추가 actionable 없음. 26 file changed (production scope 27 unique paths), 모든 11 acceptance gate green. Wire / CLI / TUI / MCP / README 변경 0, 사용자 docpfood 영향 0. internal Rust crate-API surface 만 이동 (8 type + 2 fn re-export 가 `kebab_parse_md::*` 로 symmetric 이동). 머지 OK. 머지 후 `gitea-release v0.19.0` (CLAUDE.md "Release 절차" 룰) 으로 release tag 컷 권장 — frozen design contract 변경 + workspace.package version bump 가 새 release cut trigger. 다음 작업 (Lens 3 Extractor + Chunker dispatch unification, 1d medium risk) 동일 spec/plan/review/PR 사이클로 진행 — sonnet 모델 routing 정책 (closure verify round 2+) 적용.
altair823 merged commit 96766406aa into main 2026-05-26 15:37:24 +00:00
altair823 deleted branch refactor/normalize-absorption 2026-05-26 15:37:25 +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#186