carafe Fleet Operator | Damaris X | Layer 3 of 5 · Infrastructure

AI stack | How it works | Any agent | Self-healing | Security | Proof | Small office | Licensing | | Style: plain, human style

Plain HTML on purpose; a plain-text copy for agents is at ../llms.txt.


carafe / always-on Macs for AI agents

Declare your Macs. Kubernetes keeps them.

The carafe Fleet operator runs Fleet, the open-source device manager from FleetDM, inside your cluster. Through Fleet it checks that every Mac station is awake, logged in and running its AI agent (Claude Code, Codex or your own), and runs the configured fix when a check fails.

See how it works | Licensing

  • 51 s to notice a stopped agent page
  • 142 s until it is running again
  • 0 people touching the Mac

[lab-tested, not yet in production] Measured 2026-10-28 in a kind cluster against a macOS 26.5 VM, checks every minute.

kubectl -n fleet-a get macstations -w — illustrative
NAME         ONLINE  CELLAR-DOOR  CHROME  SIGNED-IN  STATUS
station-01   true    true         true    true       ok
# 0 s    the agent's page is stopped on the Mac
station-01   true    false        true    true       attention
# 51 s   policy failing → remedy restart-cellar-door.sh
#        script exit 0, output "ok"; host refetched
station-01   true    true         true    true       ok
# 142 s  back, nobody at the screen

Where it sits

Five layers of AI. carafe is layer 3, the infrastructure.

Jensen Huang describes AI as a five-layer stack: energy, chips, infrastructure, models and applications. Infrastructure includes power delivery, networking and the systems that run many processors as one machine. carafe is building that layer for AI agents: a Mac mini cloud that keeps each agent's machine powered, connected and running.

Framework from Jensen Huang, "AI Is a 5-Layer Cake", NVIDIA blog, 2026-03-10. Placing carafe on it is our reading; carafe is not affiliated with or endorsed by NVIDIA.

5Applicationswhere value is created: assistants and agents people use every day
4ModelsClaude, GPT and open models, reached over the network
3Infrastructure
[we build this]
carafe: power delivery, networking, remote hands and orchestration for always-on agent machines
2Chipsthe processors that turn power into computation
1Energythe power every token starts from

The problem

An AI colleague only works while its computer is on.

Lid closes

The agent stops.

Claude Code, Codex and other agents run on someone's laptop. Remote access helps, but only while that laptop is awake. Not everyone can keep a computer on, or set one up.

Real work is in a browser

A container has no browser.

Permit applications on government portals and design proposals happen in web pages. Claude in Chrome drives a real Chrome on a real desktop, so the plan is a Mac mini for each of them.

Now there are N Macs

Someone has to keep them alive.

Every station must stay awake, logged in, with the agent and its browser running, and be fixed from afar when it is not. Doing that by hand in a device console adds one more place for settings to drift.


First use / carafe, for Claude Code

One always-on Claude workspace per colleague, reachable from the phone.

A carafe is one person's own container with Claude Code, their work folder and the company's skills. A Mac station runs the same setup natively on a Mac mini, with a real Chrome. Each has one web page, the cellar door, where the person signs in and turns on phone access. Then they work from the Claude app.

  • A session started from claude.ai/code, the same path the phone uses, drove Chrome on a Mac station. After a reboot the station came back by itself in about two minutes. A test on a real phone is still to come.
  • The Fleet operator reports every station's checks and runs the configured fix when one fails.

Two rules from the start

Everyone signs in themselves.
The sign-in happens in the person's own browser, through Anthropic's flow, and the code goes straight into their own carafe. carafe keeps no copy of anyone's Claude credentials.
Claude's questions are the person's to answer.
"Trust this folder?" and "Enable Remote Control?" are shown verbatim and answered by the person. carafe never answers them for anyone.
The operator respects that line.
The signed-in check has no remedy. Signing in again needs the person, so the operator reports it and stops there.

How it works

One operator. Three resources. One writer.

The operator owns Fleet: it deploys it, sets it up, configures it and upgrades it. Fleet in turn manages the Macs. The operator is meant to be the only thing that writes to Fleet.

