Skip to content

fix(kiwi): PR #143 후속 — libkiwi 버전 핀(v0.22.2) + FFI ABI 회귀 테스트/CI + 0.23 비호환 발견 - #144

Merged
hang-in merged 2 commits into
mainfrom
feat/kiwi-abi-hardening
Jul 6, 2026
Merged

fix(kiwi): PR #143 후속 — libkiwi 버전 핀(v0.22.2) + FFI ABI 회귀 테스트/CI + 0.23 비호환 발견#144
hang-in merged 2 commits into
mainfrom
feat/kiwi-abi-hardening

Conversation

@hang-in

@hang-in hang-in commented Jul 6, 2026

Copy link
Copy Markdown
Owner

@

배경

#143 이 kiwi-rs 의 kiwi_analyze_option_t ABI 불일치로 인한 secall sync SIGSEGV 를 포크 패치로 해결했습니다. 그 후속으로 (1) 버전 핀, (2) FFI 회귀 테스트를 추가하던 중, 회귀 테스트가 실제 버그를 잡아 방향이 바뀌었습니다.

핵심 발견 (회귀 테스트가 잡음)

fresh 환경에서 정품 libkiwi 0.23.2 로는 seCall 바인딩이 Kiwi::new() (builder/init 경로)에서 SEGFAULT 합니다.

  • 같은 lib+model 로 번들 kiwi-cli-0.23.2 는 정상 분석(아버지/NNG 가/JKS ...) → lib/model 이 아니라 바인딩 문제.
  • probe 로 crash 지점 확정: init (analyze 아님). fix(deps): kiwi-rs libkiwi 0.23 ABI 불일치로 인한 sync 세그폴트 수정 #143 이 고친 건 analyze 경로(KiwiAnalyzeOption)라, init 경로의 0.23 비호환은 미해결 (상류 kiwi-rs 조사 영역).
  • 사용자/CI 실측: 기존에 "0.23.2 설치"로 알던 환경이 실제로는 libkiwi 0.22.2 였음. 0.22.2 는 48B struct 의 32B prefix 만 읽어 안전 → 그래서 무사했던 것.

결론: seCall 은 현재 사실상 libkiwi 0.22.x 전용. 0.23.x 는 수동 설치 시 init crash.

변경

1. 버전 핀 v0.22.2 (tokenizer.rs)

Kiwi::init()Kiwi::init_with_version(KIWI_LIBKIWI_TAG), KIWI_LIBKIWI_TAG = "v0.22.2" (실증된 working 버전). auto-download fallback 에만 영향 (기존 설치 lib 는 Kiwi::new() 가 그대로 사용). 상수 주석에 "0.23+ 로 bump 금지" 경고 명시.

2. kiwi FFI ABI 회귀 테스트 (tokenizer.rs)

