Core에서 내장 스마트 연락처를 제거하고 cindy-contacts 플러그인으로 이관
README 링크에서 발견 · yesterday
Core 연락처 코드를 삭제하고, 플러그인 의존성은 유지하며, 읽기 전용 플러그인 도구를 허용 목록에 추가합니다.
What they did
작성자는 내장 스마트 연락처 기능이 공식 플러그인(`cindy-contacts`)으로 마이그레이션된 후 Core에서 해당 기능을 제거했습니다. 삭제는 Harness 시스템 프롬프트(Claude Code `contactsRules`, 이에 상응하는 Codex 개발자 지침 블록, 그리고 `cindy_contacts` MCP와 함께 사라진 Pi의 세그먼트), 도구 등록과 승인 정책을 포함한 `cindy_contacts` MCP 서버, 내장 플러그인 레지스트리 항목, maker-core의 `contacts/` 데이터 계층(store, manager, schema, sync), Desktop의 메인 프로세스 contacts 모듈, `maker:contacts:*` IPC 및 preload 표면, 설정 페이지 블록, Telegram 설정 힌트, LAN 전송과 codec 워커 빌드 엔트리를 포함한 기존 피어 투 피어 `contacts-sync/` 드라이버, Telegram 그룹 발화자 자동 등록, 그리고 도움말 KB, 10개 로케일의 문구, 용어집 항목과 규칙 문서에 걸쳐 이루어졌습니다. 유지된 것: 플러그인이 읽기 전용으로 가져올 수 있도록 그대로 둔 레거시 `<userData>/owners/<ownerId>/maker-contacts/contacts.db`(여전히 `ownerNamespaceMigration`이 해당 디렉터리를 마이그레이션함), 디스크상의 키 파일명과 HKDF 파라미터를 바이트 단위로 동일하게 유지하여 페어링된 머신이 계속 작동하도록 `contacts-sync/`에서 중립적인 `device-sync-keys/`로 이동한 디바이스 키와 암호화, 그리고 macOS 연락처 Info.plist 권한 문자열(10개 언어에서 LAN 권한 문구를 Device Link 표현으로 일반화함). 플러그인의 읽기 전용 도구(find, get, list, stats, find_duplicates, groups action=list)는 `ghost_call`을 통해 조용히 허용되며 기존 Cindy Art 자사 allowlist와 동일한 테이블에 병합되는 반면, 쓰기, 병합, 삭제, 가져오기는 여전히 호출별 세션 승인을 거칩니다. 기존 `device-link:contacts:sync:v1` 프레임은 전달되지 않고 폐기되며, 채널 이름은 예약되고, 저장된 `contacts` 내장 툴셋 선택은 `isRetiredBuiltinToolset`을 통해 자동 제거됩니다. 메인테이너 결정에 따라 Core 내 폐기 공지는 없으며, 릴리스 노트가 이를 전달하고 `feature-retirements.md`가 해당 패턴을 문서화합니다. 검증: maker-core, lizi-mcps, device-link 전반의 `tsc --noEmit`, desktop의 `pnpm run typecheck`, 그리고 `pnpm test:unit:related` — 65k개의 desktop 케이스 중 하나가 오래된 포르투갈어 LAN 권한 단언에서 실패했으며, 이를 업데이트하고 재실행하여 통과했습니다. 테스트 위생, 디자인 인벤토리, i18n 용어집, help-kb-guard, DCO 검사는 모두 통과했습니다. 제거된 기능의 테스트는 삭제되었고, 새로운 `device-sync-keys/__tests__/crypto.test.ts`가 두 개의 암호화 프리미티브 케이스를 유지했으며, `mcpToolApprovalPolicy.test.ts`는 플러그인 읽기 전용 허용 대 쓰기 승인에 맞게 재작성되었습니다. 격리된 Desktop 빌드에서의 수동 확인을 통해 설정 목록에 더 이상 스마트 연락처가 표시되지 않음을 확인했고, `cindy-contacts` 1.1.0을 설치하여 제거하기 전에 `stats`와 `find`가 성공적으로 실행됨을 확인했습니다.
How it went
타입체크와 관련 단위 테스트 스위트는 오래된 로케일 단언 하나를 수정한 후 통과했습니다. 격리된 빌드에서 수동 확인을 통해 설정 블록이 사라졌고 플러그인의 읽기 전용 도구가 작동함을 확인했습니다. 미검증 항목: 라이브 태스크의 시스템 프롬프트(로그인 만료, 사용 가능한 모델 없음 — 프롬프트 조립 단위 테스트로 커버됨), 두 머신 간 플러그인 동기화(인메모리 전송을 통한 실제 암호화로 `deviceSyncSlot.test.ts`에서 커버됨), 셀프 호스팅 릴레이 상호운용성. 롤백은 단순 revert이며, 기존 데이터베이스는 전혀 수정되지 않았습니다.
Worth knowing
호환성 깨지는 변경: contacts 플러그인이 없는 사용자는 해당 플러그인을 설치하고 이전 DB를 가져오기 전까지 contacts 기능을 잃습니다. 플러그인 저장소의 import 경로 수정은 범위 밖이며, Core 내 deprecation 공지는 제공되지 않습니다. 레거시 DB와 `contacts-settings.json`은 디스크에 그대로 남겨둡니다. silent allowlist는 정확한 ghost_id와 내부 도구 이름으로 한정되므로, 해당 식별자가 조금이라도 달라지면 조용히 프롬프트로 폴백됩니다. prompt-prefix 캐싱이 안정적으로 유지되는 것은 제거된 세그먼트가 접미사였기 때문일 뿐입니다.
Wiring
순서가 중요합니다: 먼저 `contacts-sync/`의 디바이스 키와 암호화를 `device-sync-keys/`로 옮기되 `contacts-device-sync-key.v1.enc` 파일명과 HKDF 유도를 동일하게 유지하고, `cindy-brain/deviceSyncSlot.ts`가 이를 가리키도록 변경하여 페어링된 머신에 영향이 없도록 합니다. 그다음 각 Harness의 프롬프트 조립에서 프롬프트 세그먼트를 제거하고(Claude Code `contactsRules`, Codex developer instructions, MCP 제거를 통한 Pi), 접두사 연결 순서가 그 외에는 변경되지 않았음을 확인합니다. 다음으로 `@cindy/mcps`에서 `cindy_contacts` MCP와 그 레지스트리 항목을 삭제하고, 이어서 maker-core의 `contacts/` 레이어, 그다음 Desktop의 메인 프로세스 모듈, `maker:contacts:*` IPC, preload API, 설정 블록 및 Telegram 힌트를 삭제합니다. `mcpToolApprovalPolicy`를 업데이트하여 플러그인의 읽기 전용 도구를 정확한 ghost_id와 내부 도구 이름으로 허용 목록에 추가하고, Cindy Art 테이블과 병합합니다. 저장된 `contacts` 선택에 대한 `isRetiredBuiltinToolset` 처리를 추가하고, device-link 경계에서 `device-link:contacts:sync:v1` 프레임을 드롭하되 이름은 예약해 둡니다. 레거시 DB와 `contacts-settings.json`은 그대로 두고 `ownerNamespaceMigration`이 여전히 이전 레이아웃을 커버하도록 합니다. 마지막으로 help KB, 10개 로케일, glossary, `feature-retirements.md` 및 테스트 스위트를 동기화합니다.
Try it yourself
# Retire Built-in Smart Contacts (moved to `cindy-contacts` plugin) ## 1. Remove contacts segment from Harness system prompts **Files:** `maker-core/src/harness/prompts/claude-code.ts`, `codex.ts`, `pi.ts` (or equivalent prompt builders) - Delete the `## Contacts` / smart-contacts section from each Harness system prompt template. - Remove any prompt-builder helpers that only existed to render the contacts segment (e.g. `renderContactsSegment`, `buildContactsContext`). - Update prompt snapshot tests to drop the contacts block. ## 2. Remove `cindy_contacts` MCP server **Files:** `lizi-mcps/src/servers/cindy-contacts/*`, MCP registry, approval policy table - Delete the `cindy_contacts` MCP server implementation and its tool registrations (`find`, `get`, `list`, `stats`, `find_duplicates`, `groups`, plus write/merge/delete/import tools). - Remove its entry from the MCP server registry and from the approval policy table. - Remove the built-in plugin registry entry for `cindy-contacts`. ## 3. Remove maker-core `contacts/` data layer **Files:** `maker-core/src/contacts/**` - Delete the entire `contacts/` module (repositories, schemas, migrations other than `ownerNamespaceMigration`). - **Keep** `ownerNamespaceMigration` and ensure it still migrates `maker-contacts/contacts.db` (legacy DB path unchanged, read-only for plugin import). - Remove exports from `maker-core/src/index.ts` that referenced the deleted module. ## 4. Remove Desktop contacts main-process module **Files:** `desktop/src/main/contacts/*`, IPC registration, preload - Delete the contacts main-process module. - Remove all `maker:contacts:*` IPC handlers and their channel constants. - Remove the corresponding preload API surface (`window.maker.contacts.*` or equivalent) and its type declarations. ## 5. Remove settings-page block **Files:** `desktop/src/renderer/settings/**` - Delete the contacts settings block/component and its route/registration. - Remove related locale keys (see §9). ## 6. Remove Telegram settings hint and group speaker auto-registration **Files:** Telegram integration in `desktop/src/main/telegram/*` and settings UI - Remove the "smart contacts" settings hint shown in the Telegram settings panel. - Remove group speaker auto-registration logic that called into the contacts layer. ## 7. Retire `contacts-sync/` driver; move device sync keys **Files:** `contacts-sync/**` → `device-sync-keys/**` - Delete the `contacts-sync/` driver: LAN transport, codec worker, and its build entry (remove from bundler/worker config). - **Move** device sync key/crypto primitives to a neutral `device-sync-keys/` module: - Keep the **key filename unchanged**. - Keep **HKDF parameters unchanged** (same salt/info/length). - Add a crypto test for the moved primitives (round-trip derive/encrypt/decrypt, key filename assertion, HKDF output vector). ## 8. Device-link: drop and reserve `device-link:contacts:sync:v1` **Files:** `device-link/src/**` - Stop forwarding incoming `device-link:contacts:sync:v1` frames; drop them at the handler boundary. - Reserve the channel name (add to a reserved-channels constant with a comment noting it's retired). - Add/adjust a test asserting the frame is dropped and the channel is reserved. ## 9. Retire builtin toolset selections **Files:** toolset selection logic (e.g. `maker-core/src/toolsets/*`) - Add `isRetiredBuiltinToolset(name)` returning true for `contacts`. - On load, auto-remove saved `contacts` builtin toolset selections from persisted settings. - Add a test covering migration of a saved selection containing `contacts`. ## 10. Allowlist plugin read-only tools via `ghost_call` **Files:** approval policy table (same table as Cindy Art first-party allowlist) - Add `cindy-contacts` read-only tools to the allowlist: `find`, `get`, `list`, `stats`, `find_duplicates`, `groups` (only when `action=list`). - Writes, merges, deletes, and imports remain per-call approval. - Rewrite the MCP approval test to target the plugin: assert read-only tools auto-approve via `ghost_call`, and write/merge/delete/import require approval. ## 11. Docs and strings - Remove contacts entries from the help KB. - Remove locale strings for the settings block, Telegram hint, and contacts UI. - Remove glossary entries for smart contacts. - Remove rule docs describing the built-in contacts feature. ## 12. Tests - Delete tests for all removed code (contacts data layer, MCP server, IPC, settings block, Telegram auto-registration, `contacts-sync/`). - Add the crypto test for `device-sync-keys/` (§7). - Rewrite the MCP approval test for the plugin (§10). - Add the device-link drop/reserve test (§8) and the retired-toolset test (§9). ## 13. Verification Run and fix until green: - `tsc` across `maker-core`, `lizi-mcps`, `device-link` - Desktop typecheck - `pnpm test:unit:related` - Hygiene check - Design check - i18n check - Help-KB check - DCO check