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

Apps Versus Macs

~14 min · firelink, watchfire, single-responsibility, orthogonal

Level 0Cold Ash
0 XP0/32 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"A Mac runs many apps. An app runs on many Macs. Two axes, two hubs — not one god-console for both."

Two Hubs, Deliberately

The family has two control centers, and they are on purpose distinct. Watchfire owns the machines: Tailscale reachability, an explicit-target fleet terminal, environment-domain sync, system and service state, macOS update campaigns, and Mac enrollment and retirement. Firelink owns the applications: the cwk* products those machines run — their census, launch, birth, deploy, and version. Where the other siblings each own an app domain, Watchfire owns the machines themselves, and Firelink is the hub for what runs on them.

Why Not One Mega-Hub?

It's tempting to build one console that 'manages everything.' Firelink and Watchfire refuse that because machines and apps are orthogonal axes. A single Mac runs many applications; a single application runs on many Macs. Their lifecycles differ — a Mac gets enrolled, updated, retired; an app gets born, deployed, versioned. Their operations differ, their owners differ, their failure modes differ. Cramming both into one hub would produce exactly the god-object the whole family avoids: a console so broad that no single mental model fits it and every screen has to answer two unrelated questions at once. Two focused hubs, each with one clear responsibility, stay comprehensible.

The Cross-Hub Boundary Is One-Directional

The two hubs do meet, cleanly and in one direction. Firelink consumes Watchfire's peer ids and its last-observed per-host liveness — as a read-only overlay, carrying Watchfire's own timestamp, never presented as a fresh Firelink probe. Firelink never tries to manage a host; that's Watchfire's domain, full stop. The boundary is observational: Firelink can show 'this app's Mac was last seen reachable at such-and-such time, per Watchfire,' and that's the extent of it. Each hub is authoritative in its own axis and a read-only guest in the other's.

When two management concerns are orthogonal, give each its own hub with a single responsibility, and let them meet only as read-only guests in each other's domain. One mega-console for two unrelated axes becomes a god-object no one can hold in their head; two focused hubs, each authoritative in one axis, stay legible and safe.

Code

Orthogonal axes: one hub per axis·text
                 APPS  (Firelink owns this axis) ------------------>
               +-----------+-----------+-----------+-----------+
  M   office   |  Pippa    |  Ember?   |  Firelink |   ...     |
  A            |  running  |  (server) |  (self!)  |           |
  C   server   |  ...      |  Ember    |  ...      |  ...      |
  S            |           |  running  |           |           |
  |   macbook  |  ...      |  ...      |  ...      |  ...      |
  v            +-----------+-----------+-----------+-----------+
 (Watchfire owns this axis)

  Watchfire  = authoritative on the ROWS  (the Macs themselves)
  Firelink   = authoritative on the COLS  (the apps those Macs run)
  Cross-hub  = Firelink reads Watchfire liveness READ-ONLY (a timestamped
               overlay), and never manages a host. One direction only.

External links

Exercise

Find two management concerns in your world that someone bundled into one tool (say, 'servers' and 'the services running on them,' or 'users' and 'their content'). Are the two axes actually orthogonal — does one of each relate to many of the other? If so, sketch the split: two hubs, one per axis, meeting only as read-only guests. What gets clearer once each screen answers exactly one kind of question?
Hint
The orthogonality test: can you have many of A per B and many of B per A? If yes (many apps per Mac, many Macs per app), one tool trying to be both will always feel like two tools wearing a trench coat. Splitting along the axes is what makes each view answer a single question.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.