← 목록
AI 2026-07-22 24KB 읽기 27분

CrownyAI Mac App Store 등록 컴플라이언스 갭 분석

개요

사장님 지시(2026-07-22): CrownyAI를 "MCP 연결 가능 웹브라우저"로 애플 앱스토어에 등록 준비. 현재 /Users/ef/CrownyBrowser/native/ 구현(신셸 crowny-ai-*.m 8파일, CrownyAI.app)을 실측해 App Store 샌드박스 요건 대비 갭을 정리한다. 본 문서는 조사·분석 전용이며 코드는 수정하지 않았다.

결론 선요약: 현재 아키텍처(그대로)로는 App Sandbox 진입 불가. NSTask로 로컬 CLI/VM/컴파일러를 기동하는 구조 자체가 샌드박스와 근본 충돌한다. 앱스토어용은 별도 타깃(샌드박스판)이 필요하며, 로컬 VM 실행 기능을 제거하거나 XPC/헬퍼-외부 서비스(HTTP)로 대체해야 한다.


1. 현재 앱의 앱스토어 차단 요소 실측

1-1. entitlements.plist 현재값과 샌드박스 충돌

/Users/ef/CrownyBrowser/native/entitlements.plist (실제 서명본, codesign -d --entitlements :- CrownyAI.app로 재확인 — plist 파일과 임베딩 값 일치):

xmlcom.apple.security.cs.allow-jit                    true   ← 샌드박스와 공존 가능(허용 O), 단 심사 시 사유 설명 요구될 수 있음
com.apple.security.cs.allow-unsigned-executable-memory  true   ← ⚠ App Sandbox에서도 이론상 허용되나, 자체 VM(crownyc) JIT/미서명 코드 실행 목적이면 App Review가 "왜 필요한가" 강하게 캐물음 — 근거 못 대면 리젝 확실
com.apple.security.cs.disable-library-validation   true   ← ⚠ 라이브러리 검증 비활성 = 서명 안 된 외부 dylib 로드 허용. App Store 심사에서 강한 리젝 사유(비검증 코드 로딩 경로 자체가 정책 위반 소지)
com.apple.security.network.client                  true   ← 샌드박스 호환 O
com.apple.security.network.server                  true   ← 샌드박스 호환 O (로컬 리슨 — 이유 설명 필요)
com.apple.security.files.user-selected.read-write   true   ← 샌드박스 호환 O(표준 항목)

com.apple.security.app-sandbox 키 자체가 없다 — 즉 현재 앱은 샌드박스 밖에서 서명(Apple Development, Team LQ83M5TL9S, codesign -dvvv 실측: Authority=Apple Development: sunkyung kim (Y447DT68BP))되어 있다. App Store Connect 제출은 com.apple.security.app-sandbox = true가 강제이며, 이 키를 켜는 순간 위 disable-library-validation/allow-unsigned-executable-memory 조합이 실질적으로 "자기 자신의 VM을 서명 없이 돌리는 구조"와 충돌한다 — VM 바이너리(crownyc, hanseonc_high)가 앱 번들 밖(/Users/ef/CrownyOS/crownyc/)에 있고 NSTask로 별도 프로세스 실행하는 구조라 disable-library-validation은 자체 바이너리 실행에는 직접 안 쓰이지만, NSTask로 번들 밖 실행파일을 띄우는 것 자체가 샌드박스에서 기본 차단(아래 1-2).

1-2. NSTask(로컬 프로세스 실행) — 샌드박스 최대 충돌점

grep -n NSTask crowny-ai-*.m 전수 결과, 8개 파일 전부에서 사용. 확인된 실행 대상:

