C.W.K.
Stream
Lesson 03 of 04 · published

Native 가 launch plane 이다

~13 min · firelink, native-launcher, read-only, offline-cache

Level 0식은 재
0 XP0/32 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"가족의 뭐든 열 수 있고 아무것도 못 바꿔. 그게 제약이 아냐 — 설계 전부야."

열기만 하는 프로덕션 앱

Native Launcher 는 진짜 서명된 macOS 앱이야 — 글로벌 hotkey 가 컴팩트한 패널을 띄우고, 검색하고, 열어. 정확히 launch-plane surface 를 소유해. hotkey 활성화; 기본 아이콘 중심 Card Deck 과 상시 Detailed List; 실행 가능한 product surface 전반 검색; favorites 와 recents; 등록된 bundle identifier 로 로컬 설치 앱 열기; 기본 브라우저에서 등록된 web surface 열기; 앱이 설치/실행 중인지 보여주기; 서비스의 best-effort 도달성; 완전한 Web Hub 열기; 그리고 WebUI 에서 cwkfirelink:// deep link 받기.

그 목록을 읽고 없는 걸 봐. Git 없음. repository 폴더도 IDE 실행도 소스 편집도 없음. roster·network 편집 없음. deploy·restart·process kill·launchd 관리 없음. 임의의 path·URL·bundle·label·command 입력 없음. writer credential 없음. 런처는 가족 전체에 닿을 수 있고 그중 아무것도 mutate 못 해.

전부 이 Mac 기준

런처의 또 다른 정의적 특성: 모든 행동이 Mac 기준이야. 네이티브 앱을 열 때, 여기 설치된 사본을 열어. web surface 를 열 때, 이 머신의 현재 network 컨텍스트로 URL 을 resolve 해. '설치됨'이나 '실행 중'을 보고할 때, 사무실이 아니라 이 노트북 얘기야. office 엔진은 GUI 앱을 travel 브라우저로 원격 실행하지 않아; 실행은 늘 로컬이야. 뭔가를 '다른 데서' 실행하는 건 범주 오류거든.

힘을 줄 수 없는 캐시

일상적 실행은 사무실이 자고 있어도 돼야 하니까, 런처는 read-only catalog 캐시를 둬. 여기가 미묘한 안전 속성이야. 캐시된 데이터는 절대 관리 authority 를 주지 않아. 캐시는 오프라인에서 Ember UI 를 열게 해주지; Ember 를 deploy 하게 해주지 않아. 노트북을 잃어버리면 공격자는 가족이 뭘 어디서 돌리는지 목록 — read-only catalog — 을 얻지, 뭔가를 mutate 하는 열쇠가 아냐. 런처의 무력함이 정확히, 그걸 모든 Mac 에 두고 공항을 지나 들고 다녀도 안전하게 만들어.

편재하는 surface 를 일부러 무력하게 만들어. 어디에나 있고 읽기+열기만 되는 런처는 잃어버려도 안전해; deploy 도 되는 런처는 모든 가방 속 가족 열쇠 한 벌이야. 무력함이 편재를 존재하게 하는 기능이야.

Code

런처는 등록된 target 을 연다 — 임의의 문자열이 아니라·swift
// Every launch resolves a REGISTERED target from the signed catalog.
// There is no text field that becomes a path, a command, or a bundle.
func open(_ target: LaunchTarget) {
    switch target.kind {
    case .nativeApp(let bundleID):          // bundleID is from the catalog, not typed
        guard let appURL = installedAppURL(for: bundleID) else {
            return report(.notInstalledOnThisMac)   // honest, never a guess
        }
        NSWorkspace.shared.openApplication(at: appURL, configuration: .init())
    case .web(let urlSet):
        let url = resolveForThisMac(urlSet)  // client-aware: localhost / LAN / tailnet
        NSWorkspace.shared.open(url)
    }
}

// What this type CANNOT express, by construction:
//   an arbitrary path, a shell command, a git op, a deploy, a restart.
// The catalog is read-only. Losing it leaks a list, not a capability.

External links

Exercise

네가 쓰는 컴패니언이나 런처 앱을 하나 떠올려 (메뉴바 도구, 서비스랑 페어링되는 모바일 앱). 오프라인에서 할 수 있는 것 vs 온라인 가야 하는 걸 나열해봐. 오프라인 capability 가 기기를 훔쳐도 데이터는 새지만 힘은 안 새게 scope 져 있어? 오프라인 모드가 진짜 state 를 mutate 할 수 있으면, 캐시가 조용히 두 번째 writer 가 된 거야 — 읽기와 열기만으로 어떻게 다시 scope 할지 설명해봐.
Hint
안전한 패턴은 이거야. 오프라인 = 읽기 + 열기 + 로컬 preference; 온라인-인증됨 = 공유 진실을 바꾸는 모든 것. 훔친 노트북이 오프라인 모드에서 여전히 deploy 나 삭제를 할 수 있으면, 경계가 잘못된 곳에 있어.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.