feat: v0.17.0 PR-B — C typedef-wrapped struct/enum/union → typedef alias unit #160

Merged
altair823 merged 2 commits from feat/c-typedef-struct-unit into main 2026-05-24 20:33:17 +00:00
Owner

요약

v0.17.0 release 의 두 번째 PR (PR-A = 한국어 trigram tokenizer, PR-C = code_lang_chunk_breakdown additive 와 동행). HOTFIXES 2026-05-21 의 "C typedef struct {...} Foo; 가 glue 로 떨어져 alias Foo 미캡처" 항목 closure.

crates/kebab-parse-code/src/c.rs::extract_blockstype_definition 분기 추가 — inner anonymous struct_specifier / enum_specifier / union_specifier (name field 없음) 일 때 declarator field 의 type_identifier 를 재귀 추출해 typedef alias 이름의 synthetic unit 방출. named inner aggregate (typedef struct Pt {...} P;) 와 plain alias (typedef int MyInt;) 는 기존대로 glue (v2 의 1차 범위는 top-level typedef-wrapped anonymous aggregate 만). PARSER_VERSION code-c-v1code-c-v2 bump 동반.

설계: docs/superpowers/specs/2026-05-22-korean-trigram-tokenizer-design.md §5
계획: docs/superpowers/plans/2026-05-22-korean-trigram-tokenizer.md PR-B

변경 요약

  • extractor: crates/kebab-parse-code/src/c.rstype_definition 분기 + recover_typedef_alias + extract_typedef_alias_name 두 helper. anonymous-aggregate 일 때만 fire (named 는 conservative None — 1B Python class-nesting 패턴과 align).
  • parser_version bump: PARSER_VERSION = "code-c-v2". design §9 cascade — doc_id = (workspace_path, asset_id, parser_version) 가 새 parser_version 으로 새 doc_id 계산.
  • orphan purge cascade: crates/kebab-store-sqlite/src/store.rs 에 두 helper 신규:
    • stale_chunk_ids_for_workspace_path_except_doc_id(workspace_path, keep_doc_id) — sister of stale_chunk_ids_at (그쪽은 asset_id 기반), 본 helper 는 doc_id 기반. keep_doc_id="" 가 sentinel "모든 doc 제거".
    • purge_document_at_workspace_path_except_doc_id(workspace_path, keep_doc_id) — CASCADE document → blocks/chunks/embedding_records. assets row 보존 (same bytes, same asset_id).
  • ingest 분기 통합: crates/kebab-app/src/lib.rs::try_skip_unchanged 의 parser_mismatch 분기에서 purge_workspace_path_for_parser_bump wrapper 호출. helper 가 app.vector() 로 LanceDB 접근 + delete_by_chunk_ids + SQLite document row 제거. cleanup 끝나면 Ok(None) 반환 → caller 가 새 doc_id 로 INSERT, idx_docs_workspace_path UNIQUE 충돌 없음.
  • docs: HOTFIXES 2026-05-21 typedef 항목 closure (Status/Next step) + 새 2026-05-24 PR-B closure entry, tasks/p10/p10-1d-c-cpp-ast-chunker.md Risks line 갱신.

사용자 가시 영향

  • typedef struct {...} Foo; 의 alias FooCitation::Code.symbol 으로 search 노출.
  • 기존 v0.16.x KB 의 C 파일은 v0.17.0 binary 로 다음 kebab ingest자동 재처리 (parser_version mismatch → cleanup → 새 doc). ���시적 re-ingest 명령 불필요.
  • 기존 bytes-edit 경로 (asset_id 변경) 의 cleanup 은 그대로 — 신규 분기와 공존, 회귀 없음.

검증

  • 신규 unit tests:
    • c_extractor_typedef_struct_emits_unitPoint alias 가 unit (이전 hotfix 의 _falls_into_glue test rename + assertion 반전).
    • c_extractor_typedef_enum_emits_unitColor alias.
    • c_extractor_typedef_union_emits_unitIntOrFloat alias.
    • c_extractor_typedef_to_existing_type_stays_glue — negative case (typedef int MyInt;<module>).
  • tier1_c_ingest_searchable: parser_version assertion code-c-v1code-c-v2.
  • cargo test --workspace --no-fail-fast -j 1 + cargo clippy --workspace --all-targets -- -D warnings 통과.

시험 항목 (Test Plan)

  • 실 C 코드 (linux kernel header 일부 또는 libuv) 를 v0.16.x KB 로 ingest → v0.17.0 binary 로 같은 dir 재 ingest → typedef alias 가 search hit 으로 나오는지 확인. 옛 doc/chunks row 잔존 없음 검증.
  • kebab.sqlite 크기 비교 (v0.16.x vs v0.17.0 backfill 후) — 큰 변화 없어야 (FTS shadow 영향 PR-A 와 별개, PR-B 자체는 chunks count 약간 증가 + parser bump cascade 한 번).
  • nested typedef (typedef struct { struct {...} inner; } Outer;) → inner 는 glue 로 남음을 확인 (v2 의 1차 범위).

Assisted-by: Claude Code

## 요약 v0.17.0 release 의 두 번째 PR (PR-A = 한국어 trigram tokenizer, PR-C = `code_lang_chunk_breakdown` additive 와 동행). HOTFIXES 2026-05-21 의 "C `typedef struct {...} Foo;` 가 glue 로 떨어져 alias `Foo` 미캡처" 항목 closure. `crates/kebab-parse-code/src/c.rs::extract_blocks` 에 `type_definition` 분기 추가 — inner anonymous `struct_specifier` / `enum_specifier` / `union_specifier` (name field 없음) 일 때 `declarator` field 의 type_identifier 를 재귀 추출해 typedef alias 이름의 synthetic unit 방출. named inner aggregate (`typedef struct Pt {...} P;`) 와 plain alias (`typedef int MyInt;`) 는 기존대로 glue (v2 의 1차 범위는 top-level typedef-wrapped anonymous aggregate 만). `PARSER_VERSION` `code-c-v1` → `code-c-v2` bump 동반. 설계: docs/superpowers/specs/2026-05-22-korean-trigram-tokenizer-design.md §5 계획: docs/superpowers/plans/2026-05-22-korean-trigram-tokenizer.md PR-B ## 변경 요약 - **extractor**: `crates/kebab-parse-code/src/c.rs` — `type_definition` 분기 + `recover_typedef_alias` + `extract_typedef_alias_name` 두 helper. anonymous-aggregate 일 때만 fire (named 는 conservative None — 1B Python class-nesting 패턴과 align). - **parser_version bump**: `PARSER_VERSION = "code-c-v2"`. design §9 cascade — `doc_id = (workspace_path, asset_id, parser_version)` 가 새 parser_version 으로 새 doc_id 계산. - **orphan purge cascade**: `crates/kebab-store-sqlite/src/store.rs` 에 두 helper 신규: - `stale_chunk_ids_for_workspace_path_except_doc_id(workspace_path, keep_doc_id)` — sister of `stale_chunk_ids_at` (그쪽은 asset_id 기반), 본 helper 는 doc_id 기반. `keep_doc_id=""` 가 sentinel "모든 doc 제거". - `purge_document_at_workspace_path_except_doc_id(workspace_path, keep_doc_id)` — CASCADE document → blocks/chunks/embedding_records. `assets` row 보존 (same bytes, same asset_id). - **ingest 분기 통합**: `crates/kebab-app/src/lib.rs::try_skip_unchanged` 의 parser_mismatch 분기에서 `purge_workspace_path_for_parser_bump` wrapper 호출. helper 가 `app.vector()` 로 LanceDB 접근 + `delete_by_chunk_ids` + SQLite document row 제거. cleanup 끝나면 `Ok(None)` 반환 → caller 가 새 doc_id 로 INSERT, `idx_docs_workspace_path` UNIQUE 충돌 없음. - **docs**: HOTFIXES 2026-05-21 typedef 항목 closure (Status/Next step) + 새 2026-05-24 PR-B closure entry, `tasks/p10/p10-1d-c-cpp-ast-chunker.md` Risks line 갱신. ## 사용자 가시 영향 - `typedef struct {...} Foo;` 의 alias `Foo` 가 `Citation::Code.symbol` 으로 search 노출. - 기존 v0.16.x KB 의 C 파일은 v0.17.0 binary 로 다음 `kebab ingest` 시 **자동 재처리** (parser_version mismatch → cleanup → 새 doc). ���시적 re-ingest 명령 불필요. - 기존 bytes-edit 경로 (asset_id 변경) 의 cleanup 은 그대로 — 신규 분기와 공존, 회귀 없음. ## 검증 - 신규 unit tests: - `c_extractor_typedef_struct_emits_unit` — `Point` alias 가 unit (이전 hotfix 의 `_falls_into_glue` test rename + assertion 반전). - `c_extractor_typedef_enum_emits_unit` — `Color` alias. - `c_extractor_typedef_union_emits_unit` — `IntOrFloat` alias. - `c_extractor_typedef_to_existing_type_stays_glue` — negative case (`typedef int MyInt;` → `<module>`). - `tier1_c_ingest_searchable`: parser_version assertion `code-c-v1` → `code-c-v2`. - `cargo test --workspace --no-fail-fast -j 1` + `cargo clippy --workspace --all-targets -- -D warnings` 통과. ## 시험 항목 (Test Plan) - [ ] 실 C 코드 (linux kernel header 일부 또는 libuv) 를 v0.16.x KB 로 ingest → v0.17.0 binary 로 같은 dir 재 ingest → typedef alias 가 search hit 으로 나오는지 확인. 옛 doc/chunks row 잔존 없음 검증. - [ ] `kebab.sqlite` 크기 비교 (v0.16.x vs v0.17.0 backfill 후) — 큰 변화 없어야 (FTS shadow 영향 PR-A 와 별개, PR-B 자체는 chunks count 약간 증가 + parser bump cascade 한 번). - [ ] nested typedef (`typedef struct { struct {...} inner; } Outer;`) → inner 는 glue 로 남음을 확인 (v2 의 1차 범위). Assisted-by: Claude Code
altair823 added 2 commits 2026-05-24 20:32:50 +00:00
closure of HOTFIXES 2026-05-21. C typedef-wrapped anonymous
struct/enum/union 이 typedef alias 이름으로 symbol unit 방출.