파일:라인실행 대상(추정 커맨드)용도샌드박스 판정
crowny-ai-engine.m:279,304,354,924,1030,1233hanseonc_high, crownyc(/Users/ef/CrownyOS/crownyc/...)오피스/뷰어용 한선씨 소스 → toau 컴파일 + VM 실행❌ 금지 — 번들 밖 임의경로 실행파일 spawn
crowny-ai-engine.m:1006,1198,1996 (gAppSrvTask)상주 appSrv 서버 프로세스(포트 9821~9840 bind)콜드스폰 대체용 상주 서버❌ 금지 — 자식 프로세스가 자체 소켓 리슨, 샌드박스는 자식 프로세스 자체를 원천 차단(com.apple.security.inherit류 예외 없이는 spawn 불가)
crowny-ai-butler.m:92,127,171,1065,1178/Users/ef/CrownyBrowser/tools/집사CLI브릿지.sh집사(butler) CLI 브릿지 호출❌ 금지 — 임의 쉘스크립트 spawn
crowny-ai-main.m:770open -n <bundle> (openNewInstance)"새 창" = 새 프로세스 기동❌ 금지 — 샌드박스는 자기자신 재실행(open -n)도 기본 차단(사용자 상호작용 없는 self-relaunch)
crowny-ai-content.m:407,423,474,497,2615,2634,2677,2695,2738,2756,3790,3809,4444,4462crownyc/hanseonc_high (오피스·ERP 저장/열기 VM 스테이지, caOfficeRunVMStage)문서 저장/열기 시 한선씨 VM 스테이지 실행❌ 금지
crowny-ai-settings.m:826,947집사CLI브릿지.sh설정 패널 → CLI 브릿지❌ 금지
대체/제거 방향(앱스토어 타깃 한정):
  1. 제거가 정답인 것: 새 창 = NSTask(open -n) → 샌드박스에서는 NSWorkspace openApplicationAtURL:configuration:completionHandler:(정상 다중 인스턴스 launch API, 샌드박스 허용)로 교체하거나, 애초에 macOS 표준 "새 윈도우" 패턴(같은 프로세스 내 NSWindowController 추가)으로 재설계.
  2. XPC로 대체: 한선씨 VM 실행(crownyc/hanseonc_high)은 앱 번들에 내장된 XPC 서비스(com.apple.security.temporary-exception.* 없이, 정식 XPC Service 타깃)로 재구성 — VM 바이너리를 Contents/XPCServices/에 넣고 NSXPCConnection으로 통신. 단 XPC 서비스도 자체 샌드박스 적용받으므로, "임의 쉘스크립트 실행"(집사CLI브릿지.sh) 성격은 XPC로도 못 살림 — 근본 재작성 필요.
  3. HTTP로 대체(권장, MVP에 가장 적합): appSrv 상주 서버·집사 CLI 브릿지 기능은 로컬 프로세스 스폰 대신 외부 상시 서버(사용자의 다른 Mac/서버에서 이미 상주 중인 crowny 서비스, 예: 9821~9840 포트 서비스를 localhost가 아닌 원격 호스트로)에 HTTP/MCP 호출로 전환. com.apple.security.network.client만으로 충분, 샌드박스 완전 호환.
  4. 오피스/ERP 저장 VM 스테이지: 이미 문서에 있는 "로컬+클라우드 동기"(저장동기.한선, /api/office/save:9938) 패턴처럼, 로컬 컴파일 스테이지를 제거하고 클라우드 API 경유로 완전 전환하거나, 애초에 이 기능(오피스/ERP/집사/한선씨 VM 실행)을 앱스토어판에서는 완전히 뺀다(별도 비앱스토어 "Pro/개발자판"으로 분리).

1-3. CGWindowListCopyWindowInfo / 탭-창 간 이동 / 창이동 훅

  • crowny-ai-main.m:916CGWindowListCopyWindowInfo(...): 다른 CrownyAI 창의 탭바 히트테스트(같은 앱 다중 창 간 탭 드래그용). CGWindowList API는 퍼블릭 API(비공개 아님)이나, macOS는 Screen Recording 권한류 프라이버시 게이트에 걸릴 수 있고, App Review는 "왜 다른 창 정보를 열거하는가"를 물을 수 있음. 리스크 등급: 의심(공식 API라 리젝 확실은 아니나, 스크린 캡처 관련 TCC 권한이 얽히면 사유서 필요).
  • crowny-ai-main.m:372-379isMovable 게터 오버라이드 + mouseLocationOutsideOfEventStream: NSWindow공개 메서드를 오버라이드하는 정상적인 Cocoa 패턴(비공개 API 아님). mouseLocationOutsideOfEventStream도 AppKit 공개 API. 리스크 등급: 허용(공식 API 정상 사용).
  • crowny-ai-content.m setValue:forKey: (fullScreenEnabled, drawsBackground) + NSSelectorFromString(@"setContinuousSpellCheckingEnabled:")/setGrammarCheckingEnabled: + NSInvocation (1102~1117행): WKWebView/NSTextView의 비공개 프로퍼티에 KVC로 접근하는 전형적 패턴. drawsBackground/fullScreenEnabled는 WKWebView 진영에서 오래 쓰인 사실상 관용구지만 공식 문서화 API가 아니다 — 앱스토어 심사에서 자동화 스캐너(비공개 셀렉터/문자열 조합 탐지)가 걸어낼 위험이 실질적으로 있다. 리스크 등급: 의심~리젝 가능(과거 사례상 setValue:forKey:@"drawsBackground"류는 심사 통과 사례도 있으나 100% 보장 안 됨 — "확인 필요").

1-4. 분산 알림(NSDistributedNotificationCenter)

crowny-ai-main.m:441,507,963, crowny-ai-engine.m:1840,1860 — 프로세스 간(다중 CrownyAI 창) 탭 이관 통신에 사용. App Sandbox는 NSDistributedNotificationCenter를 기본 차단한다(entitlement로도 살릴 수 없는 항목 중 하나 — Apple 문서상 샌드박스 앱은 distributed notification 송수신이 사실상 불가/제한적). 리스크 등급: 리젝 확실(샌드박스 활성화 시 이 통신 경로 자체가 죽는다) → 이 기능(다중 창 탭 드래그 이관)은 앱스토어판에서 재설계 필요(같은 프로세스 내 다중 윈도우로 통합하거나 기능 제거).

1-5. 파일 임의경로 접근 / 하드코딩 절대경로

grep '"/Users/ef' crowny-ai-*.m 전수 30건 (butler 3, chrome 1, main 3, engine 9, content 8, settings 3 등). 대표:

crowny-ai-butler.m:60   @"/Users/ef/CrownyBrowser"
crowny-ai-engine.m:87   @"/Users/ef/CrownyBrowser"
crowny-ai-engine.m:92   @"/Users/ef/CrownyOS/crownyc"
crowny-ai-engine.m:97   @"/Users/ef/crowny-fonts"
crowny-ai-engine.m:103  @"/Users/ef/crowny-butler"
crowny-ai-content.m:346 kCACrownycPath = @"/Users/ef/CrownyOS/crownyc/crownyc"
crowny-ai-content.m:347 kCAHanseoncHighPath = @"/Users/ef/CrownyOS/crownyc/hanseonc_high"
crowny-ai-settings.m:603 placeholder:@"/Users/ef/.local/bin/claude"
대부분 getenv("CROWNY_BROWSER_ROOT") 등 env 폴백 실패 시의 "개발기 절대경로"이며, 코드 주석도 이를 "개발 폴백"으로 명시(crowny-ai-engine.m:656). App Sandbox 컨테이너에서는 /Users/ef/... 절대경로가 애초에 접근 불가(컨테이너 밖 파일 시스템은 user-selected 경로 외 전면 차단) — env 미설정 시 이 폴백 경로로 떨어지면 100% 실패. 샌드박스판은 이 폴백 자체를 제거하고 "해당 기능 없음"으로 처리하거나, 기능을 아예 안 가져가야 한다.

/tmp/ 하드코딩도 전수(예: crowny-ai-engine.m 45건, crowny-ai-butler.m 12건, crowny-ai-content.m 7건) — 샌드박스에서 /tmp는 앱 전용 컨테이너 tmp(NSTemporaryDirectory())로 리다이렉트되긴 하나(커널이 자동 치환), 하드코딩된 절대경로 /tmp/...가 그대로 open()되면 컨테이너 밖 시스템 /tmp를 가리켜 권한 거부될 수 있다(경로에 따라 다름 — 실제로는 대부분 자동 리다이렉트되지만 readlink/심볼릭 링크 우회 경로는 실패 가능). 안전하게는 전부 NSTemporaryDirectory() API 경유로 교체 필요.

