"Mac 하나가 여러 앱을 돌려. 앱 하나가 여러 Mac 에서 돌아. 두 축, 두 허브 — 둘을 위한 god-console 하나가 아니라."
일부러 두 허브
가족엔 control center 가 둘 있고, 일부러 뚜렷해. Watchfire 가 머신 을 소유해. Tailscale 도달성, explicit-target fleet 터미널, environment-domain sync, system·service state, macOS 업데이트 campaign, Mac enrollment 과 retirement. Firelink 가 애플리케이션 을 소유해. 그 머신이 돌리는 cwk* 제품들 — census, launch, birth, deploy, version. 다른 형제들이 각자 앱 도메인을 소유하는 데서, Watchfire 는 머신 자체를 소유하고, Firelink 는 그 위에서 도는 것의 허브야.
왜 mega-hub 하나가 아냐?
'모든 걸 관리'하는 console 하나를 짓고 싶어져. Firelink 와 Watchfire 는 그걸 거부해, 머신과 앱이 직교하는 축 이라서. 한 Mac 이 여러 애플리케이션을 돌리고; 한 애플리케이션이 여러 Mac 에서 돌아. lifecycle 이 달라 — Mac 은 enroll·update·retire 되고; 앱은 born·deploy·version 돼. operation 이 다르고, 소유자가 다르고, failure mode 가 달라. 둘을 한 허브에 욱여넣으면 가족 전체가 피하는 바로 그 god-object 가 나와. 단일 멘탈 모델이 안 맞을 만큼 넓어서 모든 화면이 무관한 두 질문에 동시에 답해야 하는 console. 각자 하나의 명확한 책임을 가진 두 focused 허브가 이해 가능하게 남아.
cross-hub 경계는 단방향이다
두 허브는 만나긴 해, 깔끔하게 한 방향으로. Firelink 는 Watchfire 의 peer id 와 last-observed host별 liveness 를 consume 해 — read-only overlay 로, Watchfire 자기 타임스탬프를 지니고, 절대 갓 나온 Firelink probe 로 제시되지 않고. Firelink 는 host 를 관리하려 절대 안 해; 그건 Watchfire 도메인, 끝. 경계는 관찰적이야. Firelink 는 '이 앱의 Mac 이 Watchfire 기준 언제 마지막으로 도달 가능했음'을 보여줄 수 있고, 그게 다야. 각 허브는 자기 축에서 권위 있고 상대 축에선 read-only 손님이야.