- crates/kebab-parse-code/src/c.rs: type_definition 분기 추가.
  inner anonymous struct_specifier / enum_specifier / union_specifier
  탐지 → declarator field 의 type_identifier 재귀 추출 → synthetic
  unit (typedef alias). named inner aggregate / plain alias 는
  기존대로 glue. PARSER_VERSION code-c-v1 → code-c-v2.
  recover_typedef_alias + extract_typedef_alias_name helper 추가.

- crates/kebab-store-sqlite/src/store.rs: 두 helper 신규
  (parser_version bump cascade 용 doc-id 기반 orphan purge).
  - stale_chunk_ids_for_workspace_path_except_doc_id(workspace_path,
    keep_doc_id) — sister of stale_chunk_ids_at, doc_id 기반.
  - purge_document_at_workspace_path_except_doc_id(workspace_path,
    keep_doc_id) — CASCADE document/chunks 제거, assets 보존.
  keep_doc_id="" 가 "모든 doc 제거" 사용.

- crates/kebab-app/src/lib.rs: try_skip_unchanged 의 parser_mismatch
  분기에서 purge_workspace_path_for_parser_bump 호출. helper 가
  app.vector() 로 lazy 접근 + delete_by_chunk_ids + SQLite document
  row 제거. Ok(None) 반환 전 cleanup 끝나서 caller 의 새 INSERT 시
  idx_docs_workspace_path UNIQUE 충돌 회피.

- tests:
  - c.rs unit tests 4 신규 — typedef_struct_emits_unit /
    typedef_enum_emits_unit / typedef_union_emits_unit /
    typedef_to_existing_type_stays_glue (negative).
  - tier1_c_ingest_searchable: parser_version assertion code-c-v1 →
    code-c-v2.
- 회귀: bytes-edit 경로 (asset_id 변경) 의 기존 purge_orphan_at_workspace_path
  + purge_vector_orphans_for_workspace_path 는 그대로 — 신규 분기와
  공존, 기존 test 모두 PASS.

미해결 (Risks): nested typedef (typedef struct { struct {...} inner; }
Outer;) 의 inner 익명 struct 는 여전히 glue — v2 의 1차 범위는
top-level typedef alias 만.

cargo test --workspace --no-fail-fast -j 1 + clippy 통과.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- tasks/HOTFIXES.md: 새 2026-05-24 PR-B closure entry — extractor 의
  type_definition 분기, PARSER_VERSION bump, same-workspace_path
  orphan purge, 사용자 영향, 잔여 nested typedef Risks.
- tasks/HOTFIXES.md: 기존 2026-05-21 typedef 항목의 Status / Next step
  을 v0.17.0 closure 표현으로 갱신 (관찰 기록은 frozen 유지).
- tasks/p10/p10-1d-c-cpp-ast-chunker.md: Risks 의 typedef idiom 라인
  을 closure  + 잔여 nested typedef 안내로 갱신.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
altair823 force-pushed feat/c-typedef-struct-unit from 51eae314e7 to 70a5068c0d 2026-05-24 20:32:50 +00:00 Compare
altair823 merged commit ff9d5f5f86 into main 2026-05-24 20:33:17 +00:00
altair823 deleted branch feat/c-typedef-struct-unit 2026-05-24 20:33:18 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: altair823-org/kebab#160