1-6. 요약 — 최대 차단 요소 Top 3

  1. NSTask 기반 로컬 프로세스 실행(한선씨 VM 컴파일/실행, 집사 CLI 브릿지, appSrv 상주서버, open -n 자기재실행) — 8개 소스파일 전체에 걸쳐 40+ 호출 지점. 샌드박스 활성화 시 전부 죽는다. 가장 크고 구조적인 갭.
  2. com.apple.security.app-sandbox 자체가 미선언 + disable-library-validation/allow-unsigned-executable-memory 조합 — 현재 서명 체계가 애초에 App Store 배포 형태가 아님(Developer ID/Development 서명, 샌드박스 없음).
  3. NSDistributedNotificationCenter 기반 다중 창 통신 + 하드코딩 절대경로 폴백(/Users/ef/...) — 샌드박스에서 원천 차단/무효화되는 기능들이 핵심 UX(창 간 탭 이관, 자산·CLI 경로 해석)에 얽혀 있다.

2. WKWebView 브라우저의 앱스토어 가능성

  • Apple 정책(App Store Review Guideline 2.5.6)은 자체 브라우저 엔진(자체 렌더링/JS 엔진) 사용을 금지하고, 시스템 WebKit(WKWebView) 기반 앱은 허용한다. CrownyAI의 Path A(crowny-browser.m/신셸 crowny-ai-*.m)는 WKWebView를 사용하는 구조이므로 엔진 자체는 원칙적으로 문제 없음(OK).
  • 단, CLAUDE.md에 기록된 "Path B — 커스텀 렌더러"(HTML파서.한선/CSS해석.한선/박스레이아웃.한선, 한선씨 자체 VM 렌더링 경로)나 "크라우니전용 CrownyBrowser-Crowny.app(WebKit 0)"처럼 자체 렌더러로 웹 콘텐츠를 그리는 변종은 앱스토어 제출 대상에서 제외해야 한다 — 이건 자체 엔진 금지 조항에 정면 저촉. 앱스토어판은 반드시 "Universal/Public" 계열(WKWebView 링크 확인됨, otool 검증 기록 있음)만 사용.
  • "브라우저" 카테고리 심사 요건 (확인 필요 항목 다수 — 아래는 일반 상식 수준, Apple 공식 문서 재확인 권장):
  • 기본 브라우저 지정: macOS는 LSSetDefaultHandlerForURLScheme(이미 set-default-browser.m에 구현됨, 시스템 확인 대화상자 필요 — 이 자체는 App Store 앱도 사용 가능한 공개 API)로 사용자가 "기본 브라우저로 설정"할 수 있어야 브라우저 카테고리 요건을 충족하는 경우가 많음. 현재 CLAUDE.md에 이미 "http/https는 macOS 시스템 확인 대화상자 승인 필요(우회 불가)"로 기록 — 이 부분은 그대로 사용 가능.
  • 개인정보(Privacy) 요건: 브라우징 히스토리/북마크(history.json, bookmarks.json)는 로컬 저장이라도 Privacy Nutrition Label(App Privacy 질문지)에 "브라우징 히스토리 수집"으로 신고 필요할 가능성 — 확인 필요.
  • 콘텐츠 필터링/성인물 등: 범용 브라우저는 Apple이 임의 URL 탐색 허용 여부를 까다롭게 볼 수 있음(과거 서드파티 브라우저 리젝 사례 다수 보고됨) — 확인 필요, 최신 가이드라인 재확인 권장.
  • "MCP 연결 가능"이라는 소구점 자체는 Apple 정책에 직접 저촉되는 개념은 아니나, MCP 서버 연결이 임의 코드 실행/원격 명령 실행처럼 보이면 2.5.2(비공개 API)나 2.5.1(승인되지 않은 기능)류 조항에 걸릴 수 있어 MCP 연동은 "확인된 도구 호출 API"로 명확히 스코프해 제출 노트에 설명 필요 — 확인 필요.

  • 3. 필요한 것 목록

    3-1. App Sandbox 엔타이틀먼트 세트(최소 권한, 앱스토어 타깃 신규 entitlements 예시)

    xml<key>com.apple.security.app-sandbox</key><true/>
    <key>com.apple.security.network.client</key><true/>              <!-- MCP/원격 API 호출 -->
    <key>com.apple.security.files.user-selected.read-write</key><true/>   <!-- 파일 열기/저장 다이얼로그 -->
    <key>com.apple.security.files.downloads.read-write</key><true/>       <!-- 다운로드 폴더 -->
    <key>com.apple.security.personal-information.location</key><false/>  <!-- 불필요 항목은 아예 제외 -->
    
    제거 대상: allow-jit(VM 미포함 시 불필요), allow-unsigned-executable-memory(동일), disable-library-validation(동일), network.server(로컬 리슨 기능 제거 시 불필요). allow-jit은 WKWebView의 JavaScriptCore 자체 JIT에는 보통 불필요(WebKit 프로세스가 자체 entitlement로 처리) — 확인 필요(WKWebView만 쓰는 다른 앱스토어 앱들의 entitlements 사례 확인 권장).

    3-2. 서명 요건

    • 현재: Apple Development: sunkyung kim (Y447DT68BP), Team LQ83M5TL9S (개발 서명, 로컬 실행/테스트용).
    • 필요: "Apple Distribution" 인증서(App Store Connect 배포용, Development와 별개 발급) + Provisioning Profile(App Store 배포용, sandbox entitlement 포함). Apple Developer Program 계정에서 Certificates, Identifiers & Profiles → App Store 배포 프로파일 생성 필요. Team ID LQ83M5TL9S가 유료 Developer Program 멤버십(연 $99)인지 확인 필요 — Bundle ID org.crowny.browser를 App Store Connect에 앱으로 등록해야 함(신규 App ID 등록·앱 레코드 생성).

    3-3. 공증/제출 파이프라인

    • App Store 제출은 공증(notarization)이 별도로 필요 없다(App Store Connect가 자체 심사) — Developer ID 배포판(현재처럼 ad-hoc/개발서명 배포)만 notarize 필요. 즉 앱스토어 경로와 현재 install-ai-app.sh의 ad-hoc 재서명 경로는 완전히 다른 파이프라인.
    • 필요 파이프라인: Xcode Archive(또는 xcodebuild archive + xcodebuild -exportArchive with app-store export method) → .ipa/.pkg 생성 → xcrun altool/notarytool(App Store Connect API 업로드는 notarize와 별개 경로, xcrun altool --upload-app 또는 Transporter.app) → App Store Connect에서 심사 제출.
    • 현재 빌드는 순수 make(cc 직접 호출) + 수동 codesign — Xcode 프로젝트(.xcodeproj)가 없다(Makefile만 존재, find . -iname Info.plist 결과 native/ 루트엔 없고 /Users/ef/CrownyBrowser/CrownyAI.app/Contents/Info.plist에만 존재). App Store Connect 업로드는 사실상 Xcode 프로젝트 구조(또는 최소한 Xcode가 인식하는 export 절차)가 필요 — Makefile 산출물을 그대로 App Store Connect에 올리는 표준 경로는 없음(Transporter로 .pkg 업로드는 가능하나 서명·프로파일 요건은 동일하게 따라야 함). 확인 필요: Makefile 기반 빌드에서 App Store 배포용 아카이브를 직접 만드는 것이 가능한지, 혹은 최소 Xcode 래퍼 프로젝트를 새로 만들어야 하는지.

    3-4. Info.plist 요건

    현재 /Users/ef/CrownyBrowser/CrownyAI.app/Contents/Info.plist 실측:

    • CFBundleShortVersionString = 0.9.0-beta — App Store는 정식 버전 형식 권장(1.0.0), "beta" 문자열은 심사에서 지적될 수 있음.
    • LSApplicationCategoryType없음 — App Store는 카테고리 필수(예: public.app-category.productivity 또는 웹브라우저는 보통 public.app-category.utilities; 명시적 "Browser" 카테고리는 App Store Connect 메타데이터에서 설정, Info.plist엔 일반 카테고리 키만).
    • NSAppTransportSecurity: NSAllowsArbitraryLoads = true — ⚠ 임의 HTTP(비HTTPS) 로드 전면 허용. App Review가 사유 요구 가능(브라우저 특성상 임의 사이트 방문이 정당 사유가 될 수 있으나, "확인 필요").
    • 개인정보 사용문자열(Usage Description) 전무: NSCameraUsageDescription/NSMicrophoneUsageDescription/NSLocationUsageDescription 등이 plist에 없음 — 현재 기능이 카메라/마이크/위치를 안 쓰면 문제 없으나, WKWebView가 웹사이트의 getUserMedia 요청을 프록시할 경우 Info.plist에 해당 usage description이 없으면 크래시/거부됨 — 확인 필요(브라우저가 웹캠/마이크 권한이 필요한 사이트를 지원할지 여부에 따라 추가 필요).
    • CFBundleDocumentTypespublic.html 뷰어 선언 있음 — 유지 가능.
    • App Privacy(Nutrition Label)는 Info.plist가 아니라 App Store Connect 메타데이터에서 별도 작성 — 브라우징 데이터 수집 여부 신고 필요.

    4. 현실 판정

    현재 아키텍처 그대로는 App Sandbox 진입 불가. 근거:

    • NSTask 40+ 호출 지점이 로컬 CLI(집사 브릿지)·한선씨 VM 컴파일/실행·상주 서버·자기 프로세스 재실행에 구조적으로 얽혀 있다(오피스/ERP 저장, 뷰어, 집사, 새 창 전부). 샌드박스는 자식 프로세스 spawn 자체를 기본 차단하며, 이 기능들은 "권한 추가 신청"으로 해결되는 수준이 아니라 아키텍처 재설계가 필요한 수준이다.
    • NSDistributedNotificationCenter(다중 창 탭 이관)도 샌드박스에서 무효화된다.
    • 하드코딩된 /Users/ef/... 절대경로 폴백은 샌드박스 컨테이너 밖이라 애초에 도달 불가능하다.
    필요성: (a) 별도 타깃/변종이 필수. CLAUDE.md에 이미 "3변종 패키징"(Public/Crowny/Universal) 구조가 있으므로, 여기에 4번째 변종 "CrownyAI-Store"를 추가하는 편이 기존 관례와 정합적이다. 이 변종은:
  • WKWebView만 사용(Public/Universal 계열의 WebKit 링크 구조를 계승, Crowny 전용 렌더러 변종은 제외).
  • NSTask 기반 로컬 기능(집사 CLI, 한선씨 VM 로컬 컴파일/실행, appSrv 상주서버, open -n 자기재실행) 전부 제거 또는 원격 HTTP 대체.
  • 다중 창 탭 이관(NSDistributedNotificationCenter)은 제거하거나 같은 프로세스 내 다중 NSWindowController로 재설계.
  • 절대경로 폴백 제거, NSTemporaryDirectory()/앱 컨테이너 경로만 사용.
  • MVP로 낼 수 있는 최소 기능 셸:

    1. 순수 WKWebView 브라우저(멀티탭, 히스토리, 북마크, 시작페이지) — CLAUDE.md "Path A v0.2" 수준 기능은 대부분 샌드박스 호환(로컬 JSON 파일 저장은 앱 컨테이너 내부라 문제 없음).
    2. MCP over HTTP: 로컬 프로세스 스폰(NSTask) 없이, 사용자가 설정한 MCP 서버 엔드포인트(원격 HTTP/WebSocket)에 network.client entitlement만으로 연결하는 클라이언트 기능. crowny 생태계의 MCP 관련 로컬 실행(예: 한선씨 VM을 MCP 툴로 직접 실행)은 앱스토어판에서 배제하고, 이미 상시 구동 중인 원격 crowny 서비스(9821~9840류 포트를 로컬이 아닌 서버 호스트로 이전한 것)를 호출하는 형태로 한정.
    3. 기본 브라우저 설정 기능(set-default-browser.m 로직, 공개 API라 유지 가능).
    4. crowny:// 커스텀 앱 카드(erp/hall/cad/ev/factory/fab 등, 전부 "라이브 서버형" — loadRequest로 원격 HTTPS를 여는 방식)는 로컬 프로세스 실행이 없으므로 그대로 유지 가능(CLAUDE.md 기록상 이들은 이미 서버가 직접 서빙하는 구조라 NSTask 의존이 없음 — 단 crowny-ai-content.m 각 지점의 하드코딩 절대경로 폴백만 제거하면 됨).
    5. 제외할 것: 오피스/ERP의 로컬 cdf 저장 시 VM 스테이지 실행(caOfficeRunVMStage), 집사(butler) CLI 브릿지, appSrv 상주서버, 새 창=open -n.

    5. 단계적 로드맵 (우선순위)

    1. P0 — 변종 스캐폴딩: make-app.sh/package-variants.sh 관례를 따라 -DCROWNY_PRODUCT_STORE 매크로 신설, crowny-ai-*.m 전체에서 이 매크로로 NSTask 블록·NSDistributedNotificationCenter 블록·하드코딩 절대경로 폴백을 #ifndef CROWNY_PRODUCT_STORE로 컴파일 제외. (CLAUDE.md 3변종 정책과 동일 패턴이라 도구화 난이도 낮음.)
    2. P0 — entitlements-store.plist 신규 작성: com.apple.security.app-sandbox=true + 최소 세트(3-1 참조), Xcode 프로젝트 골격 하나 신설(Makefile과 병행, App Store Connect 업로드 경로 확보).
    3. P1 — MCP-over-HTTP 클라이언트 설계: 로컬 NSTask 대신 원격 crowny 서비스 호출로 붙일 MCP 연동 스펙 확정(어떤 기능을 "MCP 도구"로 노출할지 — 사장님 의사결정 필요 항목).
    4. P1 — Apple Developer Program / Distribution 인증서 확인: Team LQ83M5TL9S가 유료 멤버십인지, App Store Connect에 org.crowny.browser App ID 등록 여부 확인(계정 작업, 개발 범위 밖 — 사장님 액션 필요할 가능성).
    5. P2 — Info.plist 정비: 버전 문자열 정식화(beta 제거), LSApplicationCategoryType 추가, ATS NSAllowsArbitraryLoads 사유 정리, Privacy Usage Description 필요 여부 점검(웹캠/마이크 지원 범위 확정에 따라).
    6. P2 — 심사 리스크 항목 사전 정리: setValue:forKey:/NSInvocation 기반 비공개 프로퍼티 접근(§1-3) 제거 또는 공식 API 대체 검토, CGWindowListCopyWindowInfo 사용처 리뷰 노트 작성.
    7. P3 — 실제 제출: Xcode Archive → App Store Connect 업로드 → 심사 제출(Privacy Nutrition Label 작성 포함).

    관련 파일

    • /Users/ef/CrownyBrowser/native/entitlements.plist
    • /Users/ef/CrownyBrowser/native/Makefile
    • /Users/ef/CrownyBrowser/native/crowny-ai-main.m, crowny-ai-chrome.m, crowny-ai-content.m, crowny-ai-engine.m, crowny-ai-butler.m, crowny-ai-panels.m, crowny-ai-overlays.m, crowny-ai-settings.m
    • /Users/ef/CrownyBrowser/CrownyAI.app/Contents/Info.plist
    • /Users/ef/CrownyBrowser/native/install-ai-app.sh
    • /Users/ef/CrownyBrowser/CLAUDE.md

    잔여 이슈 / 확인 필요 목록

    1. Team LQ83M5TL9S가 유료 Apple Developer Program 멤버십인지, org.crowny.browser Bundle ID를 App Store Connect에 등록 가능한지(계정 레벨, 코드로 확인 불가).
    2. WKWebView-only 앱의 allow-jit entitlement 필요 여부(다른 App Store WKWebView 앱 사례 확인 권장).
    3. Makefile 기반 빌드에서 App Store Connect 업로드용 아카이브를 직접 만들 수 있는지, Xcode 프로젝트 골격이 반드시 필요한지.
    4. 브라우저 카테고리 App Review 요건 최신본(콘텐츠 필터링/성인물 정책 등) — Apple 공식 가이드라인 재확인 필요.
    5. MCP 연동을 App Review가 "비공개 API/미승인 기능"으로 보지 않도록 어떻게 설명·스코프할지 — 정책 문구 최신본과 대조 필요.
    6. WebRTC(getUserMedia) 지원 여부에 따른 Privacy Usage Description 추가 필요성.