docs/always-on.md

Keeping Clankie reachable when the Mac sleeps

A Mac that sleeps is asleep to everything on it: Clankie's service, his Discord bodies and the connection the app reaches him through all stop until it wakes. Clankie treats that as a normal condition to recover from, not a fault (ADR 0203). Choose how your own Mac handles sleep. Free accounts provide phone steering while it is awake; an account alone does not keep a sleeping Mac running.

ChoiceWhat it meansUse it when
An awake MacThe default: the launcher holds the Mac awake while it is plugged in.The Mac is your always-plugged-in home machine.
Let the Mac sleepclankie awake off. Clankie recovers on wake (below).The Mac is a laptop you carry, or you can wait for it to wake.

What recovers on its own

Sleep costs time, not messages or the sign-in. After a wake:

  • Discord catches up on messages that arrived while the gateway was down (VUH-1447).
  • The account doorway reconnects without a new sign-in, including after a lost token rotation (VUH-1451).
  • The app reconnects through the doorway once the service does.

Those are tested with fakes. A real sleep and wake is a human check: the wake test.

What keeps a running Mac's Clankie healthy

With clankie autostart enable, launchd runs one clankie recover pass every 30 seconds. Each pass:

  • restarts a service whose process died, with backoff, giving up after five crashes in 30 minutes;
  • restarts a service that is alive but has failed its loopback health probe for three minutes (the service, relay, lab body and activity surface), recorded with the reason;
  • keeps every service log under 64 MiB plus three compressed archives.

The login agent records a Node that survives brew upgrade node; clankie doctor names clankie autostart enable when an older agent pinned a versioned one.

A source checkout updates itself in batches. Every update restarts the service and drops Discord and the relay for about a minute, so an update that follows main waits until nothing is busy (no turn, voice call or working worker) or until the service has run for two hours. The relay, activity surface and keep-awake keep running through an update that does not change them. clankie update now applies at once; clankie update status shows a pending batch (batched checkout updates).

Telling when this Mac may sleep

clankie doctor reports power and, when the Mac can sleep, a remediation naming the fix. The service reports the same object on /health (power), so the app can say why he went quiet. It answers three questions:

  • state: always_on, sleep_allowed or unknown. sleep_allowed means the Mac will idle-sleep on its current power source and nothing is holding it awake. unknown (no pmset, as on a hosted body) raises no warning.
  • source and sleepAfterMinutes: plugged in or on battery, and the pmset idle sleep for that source (0 is never). A laptop is often set to never sleep on AC and sleep after a minute on battery: on battery it is sleep_allowed.
  • lastSleep: when the running service last noticed the host sleep underneath it. The service cannot see itself asleep, so this is inferred from a timer that fired far too late. It also catches DarkWake, where the Mac wakes for seconds and goes straight back down. It is in memory: a service restart clears it.

A Mac cannot report that it is asleep while it is asleep. From the app, "asleep" is the doorway being unreachable; power is what the host last said before it went, and lastSleep is what it says on waking.

An awake Mac

clankie awake status  # the choice, the launcher's process, and the power state
clankie awake off     # store "let it sleep" and stop the keep-awake now
clankie awake on

A self-hosted Mac keeps itself awake by default (owner decision, 2026-10-17, VUH-2393): with no stored choice, the launcher supervises caffeinate -s like any other service (clankie status lists it as awake). The console has the same command as /awake; on and off store host.keepAwake, and a stored choice, including one an older install saved as false, always wins over the default. Three properties are deliberate:

  • Plugged in only. macOS holds a -s assertion only on AC power. Unplug and the Mac sleeps as its own settings say; nothing here watches the charger, and doctor says "on battery" so the owner knows.
  • It changes no power setting. It never writes pmset. Turn it off and the Mac is exactly as it was.
  • It survives restarts. The launcher restarts awake with the clankie service, crash recovery restarts a caffeinate that died, and clankie autostart enable brings it back at login. Without autostart, a rebooted Mac stays down until you log in and run clankie.

A caffeinate -s you started yourself is left alone and is never mistaken for the launcher's. Amphetamine and other tools that hold a sleep assertion count in heldAwakeBy.

Limits, stated plainly: this holds against idle sleep on AC power. Closing a laptop lid follows macOS's own clamshell rules and is part of the wake test, not something this guide promises. It does not survive a power cut, a restart, or the Mac being unplugged. For a free self-operated route, use your own always-on machine and network access.

Existing hosted bodies

A hosted body already on your account runs independently of your Mac's power. Its actual deployed lifecycle, billing suspension and data limits determine availability; a free account does not provision one. See hosted support for the retained deployment and recovery details. Sign in with clankie login, or clankie connect hosted to require an existing hosted body, then pair the app; see local and hosted connection modes. Self-hosting on your own Linux host is in Linux self-hosting.

Moving an existing Clankie to a hosted body

An existing unclaimed hosted body can receive your Clankie. clankie transfer moves your Mac's Clankie there as the same one: identity, memory, conversations, projects and tracker. It moves him back the same way (ADR 0286). One body holds him at a time. The Mac freezes before the copy, comes back dormant even after a crash, and afterwards answers only /health, which names where he went. Credentials stay in each body's own broker, so the hosted body stays credits-only and the Mac keeps its sign-ins for his return. The Mac can then join the hosted body as a machine, so workers keep running in its checkouts while it is awake. The gateway carries transfers both ways: clankie transfer --to hosted (VUH-2582) and --from hosted, because a dormant managed body keeps its doorway (VUH-2583). Both are proven against a local gateway stack, not yet on a production body.

awake is local only: it refuses in hosted mode and on non-macOS hosts, and a hosted loadout never runs it.

Why caffeinate -s

caffeinate is the native, dependency-free way to hold a sleep assertion, and -s is the one macOS documents as valid on AC power only, which is what "keep it awake while plugged in" means. -i also holds on battery, which would drain a laptop in a bag, so it is not used. Doing this through the launcher instead of the owner's own caffeinate gives it the same supervision, status and stop path as every other service.