FleetServer — one per company
Fleet, MySQL and Valkey from the official Helm chart: spec.version picks Fleet, spec.chartVersion the chart. Then TLS, the first admin, an API user, Secrets, NodePort and NetworkPolicies.
FleetConfig — one per company
Policies, scripts and labels, kept matching the spec: removed from the spec means removed from Fleet. Built-in and person labels are left alone.
MacStation — one per person
An enrolled Mac, found by serial number: labelled with its person, every check in status, and the remedy script run when a check fails.
An admin or an agent writes three resources; the operator deploys Fleet with Helm and writes it through its API; fleetd on the Mac stations connects over HTTPS; another company's namespace is kept out.
Figure 1. The operator deploys Fleet with Helm and writes it through its API. Another company's namespace is a separate copy, kept out by NetworkPolicy.

What you write

A health check and its fix, declared in YAML.

Each policy is an osquery check that runs on every Mac. Give it a remedy and the operator runs that script when the check fails and the Mac is online. Give it none and the operator only reports.

  • Five station checks ship in the example: never sleeps, logs in by itself, the agent page answers, Chrome is running, Claude is signed in.
  • kubectl get macstations shows every person's Mac, with the five station checks as columns.
  • Hand edits are reverted at the next drift check.
stations.yaml, excerpt — carafe.damaris.club/v1alpha1
kind: FleetConfig
spec:
  serverRef: fleet
  policies:
  - key: cellar-door
    platform: darwin
    query: SELECT 1 FROM curl WHERE url =
      'http://127.0.0.1:7681/healthz' AND response_code = 200;
    remedy: restart-cellar-door.sh   # run when it fails
  - key: signed-in
    query: SELECT 1 FROM curl WHERE url =
      'http://127.0.0.1:7681/signedin' AND result = 'yes';
    # no remedy: signing in again is the person's job
---
kind: MacStation
spec:
  serverRef: fleet
  person: ana
  serial: C02ABCDEF123
  remedyBackoff: 120          # seconds between fixes

Any agent

Claude Code, Codex or your own agent.

If it runs on macOS, the operator can watch it. A check is an osquery query, a fix is a shell script run as root, and both live in your spec. Anything osquery can see counts: a process, a launchd job, a port, a heartbeat file.

agent on the stationwhat to checkstatus
Claude Code, in a carafe Mac stationagent page answers, Chrome running, Claude signed in[lab-tested]
OpenAI Codex CLIprocess running, its LaunchAgent loaded[same pattern]
your own agent or bota process, a port, a heartbeat file[same pattern]

Lab-tested: carafe's checks and its agent page's recovery. Codex and custom agents are examples, not yet tested; their checks show in status.checks.

codex-station.yaml, excerpt — carafe.damaris.club/v1alpha1
kind: FleetConfig
spec:
  serverRef: fleet
  scripts:
  - name: restart-codex.sh
    content: |
      #!/bin/sh
      # your own LaunchAgent that runs Codex
      l=com.example.codex
      u=$(stat -f %Su /dev/console); uid=$(id -u "$u")
      launchctl kickstart -k "gui/$uid/$l" ||
        launchctl bootstrap "gui/$uid" \
          "/Users/$u/Library/LaunchAgents/$l.plist"
  policies:
  - name: "station: Codex is running"
    key: codex
    platform: darwin
    query: SELECT 1 FROM processes WHERE name = 'codex';
    remedy: restart-codex.sh   # run when it fails

Configuration drift

The spec is the only truth. Hand edits are put back.

No edits in Fleet's web page, no separate GitOps run, no tug of war between two tools. The operator reads Fleet back every five minutes and makes it match.

what happenedwhat the operator didmeasured
a policy edited in the specapplied to Fleetunder 1 s
a policy added by hand in Fleetremovedat the next check
a script changed by hand in Fleetput back287 s
The spec goes into Fleet through the operator; a hand edit in Fleet's web page is read back within 5 minutes and removed or put back.
Figure 2. The spec goes into Fleet through the operator; a hand edit in Fleet's web page is read back within 5 minutes and removed or put back.