test_kiwi_ffi_abi_smoke: 실제 libkiwi 로 kiwi 를 태워 아버지 형태소 검증. env SECALL_KIWI_FFI_TEST=1 opt-in(기본 skip). Windows 컴파일(#133 정합). 이 테스트가 위 0.23 crash 를 잡았음.

3. 전용 CI job (ci.yml)

kiwi-ffi 잡: 인증된 gh release download 로 libkiwi+model(v0.22.2) 직접 provision → KIWI_LIBRARY_PATH/KIWI_MODEL_PATHKiwi::new() 에 전달(다운로드 우회). 필수 test 매트릭스와 분리.

참고: 포크의 런타임 auto-download 는 별개로 깨져 있음 — find_asset_url 이 릴리스 JSON 의 중첩 uploader 객체에서 brace 매칭이 틀어져 asset 을 못 찾음(fresh 설치자 전원 영향). 그래서 CI 는 인증 다운로드로 직접 provision.

검증

  • fresh 0.22.2 provision → env → FFI 테스트 통과 (2.18s). 동일 메커니즘으로 0.23.2 는 init SEGFAULT 재현.
  • secall-core 485 green, clippy -Dwarnings 클린, ci.yml YAML valid.

후속 (별도 트래킹/상류)

  • libkiwi >= 0.23 init 비호환 — kiwi-rs 포크의 init/builder 경로 0.23 대응 필요 (상류 리포트).
  • find_asset_url 다운로드 버그 — 중첩 객체 brace 매칭 (상류 리포트).
  • upstream JAICHANGPARK/kiwi-rs#2 릴리스 시 [patch.crates-io] 제거.
  • (여유 시) libkiwi 버전 감지 후 graceful 경고/에러 — segfault 대신.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LVEL1SnCQBtUMeWVy99ebj
@

Summary by CodeRabbit

  • Bug Fixes
    • 검색 토크나이저가 라이브러리/모델을 고정된 버전 기준으로 초기화해, 다운로드 불일치로 인한 ABI 호환성 문제 가능성을 줄였습니다.
  • Tests
    • FFI 연동 결과를 확인하는 스모크 테스트를 추가해, 설정 시 실제 실행 환경에서 드리프트를 조기 탐지합니다.
  • Chores
    • CI에 별도 회귀 테스트 작업을 보강해 실제 ABI 회귀를 독립적으로 수행하고 탐지 범위를 확대했습니다.

#143 이 kiwi_analyze_option_t ABI 불일치(SIGSEGV)를 포크 패치로 해결했으나 두 gap 잔존:
런타임 libkiwi 다운로드가 `latest` 라 미래 0.24+ 에서 동일 크래시 재발 가능하고,
kiwi FFI 를 태우는 자동 테스트가 없어(모든 kiwi 테스트 #[ignore]) CI 가 ABI drift 를 못 잡음.

- tokenizer.rs: Kiwi::init() → init_with_version(KIWI_LIBKIWI_TAG="v0.23.2").
  컴파일된 struct 레이아웃(48B/7필드)과 다운로드 바이너리 태그를 일치. auto-download
  fallback 에만 영향(기존 설치 lib 는 new() 로 그대로 사용).
- tokenizer.rs: test_kiwi_ffi_abi_smoke — 실제 libkiwi 로 kiwi_analyze 를 태워 '아버지'
  형태소를 검증(ABI drift → SIGSEGV/garbage/fallback → red). env SECALL_KIWI_FFI_TEST
  로 opt-in(기본 skip, 50MB 다운로드 회피). Windows 도 컴파일(#133 정합).
- ci.yml: kiwi-ffi 전용 job — 핀 태그 libkiwi 다운로드+캐시 후 회귀 실행. 네트워크
  flake 가 필수 test 매트릭스를 오염시키지 않도록 분리.

검증: 실제 libkiwi 0.23.2 FFI 통과(크래시 없음), secall-core 485 green, clippy -Dwarnings 클린.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LVEL1SnCQBtUMeWVy99ebj
@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Kiwi 토크나이저가 고정 libkiwi 버전을 사용하도록 바뀌었고, 실제 FFI 분석 결과를 확인하는 스모크 테스트가 추가됐다. 이 테스트를 전용 CI 잡에서 캐시와 함께 다운로드된 libkiwi/모델로 실행한다.

Changes

Kiwi FFI 버전 고정 및 검증

Layer / File(s) Summary
Kiwi 초기화 버전 고정
crates/secall-core/src/search/tokenizer.rs
KIWI_LIBKIWI_TAG 상수가 추가되고 Kiwi 초기화가 고정 버전 경로로 바뀌었으며 관련 설명 문구가 갱신됐다.
ABI 스모크 테스트
crates/secall-core/src/search/tokenizer.rs
SECALL_KIWI_FFI_TEST로 활성화되는 test_kiwi_ffi_abi_smoke가 추가되어 실제 libkiwi 분석 결과를 검증한다.
전용 kiwi-ffi CI 잡
.github/workflows/ci.yml
캐시, cargo-nextest 설치, libkiwi/모델 다운로드, 환경변수 주입, test(kiwi_ffi_abi) 실행 단계를 포함하는 CI 잡이 추가됐다.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

  • hang-in/seCall#143: kiwi-rslibkiwi 간 ABI 불일치 문제를 다루며, 이번 버전 고정과 회귀 테스트와 직접 연결된다.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목이 libkiwi 버전 핀과 FFI ABI 회귀 테스트/CI 추가라는 주요 변경을 정확히 요약합니다.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/kiwi-abi-hardening

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
.github/workflows/ci.yml (1)

118-128: 🗄️ Data Integrity & Integration | 🔵 Trivial | 🏗️ Heavy lift

핀 버전이 두 곳에 중복 정의됨 — 캐시 무효화로 ABI 회귀 탐지가 무력화될 수 있음.

핀 버전 v0.23.2tokenizer.rsKIWI_LIBKIWI_TAG와 이 캐시 키(Line 126, 128)에 각각 하드코딩되어 있습니다. 향후 KIWI_LIBKIWI_TAG만 올리고 여기 캐시 키를 그대로 두면, restore-keys가 이전 버전 libkiwi가 담긴 .kiwi-cache를 복원하고 kiwi-rs가 이를 재사용해 새 버전을 내려받지 않을 수 있습니다. 그 경우 이 잡은 여전히 구버전 libkiwi로 실행되어, 바로 이 잡이 잡아야 할 ABI 드리프트를 놓칠 수 있습니다.

캐시 키를 실제 태그와 동기화되도록(예: 리포지토리에서 KIWI_LIBKIWI_TAG 값을 읽어 키에 주입) 만들거나, 최소한 태그 상수와 캐시 키를 함께 갱신해야 함을 명시하는 주석을 추가하는 것을 권장합니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml around lines 118 - 128, The cache key in the CI
workflow is hardcoded with the libkiwi pin version, which can drift from the
actual tag used elsewhere. Update the cache key and restore-keys in the cache
step to stay in sync with the same source of truth as KIWI_LIBKIWI_TAG from
tokenizer.rs, or add a clear note that both must be updated together. Keep the
unique version segment in the actions/cache configuration aligned with the
libkiwi tag so .kiwi-cache cannot restore stale assets after a tag bump.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/ci.yml:
- Line 113: The checkout step in the CI workflow should explicitly disable
credential persistence because this job downloads and runs an external binary
after fetching the repo. Update the existing actions/checkout@v4 usage to set
persist-credentials to false so no Git credentials remain in .git/config. Keep
the change scoped to the checkout step in the CI workflow.

---

Nitpick comments:
In @.github/workflows/ci.yml:
- Around line 118-128: The cache key in the CI workflow is hardcoded with the
libkiwi pin version, which can drift from the actual tag used elsewhere. Update
the cache key and restore-keys in the cache step to stay in sync with the same
source of truth as KIWI_LIBKIWI_TAG from tokenizer.rs, or add a clear note that
both must be updated together. Keep the unique version segment in the
actions/cache configuration aligned with the libkiwi tag so .kiwi-cache cannot
restore stale assets after a tag bump.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 477a60a2-797a-48f1-afc6-5ec63de4a902

📥 Commits

Reviewing files that changed from the base of the PR and between b63757f and d9d8454.

📒 Files selected for processing (2)
  • .github/workflows/ci.yml
  • crates/secall-core/src/search/tokenizer.rs

Comment thread .github/workflows/ci.yml
name: kiwi FFI ABI regression
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

checkout에 persist-credentials: false 설정 권장.

이 잡은 코드 체크아웃 후 네트워크로 외부 libkiwi 바이너리를 받아 실행합니다. 자격 증명이 .git/config에 남지 않도록 persist-credentials: false를 명시하는 것이 안전합니다.

🔒 제안 수정
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@v4
+        with:
+          persist-credentials: false
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- uses: actions/checkout@v4
- uses: actions/checkout@v4
with:
persist-credentials: false
🧰 Tools
🪛 zizmor (1.26.1)

[warning] 113-113: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml at line 113, The checkout step in the CI workflow
should explicitly disable credential persistence because this job downloads and
runs an external binary after fetching the repo. Update the existing
actions/checkout@v4 usage to set persist-credentials to false so no Git
credentials remain in .git/config. Keep the change scoped to the checkout step
in the CI workflow.

Source: Linters/SAST tools

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request pins the libkiwi version used by kiwi-rs to v0.23.2 via Kiwi::init_with_version to prevent ABI desynchronization and potential SIGSEGV issues. Additionally, a new integration smoke test test_kiwi_ffi_abi_smoke has been introduced to verify the real FFI ABI compatibility, which runs when the SECALL_KIWI_FFI_TEST environment variable is set. There are no review comments, so I have no feedback to provide.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

FFI 회귀 테스트가 실제 버그를 잡음: 정품 libkiwi 0.23.2 로는 seCall 바인딩이
Kiwi::new() (builder/init 경로)에서 SEGFAULT. 같은 lib+model 로 번들 kiwi-cli 0.23.2
는 정상 분석 → lib/model 이 아니라 바인딩 문제. #143 은 analyze 경로(KiwiAnalyzeOption)
ABI 를 고쳤으나 init 경로 0.23 비호환은 미해결(상류 kiwi-rs 조사 영역).

- KIWI_LIBKIWI_TAG: v0.23.2 -> v0.22.2 (실증된 working 버전). 0.22.2 통과, 0.23.2 는
  init crash 를 동일 env 메커니즘·테스트로 확인. 컴파일된 48B KiwiAnalyzeOption 은
  0.22.2 의 32B prefix 만 읽혀 안전.
- ci.yml: 이전 kiwi-ffi 잡은 포크의 깨진 auto-download 에 의존해 CI 에서 실패했음
  (find_asset_url 이 릴리스 JSON 의 중첩 uploader 객체에서 brace 매칭 실패 -> asset
  not found). 이제 인증된 gh release download 로 libkiwi+model 을 직접 provision 하고
  KIWI_LIBRARY_PATH/KIWI_MODEL_PATH 로 넘겨 Kiwi::new() 가 다운로드 없이 로드.

검증: fresh 0.22.2 provision -> env -> FFI 테스트 통과(2.18s). secall-core 485 green,
clippy -Dwarnings 클린, ci.yml YAML valid.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LVEL1SnCQBtUMeWVy99ebj
@hang-in hang-in changed the title fix(kiwi): PR #143 후속 — libkiwi 버전 핀 + FFI ABI 회귀 테스트/CI fix(kiwi): PR #143 후속 — libkiwi 버전 핀(v0.22.2) + FFI ABI 회귀 테스트/CI + 0.23 비호환 발견 Jul 6, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/ci.yml:
- Around line 118-120: The kiwi-ffi job currently relies on the default broad
GITHUB_TOKEN permissions, even though it only needs read access for gh release
download. Add a job-level permissions block on kiwi-ffi and restrict it to
contents: read so the workflow uses least-privilege access.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f3d0283e-65ef-470f-970f-edfff295762e

📥 Commits

Reviewing files that changed from the base of the PR and between d9d8454 and e28532b.

📒 Files selected for processing (2)
  • .github/workflows/ci.yml
  • crates/secall-core/src/search/tokenizer.rs

Comment thread .github/workflows/ci.yml
Comment on lines +118 to +120
kiwi-ffi:
name: kiwi FFI ABI regression
runs-on: ubuntu-latest

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

최소 권한 블록 추가 권장.

kiwi-ffi 잡은 gh release download(읽기)만 필요하지만 워크플로/잡에 permissions 블록이 없어 기본 광범위 토큰 권한이 부여됩니다. 잡 수준에서 contents: read로 제한하세요.

🔒 제안 수정
   kiwi-ffi:
     name: kiwi FFI ABI regression
     runs-on: ubuntu-latest
+    permissions:
+      contents: read
     steps:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
kiwi-ffi:
name: kiwi FFI ABI regression
runs-on: ubuntu-latest
kiwi-ffi:
name: kiwi FFI ABI regression
runs-on: ubuntu-latest
permissions:
contents: read
🧰 Tools
🪛 zizmor (1.26.1)

[warning] 118-165: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block

(excessive-permissions)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml around lines 118 - 120, The kiwi-ffi job currently
relies on the default broad GITHUB_TOKEN permissions, even though it only needs
read access for gh release download. Add a job-level permissions block on
kiwi-ffi and restrict it to contents: read so the workflow uses least-privilege
access.

Source: Linters/SAST tools

@hang-in
hang-in merged commit 80b0a94 into main Jul 6, 2026
5 checks passed
@hang-in
hang-in deleted the feat/kiwi-abi-hardening branch July 6, 2026 23:02
hang-in pushed a commit that referenced this pull request Jul 7, 2026
….22.2

#143(kiwi-rs ABI 포크 패치)/#144(버전 핀 + FFI 회귀 테스트 + CI) 머지, libkiwi 0.23
init 비호환 발견(이슈 #145), MCP/컨텍스트 점검 요약.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LVEL1SnCQBtUMeWVy99ebj
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant