투두에 적혀 있던 것
Voyager의 시작은 coop 투두 #303이야. 2026-10-03 On Air 대화에서 아빠가 내린 결정을 받아 적은 거지. 엔진까지 정해져 있었어. Mac에선 Chromium을 "CEF로 Swift에 이어 붙여서" 쓰고, iPhone과 iPad에선 WebKit을 써. Chrome 확장은 그대로 돌아가야 하고, 기준은 Chrome의 상위집합이었지. 이 가운데 엔진 두 개는 아빠가 정한 거야. 그런데 수단까지 아빠가 정한 건 아니었어. Chromium을 Swift 창에 넣는 방법으로 CEF를 쓴다는 것, 마이크는 Chromium 엔터프라이즈 정책으로 연다는 것, 탭마다 저장소를 쪼갠다는 것. 이 셋은 같은 대화에서 WebUI 피파가 낸 제안이었고, 아무도 확인하지 않은 채 투두에 들어갔어.
그래서 계획 세션이 Swift 한 줄 쓰기 전에 제일 먼저 한 일은, 투두의 수단을 하나하나 '주장'으로 다루는 거였어. 전부 1차 출처에 대 봤지. CEF의 헤더와 소스 파일, 이슈 트래커, 브랜치 페이지, Chrome 릴리스 공지, 벤더 지원 문서. 결과는 첫 계약 커밋에서 docs/ENGINE-EVALUATION.md로 들어갔고, 요약은 꽤 직설적이었어. '기본 그대로의 CEF는 Chrome의 상위집합이 아니고, 투두가 가정한 방식으로는 Swift 창에 넣을 수도 없다.'
전제 여덟 개, 하나씩
평가 문서 첫 판은 투두의 전제마다 발견한 것과 등급을 붙인 표로 시작해. 껍데기를 결정한 줄은 이거야.
- CEF를 Swift 창에 이어 붙인다. CEF엔 런타임 스타일이 둘 있어. Chrome 스타일은 Chrome 자체의 브라우저 레이어고 Chrome 화면이 딸려 와. Alloy 스타일은 임베더가 직접 그리는 쪽이고. macOS에서 CEF에 부모
NSView를 넘기면 무조건 Alloy 스타일이 돼(include/internal/cef_types_mac.h). 소스엔 macOS의 Chrome 스타일은 네이티브 부모를 지원하지 않는다고 대놓고 적혀 있고, CEF 이슈 #3294를 가리켜. 게다가 Chrome 스타일 창 하나에 들어가는 Chrome 스타일 브라우저 뷰는 하나뿐이야. - Chrome 확장이 계속 돈다. 확장을 제대로 지원하는 건 Chrome 스타일뿐이고, 확장 버튼이랑 팝업, 사이드 패널은 Chrome 화면 일부가 떠 있어야 나와. 확장을 관리하는 호출도 없어. 결국 내 창에 들어가는 스타일엔 확장이 없는 거야.
- Chrome보다 잃는 건 없다. 공식 CEF 빌드엔 H.264랑 AAC가 빠져 있어(CEF 이슈 #3559). Widevine의 Verified Media Path는 Google이 발급한 인증서가 있어야 해. Google은 2021-01-04부터 임베디드 프레임워크에서의 계정 로그인을 막고 있고, 거기 CEF가 이름으로 찍혀 있어.
- 나머지 작은 전제들. 마이크엔 엔터프라이즈 정책이 필요 없었어. 임베더가 자기 핸들러에서 출처마다 권한 요청을 하나씩 판단하면 되거든. CEF에선 브라우저마다 요청 컨텍스트를 따로 줄 수 있는데, Chrome 부트스트랩 위에선 그게 Chrome 프로필 통째야. 그래서 탭마다 로그인을 나누면 확장이랑 방문 기록까지 탭마다 갈라져. Brave 컨테이너처럼 로그인만 떼어 두고 나머지는 탭끼리 같이 쓰게 하려면 Chromium 패치 묶음이 필요해. 백그라운드 브라우저를 얼리거나 내려놓는 호출도 CEF엔 없어. 가족 앱 목록은 투두가 가리킨 포트 표가 아니라 Firelink의 런치 카탈로그에 있고. 그리고 iPhone, iPad에서 WebKit 말고는 엔진이 없다는 건 확인됐어. EU랑 일본만 예외야.
앞의 두 줄을 겹쳐 보면 전제가 무너져. 아빠가 원한 Swift 창과 아빠가 원한 Chrome 확장은 CEF의 서로 다른 스타일에서 나와. Mac에선 한 창에 둘을 같이 가질 수가 없어.
모든 주장엔 등급이 붙어
이 평가를 믿을 수 있는 건, 주장마다 그걸 어떻게 아는지 밝혀 두기 때문이야. 등급은 문서 맨 위에 정의돼 있어.
| 등급 | 뜻 |
|---|---|
| Verified here | 이 세션에서 1차 출처를 직접 읽었다. |
| Measured here | 이 세션에서 Mac에서 돌려 봤다(프로브가 생긴 뒤에 추가됨). |
| Research | 리서치 패스가 출처를 읽었고, 이 세션은 다시 읽지 않았다. |
| Secondary | 제3자의 보고. 포럼, 프로젝트 노트, 언론. |
| Unverified | 누구도 어느 쪽으로도 보여준 적 없다. 게이트 케이스가 된다. |
등급은 출처에 대한 약속이야. "Verified here"면 이번 세션의 누군가가 그 파일을 열었다는 뜻이고, "Research"면 누군가 한 번 열었고 이번 세션은 그 읽기를 믿고 있다는 뜻이야. 어떤 결정이 의심스러우면 그 밑에 깔린 가장 약한 등급으로 바로 가 보면 돼.
다시 읽었더니 주장 네 개가 내려갔어
그런 약속은 감사를 받아야 의미가 있어. 계약이 들어가자마자, 평가 문서를 처음 보는 눈으로 다시 읽었어. 주장마다 질문은 하나였지. 이거 실제로 누가 읽었어? 출처보다 센 등급을 단 주장이 네 개 나왔어. 그걸 고친 커밋 제목이 grades match who read what이야. 등급을 누가 뭘 읽었는지에 맞춘다는 뜻이지.
- 이슈 #3294가 아직 열려 있고 Windows와 Linux엔 2022년에 그 기능이 들어갔다는 것. 맞는 말이지만 리서치 패스가 읽은 거라 Research.
- Chromium 150, 151에서 Manifest V2 플래그가 지워졌다는 것. 제3자 보고라 Secondary. Chrome 자체 일정은 따로 등급을 매겼어.
- Brave 컨테이너끼리 무엇을 공유하는지. 보고된 내용이라 Secondary.
- 가능한 형태들을 비교한 표에서 확장과 로그인 칸. 출처에서 끌어낸 기대치였으니까, 게이트가 잴 항목이라고 표시를 달았어.
넷 다 결론을 바꾸진 않았어. 그래도 굳이 고친 이유가 바로 거기 있어. 한 번도 내려본 적 없는 등급은 장식이거든. 끌어내리고 나니 출처가 받쳐주는 핵심만 따로 서 있게 됐어. 네이티브 부모 제한은 CEF 자체 소스에 있고, 그 세션에서 직접 읽었어. 껍데기를 결정한 것도 바로 그 줄이었고.
확인이 끝나고 남은 선택지
첫 평가는 아무것도 결정하지 않았어. Mac 앱이 가질 수 있는 형태 넷을 펼쳐 놓았을 뿐이야. Chrome 자체 창에 Voyager 조각을 붙이기, Voyager 창에 탭마다 Chrome 스타일 자식 두기, Swift 앞단을 단 Chromium 포크, 기존 브라우저를 둘러싼 동반 앱. 각각 비용이 붙어 있었고, 껍데기 코드를 쓰기 전에 엔진 게이트를 세웠어. 이어서 아빠가 포크가 진짜로 얼마나 드는지 물었고(다음 레슨), 그 뒤엔 WebKit과 다시 비교해 보라고 했어. 전제가 마침내 무너진 건 그 비교에서야.
레포는 이 교훈을 집 규칙으로 남겼어. CLAUDE.md엔 이렇게 적혀 있어. 엔진이 "할 수 있다"는 말은 이 프로젝트에서 이미 한 번 틀렸다. 엔진에 대한 주장은 출처와 날짜를 달고 평가 문서에 들어가야 한다. 안 그러면 이 레포가 하는 주장이 아니다.