Self-healing

A failed check triggers its fix, carefully.

The operator runs a remedy only when four things hold. That keeps a broken script from hammering a Mac, and skips Macs that are off.

  1. The policy is failing, per Fleet's own result.
  2. The spec names a remedy for it.
  3. The Mac is online. Nothing new is sent while Fleet reports it offline.
  4. The backoff has passed since the last run.

After a reboot every check came back with nobody touching the Mac. The operator works out boot time from uptime, because in the lab a quick reboot never showed as offline in Fleet; it landed within one second of the kernel's own boot time.

The remedy chain: a failing policy, a remedy script, the Mac online and the backoff passed; only then the script runs and Fleet refetches the host.
Figure 3. The remedy chain: a failing policy, a remedy script, the Mac online and the backoff passed; only then the script runs and Fleet refetches the host.
Measured with the Go operator: cellar door stopped at 0 s, failing at 51 s, back at 142 s.
Figure 4. Measured, to scale: the agent's page stopped at 0 s, failing at 51 s, back at 142 s.

Fleet Free

Runs on Fleet's free tier.

Fleet's own "run a script when a policy fails" is a Premium feature. The operator does it itself with what the free tier already has: scripts, policies, labels and an API-only user.

When we looked in October 2026 we found no Kubernetes operator for Fleet, from its maintainers or the community. The options were the Helm chart, a Terraform provider and fleetctl gitops. The operator uses the official chart rather than replacing it.

Fleet tiers per fleetdm.com/pricing, read 2026-10-27.

capabilityFleet Freewith the operator
policies, scripts, labels, API-only users[yes]declared in YAML
run a fix when a policy fails[Premium][yes] with backoff
install, set up, upgrade Fleetseparate tools: Helm, Terraform[yes] from spec.version
keep Fleet matching a specwhen fleetctl gitops runs[yes] every 5 min
several companies apartone org per install[yes] one per namespace

Security

The token that can run root on every Mac stays in one namespace.

  • Least privilege in Fleet. The operator's API user defaults to maintainer, the lowest role that can run scripts, not admin.
  • Least privilege in Kubernetes. A namespaced Role, never a ClusterRole. The operator watches one namespace only.
  • NetworkPolicies by default. MySQL and Valkey only from inside the namespace; from outside the cluster, only Fleet's port.
  • The AI agents' pods cannot reach Fleet. The lab found that a pod going to a node's NodePort keeps its pod address, so the rule for the Macs excludes the pod network. In the kind lab, pods in other namespaces timed out on the Service, the NodePort and MySQL. Nothing else runs in Fleet's namespace.
A pod in another namespace is blocked both through the Service and through the node's NodePort, where its source address is still the pod's; a Mac coming in through the NodePort is let in.
Figure 5. Blocked through the Service and through the NodePort. The Macs come in through the NodePort.

Multi-company

One Fleet per company, tested apart.

Each company gets its own namespace, operator, Fleet, database and port, and later its own Apple push certificate. Fleet's free tier has one organization per install, so this is also how each company sees only its own name and its own Macs.

  • <1 GB memory per company, 690–930 MB observed
  • ~20 MB the operator itself

Two companies side by side in the kind lab, 2026-10-28; the first had one Mac enrolled, the second none.

#company A against company Bresult
1second Fleet comes up beside the first[71 s] first untouched
2each sees only its own hosts[apart]
3one company's API token on the other's Fleet[401] both ways
4one company's enroll secret on the other's Fleet[401] both ways
5one company's CA on the other's Fleet[TLS refused]
6a pod to the other's Fleet, MySQL, Valkey, NodePort[blocked] both ways
7one operator's account on the other's namespace[denied] both ways
8A's Mac declared as a station of B[not enrolled] nothing shown

Proof / six checks, two implementations

Built twice, measured twice.

A Python proof of concept first, then a Go rewrite with kubebuilder and controller-runtime that runs inside the cluster, calling Helm's Go SDK in-process. Both passed the same six checks against a real macOS VM. The Python code was then removed.

#checkGo operator, in the clusterPython POC
Aempty namespace to a working Fleet, users and Secrets[pass] Ready in 71 s97 s
Bspec applied; hand edits undone[pass] < 1 s; 287 s2 s; 71 s
Ca Mac enrolls and shows its checks[pass] listed after 10 spass
Dthe agent page stopped, fixed by the operator[pass] 51 s / 142 s82 s / 171 s
Ereboot, every check back untouched[pass] boot time ±1 spass
Fother namespaces cannot reach Fleet[pass] timeouts on all pathspass

Fleet 4.93.2, Helm chart 7.0.30, kind 0.33 with Kubernetes 1.37, macOS 26.5 VM. Lab checks ran every minute; about every five minutes is proposed for stations. Single runs, one macOS VM.


Status

Proven in the lab. Next: MDM and a first real office.

Nothing here runs in production yet. Lab-tested; MDM, backups and a first office come next.

Proven [lab]

  • Go operator: install, configure, drift, remedy, reboot, isolation (A–F)
  • Two companies side by side, eight isolation checks
  • Unit tests against a fake Fleet and a fake API server, no cluster needed
  • Trusting the company CA on a Mac as root, with nobody at the screen

Next [planned]

  • MDM: Apple push certificate in a Secret, expiry in status, enrollment profile from the API
  • First profile: Chrome's managed policy that installs Claude in Chrome
  • Nightly MySQL dump, with a restore tested before stations depend on it
  • The NetworkPolicy checks again on k3s; a per-company install overlay

Later [open]

  • Zero-touch enrollment through Apple Business Manager
  • Several fleets per install with Fleet Premium
  • OS updates, lock and wipe through MDM
  • A company-owned carafe box for small offices, with an engineer for setup and workflows

Where it goes / a small office [direction, not built yet]

Next: an agent-ready office for a ten-person company.

A small company has no IT team and no Kubernetes. The plan: it buys a carafe box that becomes its control plane, with no data centre to rent and nothing hosted by us. An engineer sets it up, then works on the team's workflows.

carafe box — the control plane
A Raspberry Pi 5 running k3s and the operator. The company owns it and decides who is admin; support would get in only with its approval, each visit logged.
carafe — one per person
Claude Code, a work folder and the company's skills, on a host in the office, reached from the phone.
Mac station — one per boundary
A Mac mini for each role that must stay apart: front desk, finance, back office, audit, the owner. Each checked and fixed by the operator through Fleet.
network — the office's own
Claude Code's Remote Control opens no inbound ports, so phones need no public address; Fleet stays on the office LAN. A recommended UniFi kit would add a VLAN for the agents, PoE and a 5G backup line.

Setup

The box goes in.

An engineer, ours or a partner's, installs the box, sets up the network and sign-in, and gives everyone a carafe.

The engagement

Work, not plumbing.

The setup is the same in every office, so the engineer's time goes to one or two workflows for each team.

After

Skills travel.

Those workflows become skills that the next company of the same kind can start with. A subscription per person would cover monitoring, upgrades and skill updates.


Licensing

Source available. Free for noncommercial use. Licensed for companies.

For IT teams that already run Kubernetes, for service providers who look after Macs for several small companies, for consultancies placing AI Mac stations with their clients, and, next, for small companies and the engineers who set them up.

ccheng@ccheng.us | | Write to us

Write for a commercial license or a scoped pilot on your own Mac stations.

Independent software. Not affiliated with or endorsed by Fleet Device Management, Anthropic, OpenAI, NVIDIA, Apple, Raspberry Pi or Ubiquiti.

Noncommercial

Free for the uses the PolyForm Noncommercial License 1.0.0 permits.

Commercial

Commercial use, including running carafes for an organization's own staff or its clients, needs a separate written license signed by Cheng Cheng.

Yours stays yours

The licensor claims nothing in what a person keeps or makes in their carafe: workspace files, sessions, transcripts, the configuration carafe writes.

Third parties

Fleet, Claude Code, Codex and macOS keep their own terms. carafe's license covers carafe's own code only.

← → to move · Esc to leave