크라우니AI Safari-파리티 UA + 디자인갭검증.sh 크라우니AI 전환
개요
2건 작업: (A) 크라우니AI 신셸 WKWebView가 기본 UA에
Version/x Safari/x 토큰이 없어 오라클클라우드 등 브라우저 화이트리스트에서 "지원되지 않는 브라우저"로 차단되던 문제 해소. (B)
디자인갭검증.sh의 스크린샷 축을 Chrome 헤드리스에서 크라우니AI 렌더로 전환(엔진 일관성 유지 + 실패시 Chrome 폴백).
(A) Safari 파리티 UA
native/crowny-ai-content.m에 caApplySafariParityUA(WKWebView*) static 헬퍼 추가(#ifdef CROWNY_HYBRID, makeWebView 직전):
objc static void caApplySafariParityUA(WKWebView *wv) {
wv.customUserAgent = @"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Safari/605.1.15";
}
호출 지점 2곳(파일 내 WKWebView alloc 전수, crowny-ai-*.m 기준 이 2곳뿐):
makeWebView(1174행 근처, WKWebView alloc initWithFrame:configuration: 직후)
팝업 핸들러 webView:createWebViewWithConfiguration:forNavigationAction:windowFeatures:(2532행 근처)
순수 Safari 파리티만 부여 — Crowny 식별 토큰 미포함(외부 사이트 UA 스니퍼 오탐 방지). crowny_tier.m:186 crowny_build_ua()(tier UA)와는 별개 트랙, 미배선 확인(회귀 없음).
빌드: make ai 신규경고 0(기존 3건은 사전존재 — main.m ivar 미참조 3건, butler.m unused-function 1건, 전부 이번 수정과 무관).
설치: install-ai-app.sh 실행 완료(배선: factory=1 ev=1 cad=1 hall=1). 사용자 라이브 인스턴스(다수 pid 확인됨, kill/재시작 안 함) — .app 번들 디스크상 바이너리만 교체됐고, 실행 중 프로세스는 재시작 전까지 구 UA로 계속 동작한다. 반영에는 앱 재시작 필요.실측 증거 (크라우니AI검증.sh dump, 이번에 설치한 새 번들로 자동 기동된 별도 인스턴스 — 사용자 라이브 인스턴스와 무관)
- 메인 웹뷰:
text.txt = UA=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Safari/605.1.15
- 팝업 웹뷰(
window.open): text.txt = POPUP_OPENED=1 POPUP_UA=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Safari/605.1.15
- 둘 다
Version/17.5·Safari/605.1.15 토큰 확인.
한선씨 동반
검증표면.한선 자체 로직에 UA 판정을 넣기엔 자연스럽지 않아(그 파일은 검증 파이프라인 흐름 판정 전용) 생략. 대신 임시 검증용 스크래치 파일 ua_echo.한선/ua_echo_popup.한선(scratchpad, 자체시험 2/2·3/3 PASS)에 UA 토큰 판정 로직(사파리파리티UA인가/팝업오픈판정)을 이식해 학습 남김.
(B) 디자인갭검증.sh 엔진 전환
- 파일:
~/.claude/scripts/디자인갭검증.sh (수정 전 97줄, 백업 .bak-크라우니AI배선전).
- 기본 엔진 =
크라우니AI검증.sh shot <url> <png>. CROWNY_VERIFY_BROWSER=chrome 강제 또는 크라우니AI 촬영(레퍼런스·타깃 중 하나라도) 실패 시 둘 다 Chrome 헤드리스로 재촬영(엔진 혼용 방지, stderr 고지).
- 히어로 크롭(
0,80,W,1400)이 Chrome 풀페이지(2400px)에는 맞지만 크라우니AI 뷰포트(~700px대)엔 넘치므로 y0=min(80,H-1) / y1=min(1400,H)로 실제 이미지 높이에 클램프 — 레퍼런스·타깃이 항상 같은 엔진으로 찍히므로 클램프도 둘에게 동일 적용돼 비율 비교 공정성 유지.
- 출력 형식·exit 규약(0/1/2)·리포트
.md 생성 로직 불변.
실측
- 기본(크라우니AI) 엔진:
https://tree.crowny.org vs https://hall.crowny.org → SCORE 90 · VERDICT 티:과감히달성 · 리치=113% 색=56%, 리포트 정상 생성 후 정리.
CROWNY_VERIFY_BROWSER=chrome 강제: 같은 URL 쌍 → SCORE 76 · VERDICT 티:과감히달성 · 리치=99% 색=42% — 두 경로 모두 정상 동작 확인.
- 폴백 경로: 존재하지 않는 호스트를 레퍼런스로 줘서 크라우니AI 촬영 실패 유도 → stderr
⚠ 크라우니AI 촬영 실패 — Chrome 폴백 출력 확인 후 Chrome으로 자동 전환해 계속 진행됨을 확인.
- 테스트로 생성된 리포트(
갭검증테스트*-gap.md)는 실측 후 정리 삭제.
관련 파일
/Users/ef/CrownyBrowser/native/crowny-ai-content.m (caApplySafariParityUA + 2지점 호출)
/Users/ef/.claude/scripts/디자인갭검증.sh (+ .bak-크라우니AI배선전)
/Users/ef/CrownyBrowser/native/CrownyAI (재빌드), /Users/ef/CrownyBrowser/CrownyAI.app (재설치)
잔여 이슈
- 사용자가 실행 중인 CrownyAI 인스턴스는 재시작해야 새 UA가 실제로 적용된다 — 이번 세션에서 라이브 인스턴스는 전혀 건드리지 않음(파일 교체만).
- 오라클클라우드 등 실제 화이트리스트 사이트에서의 최종 확인은 앱 재시작 후 사용자가 직접 열어 봐야 함(이번 검증은 UA 문자열 자체의 정확성만 헤드리스로 실측).